首先来介绍一下关于相机的基础知识:
1.CCD/CMOS相机的感光元件对波长(即颜色)不敏感,如果拿一个裸体的CCD/CMOS传感器去拍摄图像,只能得到灰度图;
2.因为上述这条,人们必须找到能够将波长区分开的方法,其中一种是使用三个滤光片(通常是RGB三色),在这三个滤光片之后放置三个CCD,这就是3CCD相机;
显然上一种方法的成本太高了,聪明的人类又想到了另一个方法:那就是在CCD/CMOS传感器矩阵之前放置一个滤色片矩阵,每个像素对应一个滤色片,将RGB三种颜色的滤色片均匀分布在这个矩阵中,拍摄到图像后将对应颜色的像素的值取出来并进行插值,就得到了三个通道的数据。
如何用opencv打开raw图像并预览图像信息?
const char* raw_filename = "D:\\ImageLibrary\\Interpolation_Test_images\\5840B+sony119\\ISO12233_100_after_DPC.cap";
const int WIDTH = 1280;
const int HEIGHT = 1024;
CFile file;
file.Open(raw_filename, CFile::modeRead | CFile::typeBinary);
file.SeekToBegin();
file.Seek(128,CFile::begin);
1.CCD/CMOS相机的感光元件对波长(即颜色)不敏感,如果拿一个裸体的CCD/CMOS传感器去拍摄图像,只能得到灰度图;
2.因为上述这条,人们必须找到能够将波长区分开的方法,其中一种是使用三个滤光片(通常是RGB三色),在这三个滤光片之后放置三个CCD,这就是3CCD相机;
显然上一种方法的成本太高了,聪明的人类又想到了另一个方法:那就是在CCD/CMOS传感器矩阵之前放置一个滤色片矩阵,每个像素对应一个滤色片,将RGB三种颜色的滤色片均匀分布在这个矩阵中,拍摄到图像后将对应颜色的像素的值取出来并进行插值,就得到了三个通道的数据。
如何用opencv打开raw图像并预览图像信息?
const char* raw_filename = "D:\\ImageLibrary\\Interpolation_Test_images\\5840B+sony119\\ISO12233_100_after_DPC.cap";
const int WIDTH = 1280;
const int HEIGHT = 1024;
CFile file;
file.Open(raw_filename, CFile::modeRead | CFile::typeBinary);
file.SeekToBegin();
file.Seek(128,CFile::begin);
BYTE * pfilebuf = new BYTE[HEIGHT*WIDTH*2];
if (HEIGHT*WIDTH*2 != file.Read(pfilebuf, HEIGHT*WIDTH*2))
{
//提示文件读取错误
AfxMessageBox("Read Raw File Error");
file.Close();
}
file.Close();
if (HEIGHT*WIDTH*2 != file.Read(pfilebuf, HEIGHT*WIDTH*2))
{
//提示文件读取错误
AfxMessageBox("Read Raw File Error");
file.Close();
}
file.Close();
CvMat* mat_a = cvCreateMat(1, HEIGHT*WIDTH, CV_8U); //单行矩阵便于赋值操作
CvMat* mat_b = cvCreateMat(1, HEIGHT*WIDTH, CV_8U); //同上
int i=0;
do
{
CV_MAT_ELEM(*mat_a, unsigned char, 0, i) = pfilebuf[i*2]; //低8位信息
CV_MAT_ELEM(*mat_b, unsigned char, 0, i) = pfilebuf[i*2+1]; //高8位信息
i++;
}
while(i<HEIGHT*WIDTH);
delete[] pfilebuf;
cvReshape(mat_a, mat_a, 0, HEIGHT); //把单行矩阵整形为二维矩阵
cvReshape(mat_b, mat_b, 0, HEIGHT);
IplImage* img_a = cvCreateImage(cvSize(WIDTH,HEIGHT), IPL_DEPTH_8U, 3);
IplImage* img_b = cvCreateImage(cvSize(WIDTH,HEIGHT), IPL_DEPTH_8U, 3);
cvCvtColor(mat_a, img_a, CV_BayerGR2RGB); //色彩空间转换,即Bayer模式转为RGB
cvCvtColor(mat_b, img_b, CV_BayerGR2RGB);
IplImage* img_b = cvCreateImage(cvSize(WIDTH,HEIGHT), IPL_DEPTH_8U, 3);
cvCvtColor(mat_a, img_a, CV_BayerGR2RGB); //色彩空间转换,即Bayer模式转为RGB
cvCvtColor(mat_b, img_b, CV_BayerGR2RGB);
cvReleaseMat(&mat_a);
cvReleaseMat(&mat_b);
cvNamedWindow("img_a");
cvNamedWindow("img_b");
cvShowImage("img_a", img_a);
cvShowImage("img_b", img_b);
//
//因为cvAddWeighted需要参数矩阵都具有相同类型、相同大小
IplImage* img_a_16 = cvCreateImage(cvSize(WIDTH,HEIGHT), IPL_DEPTH_16U, 3);
IplImage* img_b_16 = cvCreateImage(cvSize(WIDTH,HEIGHT), IPL_DEPTH_16U, 3);
cvConvert(img_a, img_a_16);
cvConvert(img_b, img_b_16);
IplImage* img = cvCreateImage(cvSize(WIDTH,HEIGHT), IPL_DEPTH_16U, 3);
//高8位左移8位加上低8位合成一个16位图像
cvAddWeighted(img_a_16, 1, img_b_16, 256, 0, img);
cvConvertScale(img,img,0.25,0);
IplImage* dst_img = cvCreateImage(cvSize(WIDTH,HEIGHT), IPL_DEPTH_8U, 3);
cvConvert(img, dst_img);
cvShowImage("img", dst_img);
cvWaitKey();
cvDestroyAllWindows();
cvReleaseImage(&img_a);
cvReleaseImage(&img_b);
cvReleaseImage(&img);
reference: http://www.opencv.org.cn/forum/viewtopic.php?t=18681