图像采集的功能一般用CCD和CMOS传感器来实现。但是这两种图像传感器在一个像素上只能采集
RGB颜色的一个分量,为了获得最佳的图像效果,需要3个图像传感器分别采集不同的颜色分量,但考虑
到产品的成本及设计复杂度,通常的数字成像设备用一个传感器在表面覆盖颜色滤波阵列(CFA)来采集
图像。目前常用的一种颜色滤波阵列是Bayer型的,当采集到的图像通过一个颜色滤波阵列滤波后在图像
传感器上感光,得到的图像数据每个像素点表示RGB中的一种颜色,然后对该数据进行颜色插值可获得待
采集的彩色图像。Bayer CFA 型颜色滤波阵列如下图所示:
在这个图像阵列中,每个像素只有一个颜色的色调值,另外两个颜色的色调必须利用相邻像素之间的相关性
,通过计算获得,这些方法通常被称为色彩插值。现主要针对Bayer图像阵列为基础,利用色彩插值算法中
的双线性插值算法来实现RGB 图和Bayer型的颜色滤波阵列图之间的转换。
1.双线性插值算法原理
双线性(bilinear) 插值算法就是这样一种得到广泛应用的算法. 该算法利用相邻像素域中同色分量的平均值作为
当前像素的待求颜色分量.,如上图所示在红/蓝色点处的像素绿色分量如G22=(G21+G12+G23+G32)/4,其插值
等于相邻的四个像素点的绿色分量的平均值。如果存在相邻的两个像素的红色/蓝色分量,就取红/蓝色分量的均
值。如B32=(B22+B42)/2; R22=(R31+R33)/2。如果周围没有相邻的红/蓝色分量,就取对角线方形的4个像素点
处的红/蓝分量的均值,如R24=(R13+R35+R15+R33)/4;B33=(B22+B44+B42+B24)/4。
2.实现的代码如下
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
IplImage* bilinear(IplImage* bayer1,IplImage* huanyuan);
int _tmain(int argc, _TCHAR* argv[])
{
IplImage* src=cvLoadImage("lena.jpg");
IplImage* src_r=cvCreateImage(cvGetSize(src),8,1);
IplImage* src_g=cvCreateImage(cvGetSize(src),8,1);
IplImage* src_b=cvCreateImage(cvGetSize(src),8,1);
cvSplit(src,src_b,src_g,src_r,0);//把RGB图像分成三幅单通道图像
IplImage* bayer=cvCreateImage(cvGetSize(src),8,3);
IplImage* huanyuan=cvCreateImage(cvGetSize(bayer),8,3);
//把src中的颜色分量按bayer模板排列,偶行为GRGRGR,奇行为BGBGBG
for(int i=0; i
{
for(int j=0;j
{
if(i%2==0)
{
cvSetReal2D(src_r,i,j,0);//去掉红色分量
cvSetReal2D(src_b,i,j,0);//去掉蓝色分量
j++;
cvSetReal2D(src_b,i,j,0);//去掉蓝色分量
cvSetReal2D(src_g,i,j,0);//去掉绿色分量
}
else
{
cvSetReal2D(src_r,i,j,0);//去掉红色分量
cvSetReal2D(src_g,i,j,0);//去掉绿色分量
j++;
cvSetReal2D(src_r,i,j,0);//去掉红色分量
cvSetReal2D(src_b,i,j,0);//去掉蓝色分量
}
}
}
cvMerge(src_b,src_g,src_r,0,bayer);//将变换后的图像融合成bayer图像
将bayer图像阵列转变成RGB彩色图像
bilinear(bayer, huanyuan);
cvNamedWindow("src");
cvNamedWindow("huanyuan");
cvNamedWindow("bayer");
cvShowImage("huanyuan",huanyuan);
cvShowImage("bayer",bayer);//将bayer图像显示出来
cvShowImage("src",src);
cvWaitKey();
cvDestroyWindow("src");
cvDestroyWindow("bayer");
cvReleaseImage(&bayer);
cvDestroyWindow("src");
cvDestroyWindow("huanyuan");
cvReleaseImage(&huanyuan);
return 0;
}
//利用双线性插值算法将bayer图像阵列转变成RGB彩色图像
IplImage* bilinear(IplImage* bayer1,IplImage* huanyuan)
{
int x,y;
int t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11;
IplImage* bayer_r=cvCreateImage(cvGetSize(bayer1),8,1);
IplImage* bayer_g=cvCreateImage(cvGetSize(bayer1),8,1);
IplImage* bayer_b=cvCreateImage(cvGetSize(bayer1),8,1);
cvSplit(bayer1,bayer_b,bayer_g,bayer_r,0);
for(x=0; x
{
for(y=0;y
{
if(x == 0 || y == 0 || x == bayer1->width - 2 || y == bayer1->height - 2)
{
t1=(cvGetReal2D(bayer_g,x,y)+cvGetReal2D(bayer_g,x+1,y+1))/2;
cvSetReal2D(bayer_g,x+1,y,t1);cvSetReal2D(bayer_g,x,y+1,t1);//g
t2=cvGetReal2D(bayer_r,x+1,y);
cvSetReal2D(bayer_r,x,y,t2);cvSetReal2D(bayer_r,x,y+1,t2);//r
cvSetReal2D(bayer_r,x+1,y+1,t2);
t3=cvGetReal2D(bayer_b,x,y+1);
cvSetReal2D(bayer_b,x,y,t3);cvSetReal2D(bayer_b,x,y+1,t3);//b
cvSetReal2D(bayer_b,x+1,y+1,t3);
}
else
{
t4=(cvGetReal2D(bayer_g,x,y)+cvGetReal2D(bayer_g,x+2,y)+cvGetReal2D(bayer_g,x+1,y-1)+cvGetReal2D(bayer_g,x+1,y+1))/4;
cvSetReal2D(bayer_g,x+1,y,t4);
t5=(cvGetReal2D(bayer_b,x,y-1)+cvGetReal2D(bayer_b,x,y+1)+cvGetReal2D(bayer_b,x+2,y-1)+cvGetReal2D(bayer_b,x+2,y+1))/4;
cvSetReal2D(bayer_b,x+1,y,t5);
t6=(cvGetReal2D(bayer_b,x,y-1)+cvGetReal2D(bayer_b,x,y+1))/2;
cvSetReal2D(bayer_b,x,y,t6);
t7=(cvGetReal2D(bayer_r,x-1,y)+cvGetReal2D(bayer_r,x+1,y))/2;
cvSetReal2D(bayer_r,x,y,t7);
t8=(cvGetReal2D(bayer_g,x,y)+cvGetReal2D(bayer_g,x,y+2)+cvGetReal2D(bayer_g,x-1,y+1)+cvGetReal2D(bayer_g,x+1,y+1))/4;
cvSetReal2D(bayer_g,x,y+1,t8);
t9=(cvGetReal2D(bayer_r,x-1,y)+cvGetReal2D(bayer_r,x+1,y)+cvGetReal2D(bayer_r,x-1,y+2)+cvGetReal2D(bayer_r,x+1,y+2))/4;
cvSetReal2D(bayer_r,x,y+1,t9);
t10=(cvGetReal2D(bayer_r,x+1,y)+cvGetReal2D(bayer_r,x+1,y+2))/2;
cvSetReal2D(bayer_r,x+1,y+1,t10);
t11=(cvGetReal2D(bayer_b,x,y+1)+cvGetReal2D(bayer_b,x+2,y+1))/2;
cvSetReal2D(bayer_b,x+1,y+1,t11);
}
}
}
cvMerge(bayer_b,bayer_g,bayer_r,0,huanyuan);//将变换后的图像融合成bayer图像
return huanyuan;
}
3.结果图如下
bayer滤波阵列图
利用bayer滤波阵列还原的图