GitCode 开源社区
使用OpenCV打开RAW文件
使用OpenCV打开RAW文件
opencv
OpenCV: 开源计算机视觉库
项目地址:https://gitcode.com/gh_mirrors/opencv31/opencv

首先来介绍一下关于相机的基础知识:
1.CCD/CMOS相机的感光元件对波长(即颜色)不敏感,如果拿一个裸体的CCD/CMOS传感器去拍摄图像,只能得到灰度图;
2.因为上述这条,人们必须找到能够将波长区分开的方法,其中一种是使用三个滤光片(通常是RGB三色),在这三个滤光片之后放置三个CCD,这就是3CCD相机;
1.CCD/CMOS相机的感光元件对波长(即颜色)不敏感,如果拿一个裸体的CCD/CMOS传感器去拍摄图像,只能得到灰度图;
2.因为上述这条,人们必须找到能够将波长区分开的方法,其中一种是使用三个滤光片(通常是RGB三色),在这三个滤光片之后放置三个CCD,这就是3CCD相机;
- 局部放大
-
在一个项目中我用到了12bit的工业相机,通过调用该相机SDK中的函数可以将拍摄的图像数据保存为16bit单通道的raw文件,其中前12bit有效,末尾4bit是0。
下面来介绍如何用OpenCV打开raw文件。思路如下:
1.以二进制方式打开文件;
2.将每个像素对应的16bit的数据分成两个8bit,分别放入两个矩阵中;
3.对这两个矩阵进行色彩空间变换,转换为两个8bit三通道的图像;
4.将这两个图像合成为一个16bit三通道的图像。
废话少说,代码如下: -
void CMy20120510readrawfileDlg::OnBnClickedButton2() { const int WIDTH = 1360; const int HEIGHT = 1024; CFile file; file.Open(_T("aaa.raw"), CFile::modeRead | CFile::typeBinary); file.SeekToBegin(); BYTE * pfilebuf = new BYTE[HEIGHT*WIDTH*2]; if (HEIGHT*WIDTH*2 != file.Read(pfilebuf, HEIGHT*WIDTH*2)) { //提示文件读取错误 file.Close(); return; } 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_BayerBG2RGB); //色彩空间转换,即Bayer模式转为RGB cvCvtColor(mat_b, img_b, CV_BayerBG2RGB); 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); cvNamedWindow("img"); cvShowImage("img", img); cvWaitKey(); cvDestroyAllWindows(); cvReleaseImage(&img_a); cvReleaseImage(&img_b); cvReleaseImage(&img); }
得到的图像如下:
可以看出img_a的结果是原16bit图像的低8位,直接显示的话是没什么意义的。
最后合成的16bit肉眼几乎观察不出有什么区别,但是对OpenCV来说已经是可以直接处理的16bit图像数据了!
接下来,要怎么处理就可以自由发挥啦。
顺便给出OpenCV帮助文档里cvCvtColor对Bayer模式转换的说明,请认真阅读哦:
继续放大:




OpenCV: 开源计算机视觉库
最近提交(Master分支:5 个月前 )
60924999
replace tostring() with tobytes() 1 天前
b5c3b706
Removed Android test as it's broken for now 1 天前
2w
1
0
- 0
扫一扫分享内容
分享
回到
顶部
顶部
所有评论(0)