一般相机设备获取的图片数据并不是8位的图片数据,而是16位的Raw数据,也就是说我们看到的图片都是经过对16位的数据进行读取,然后转8位进行显示(中间可能包含各种算法,用于提高图像的画质)。代码中RawDataToImg()函数就是转八位数据的函数,方法有很多,比如线性映射、直方图调光、单平台调光、双平台调光等等。
bool readRawData(const char* fileName, short* dstData, int nWidth, int nHeight)
{
unsigned char* srcData = new unsigned char[ nWidth * nHeight * sizeof(short)];
FILE* fp;
fp = fopen(fileName, "r");
if(fp == NULL){
cout<<"文件打开出错"<<endl;
return false;
}
else{
cout<<"文件打开成功"<<fp<<endl;
fread(srcData, sizeof(unsigned char), nWidth * nHeight * sizeof(short), fp);
fclose(fp);
}
for(int i = 0; i < nWidth*nHeight;i++){
dstData[i] = srcData[i*2+1]*256 + srcData[i*2];
}
if(srcData){
delete []srcData;
srcData = NULL;
}
return true;
}
主函数main( ):
int main(int argc, char* argv[]){
string fileName;
short* srcData; //Raw数据类型
unsigned char* dstData; //8位图片类型
srcData = new short[iWidth * iHeight]; //给数据开辟个空间
dstData = new unsigned char[iWidth * iHeight];
//fileName = new char[100];
if(argc > 1){
fileName = string( argv[1] );
}
else{
cout<<"please input fileName: ";
cin>>fileName;
cout<<endl;
}
if(srcData == NULL){
cout<<"Getting wrong when readding the fileName!"<<endl;
}else{
if(readRawData((char*)fileName.c_str(), srcData, iWidth, iHeight)){
RawDataToImg(dstData, srcData, iWidth, iHeight); //将16位Raw数据转8位数据
}
}
Mat img(iHeight, iWidth, CV_8UC1, 1);
memcpy(img.data, dstData, iHeight * iWidth * sizeof(unsigned char));
imshow("img", img);
waitKey(0);
//释放原先开辟的空间
if(dstData){
delete []dstData;
dstData = NULL;
}
if(srcData){
delete []srcData;
srcData = NULL;
}
return 0 ;
}
void RawDataToImg(unsigned char* Dist, short* Src, int iWidth, int iHeight)
{
short* tmpSrc = Src;
unsigned char* pDits = Dist;
long nImageSize = iHeight * iWidth;
int i =0, j = 0, k=0, sum = 0, nSigma = 0, mMax = 0, mMin = 0;
int* pHist = new int[HIST_SIZE * sizeof(int)];
if (pHist != NULL)
{
memset((void*)pHist, 0, sizeof(int) * HIST_SIZE);
for (int i = 0; i < nImageSize; i++)
{
pHist[tmpSrc[i] + Y16_AD_MOVE]++;
}
nSigma = nImageSize * 0.001;
for(i = 0 ; i < HIST_SIZE ; i++){
sum += pHist[i];
if(sum >= nSigma){
mMin = i;
break;
}
}
sum = 0 ;
for(i = HIST_SIZE - 1 ; i >= 0 ; i--){
sum += pHist[i];
if(sum >= nSigma){
mMax = i;
break;
}
}
mMin -= Y16_AD_MOVE;
mMax -= Y16_AD_MOVE;
float K = (float)((255.0 - 0.0)/(mMax - mMin + 1));//对比度
float C = (float)((0.0 * mMax - 255.0 * mMin) / (mMax - mMin + 1));//亮度
for(i = 0 ; i < nImageSize ; i++){
int nValue = (int)(K * tmpSrc[i] + C -10);
if(nValue < 0){
pDits[i] = 0;
}else if(nValue > 255){
pDits[i] = 255;
}else{
pDits[i] = (char)nValue;
}
}
delete[] pHist;
pHist = NULL;
}
}
matlab代码:
clear all;
close all;
nWidth = 100; %图片列数
nHeight = 100; %图片行数
[filename , pathname] = uigetfile('F:\*', '选择图片');
fid = fopen([pathname filename]);
s = fread(fid, 'uint8');
s2 = reshape(s(1:2:end),[nWidth , nHeight]);
s3 = reshape(s(2:2:end),[nWidth , nHeight]);
s4 = (s3)*256+s2;
Image =int16(s4');
fclose(fid);
img = Image;