相比较与前一篇BLOG,这篇文章的重点在于将代码优化,并用string等代替传统char的代码,如有能继续优化的部分,望不吝赐教。
#include<opencv2\opencv.hpp>
using namespace cv;
using namespace std;
Mat mat14to8(unsigned short *srcData);
Mat img14to8(ushort *in, int rows, int cols);
//红外文件名
String LoadFileDir = "G:\\ir\\";
String IrName = "20190907_111018";
String LoadFilePath = LoadFileDir + IrName + ".dat"; //输入文件完整路径
String FileIrBmp2Video = LoadFileDir + IrName+ ".avi"; //保存成视频完整路径
String SaveImgPath =LoadFileDir+"temp\\"; //保存成图片完整路径
#define IMG_TYPE ".bmp"
#define IMG_WIDTH 640
#define IMG_HEIGHT 512
#define IMG_BITWIDTH 16384 //2^14
#define SAVEIRIMG
#define SAVEIMG2VIDEO //在这里注意,图片需要先保存下来再次读取才能转化为视频,原因未知
unsigned short(imagedata[IMG_WIDTH*IMG_HEIGHT]);
unsigned short Hist[IMG_BITWIDTH];
int main()
{
Mat outputImage(IMG_HEIGHT, IMG_WIDTH, CV_8UC1, Scalar(0));
//打开文件并确定结尾位置和图片数量
FILE *pFile;
pFile = fopen(LoadFilePath.c_str(), "rb");
struct stat statbuf;
stat(LoadFilePath.c_str(), &statbuf);
printf("文件大小为%dB\n", statbuf.st_size);
int number_size = statbuf.st_size / (sizeof(unsigned short)*IMG_HEIGHT*IMG_WIDTH);
printf("图片数量为%d张\n", number_size);
for (size_t i = 0; i < number_size; i++)
{
fread(imagedata, sizeof(unsigned short), IMG_HEIGHT*IMG_WIDTH, pFile);
//outputImage = mat14to8(imagedata);
outputImage = img14to8(imagedata, IMG_HEIGHT, IMG_WIDTH);
imshow("outputImage", outputImage);
cout << "正在处理第" << i << "帧" << endl;
#ifdef SAVEIRIMG
String sNum = to_string(i);
while (sNum.size() < 6) {sNum = "0" + sNum;}
String SaveFileName = SaveImgPath + sNum + IMG_TYPE;
imwrite(SaveFileName, outputImage);
#endif //SAVEIRIMG
waitKey(1);
}
#ifdef SAVEIMG2VIDEO
Mat LoadSrcImg;
VideoWriter videoWriter;
videoWriter.open(FileIrBmp2Video, CV_FOURCC('M', 'J', 'P', 'G'), 25, Size(IMG_WIDTH, IMG_HEIGHT));
for (size_t ImgCount = 0; ImgCount < number_size; ImgCount++)
{
String sNum = to_string(ImgCount);
while (sNum.size() < 6) { sNum = "0" + sNum; }
String sGetIrImgPic = SaveImgPath + sNum + IMG_TYPE;
LoadSrcImg = imread(sGetIrImgPic);
if (LoadSrcImg.data == 0){return false;}else {}
videoWriter.write(LoadSrcImg);
imshow("LoadSrcImg", LoadSrcImg);
waitKey(1);
}
#endif // SAVEIMG2VIDEO
return true;
}
Mat mat14to8(unsigned short *srcData)
{
Mat out(IMG_HEIGHT, IMG_WIDTH, CV_8UC1, Scalar(0));
unsigned int MaxValue = 0, MinValue = 0xffffff;
float Factor = 1.0, middle = 0.0;
for (size_t i = 0; i < IMG_HEIGHT*IMG_WIDTH; i++)
{
Hist[srcData[i]]++;
}
for (size_t i = 0; i < IMG_HEIGHT*IMG_WIDTH; i++)
{
if ((MaxValue<*(srcData + i)) && (Hist[*(srcData + i)]>50))
{
MaxValue = *(srcData + i);
}
else {}
if ((MinValue>*(srcData + i)) && (Hist[*(srcData + i)]>50))
{
MinValue = *(srcData + i);
}
else {}
}
Factor = 255.0 / (MaxValue - MinValue);
for (size_t i = 0; i < IMG_HEIGHT; i++)
{
for (size_t j = 0; j < IMG_WIDTH; j++)
{
middle = (*(srcData + i*IMG_WIDTH + j) - MinValue)*Factor;
if (*(srcData + i*IMG_WIDTH + j) == 0)
{
out.ptr<uchar>(i)[j] = 0;
}
else
{
if (middle < 0)
out.ptr<uchar>(i)[j] = 0;
else if (middle>255)
out.ptr<uchar>(i)[j] = 255;
else
out.ptr<uchar>(i)[j] = (uchar)middle;
}
}
}
return out;
}
Mat img14to8(ushort *in, int rows, int cols)
{
Mat out(rows, cols, CV_8UC1);
int inc = 0, minValue = 0, maxValue = 0;
double factor = 0.0, middle = 0.0;
unsigned char hist[640 * 512];
memset(hist, 0, sizeof(hist));
for (size_t i = 0; i < rows; i++)
{
for (size_t j = 0; j < cols; j++)
{
if (in[i*cols + j] > 0 && in[i*cols + j] < 16384)
hist[in[i*cols + j]] = hist[in[i*cols + j]] + 1;
}
}
for (size_t i = 0; i < 16384; i++)
{
if ((inc < 2000) && ((inc + hist[i]) > 1999))
{
minValue = i;
break;
}
inc = inc + hist[i];
}
inc = 0;
for (size_t i = 16383; i > 0; i--)
{
if ((inc < 2000) && ((inc + hist[i]) > 1999))
{
maxValue = i;
break;
}
inc = inc + hist[i];
}
maxValue = maxValue + 32;
minValue = minValue - 32;
factor = 1.0 / (maxValue - minValue) * 255;
for (size_t i = 0; i < rows; i++)
{
for (size_t j = 0; j < cols; j++)
{
if (in[i*cols + j] == 0)
out.ptr<uchar>(i)[j] = 0;
else
{
middle = (in[i*cols + j] - minValue)*factor;
if (middle>255)
out.ptr<uchar>(i)[j] = 255;
else if (middle<0)
out.ptr<uchar>(i)[j] = 0;
else
out.ptr<uchar>(i)[j] = uchar(middle);
}
}
}
return out;
}