1. 程式人生 > >Bayer模型的顏色插值演算法

Bayer模型的顏色插值演算法

        影象採集的功能一般用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<src->width;i++)
{
for(int j=0;j<src->height;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<bayer1->width;x+=2)
{
for(y=0;y<bayer1->height;y+=2)
{
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濾波陣列還原的圖