由于成本和面积等因素的限定,CMOS/CCD在成像时,感光面阵列前通常会有CFA(color filter array),如下图所示,CFA过滤不同频段的光,因此,Sensor的输出的RAW数据信号包含了3个通道的信息。由于人眼对绿色(大约550nm波长)光更敏感,因此CFA阵列包含1/2的G分量,1/4和R和1/4的B分量。
Sensor输出RAW数据后,需要经过Demosaic模块(ISP中)将其转成RGB图像。作为测试,我们可以对一幅全彩色RGB图进行RGB2Bayer转换,将其转换成RAW数据,再进行Bayer2RGB转换,输出RGB,对比输入和输出,可判断算法是否有效。
Bayer2RGB的转换方法有许多,下面给出基于3x3窗口简单插值的代码,支持BGGR、RGGB、GBRG三种bayer格式。输入一幅RGB图像,先进行RGB2Bayer转换,再进行Bayer2RGB转换。
%% ------------------------------------
% Author : lemonHe
% Time : 20180814
% Function : Demosaic
%%------------------------------------
clc;
clear;
close all;
imSrc = imread('detailTest.bmp');
% imSrc = imread('./bayer_data/bayer_1920x1080_12bit.tif');
figure,imshow(imSrc);
[hei, wid, chan] = size(imSrc);
bayer = uint8(zeros(hei,wid));
%% BGGR
% B G B G B G
% G R G R G R
% B G B G B G
% for ver = 1:hei;
% for hor = 1:wid
% if((1 == mod(ver,2)) && (1 == mod(hor,2)))
% bayer(ver,hor) = imSrc(ver,hor,3);
% elseif((0 == mod(ver,2)) && (0 == mod(hor,2)))
% bayer(ver,hor) = imSrc(ver,hor,1);
% else
% bayer(ver,hor) = imSrc(ver,hor,2);
% end
% end
% end
%
% figure,imshow(bayer);
%
% bayerPadding = zeros(hei+2,wid+2);
% bayerPadding(2:hei+1,2:wid+1) = bayer;
% bayerPadding(1,:) = bayerPadding(3,:);
% bayerPadding(hei+2,:) = bayerPadding(hei,:);
% bayerPadding(:,1) = bayerPadding(:,3);
% bayerPadding(:,wid+2) = bayerPadding(:,wid);
% imDst = zeros(hei+2, wid+2, chan);
%
% for ver = 2:hei+1
% for hor = 2:wid+1
% if(1 == mod(ver-1,2))
% if(1 == mod(hor-1,2))
% imDst(ver,hor,3) = bayerPadding(ver,hor);
% imDst(ver,hor,1) = (bayerPadding(ver-1,hor-1) + bayerPadding(ver-1,hor+1) + bayerPadding(ver+1,hor-1) + bayerPadding(ver+1,hor+1)) / 4;
% imDst(ver,hor,2) = (bayerPadding(ver-1,hor) + bayerPadding(ver,hor-1) + bayerPadding(ver,hor+1) + bayerPadding(ver+1,hor)) / 4;
% else
% imDst(ver,hor,2) = bayerPadding(ver,hor);
% imDst(ver,hor,1) = (bayerPadding(ver-1,hor) + bayerPadding(ver+1,hor)) / 2;
% imDst(ver,hor,3) = (bayerPadding(ver,hor-1) + bayerPadding(ver,hor+1)) / 2;
% end
% else
% if(1 == mod(hor-1,2))
% imDst(ver,hor,2) = bayerPadding(ver,hor);
% imDst(ver,hor,1) = (bayerPadding(ver,hor-1) + bayerPadding(ver,hor+1)) / 2;
% imDst(ver,hor,3) = (bayerPadding(ver-1,hor) + bayerPadding(ver+1,hor)) / 2;
% else
% imDst(ver,hor,1) = bayerPadding(ver,hor);
% imDst(ver,hor,2) = (bayerPadding(ver-1,hor) + bayerPadding(ver,hor-1) + bayerPadding(ver,hor+1) + bayerPadding(ver+1,hor)) / 4;
% imDst(ver,hor,3) = (bayerPadding(ver-1,hor-1) + bayerPadding(ver-1,hor+1) + bayerPadding(ver+1,hor-1) + bayerPadding(ver+1,hor+1)) / 4;
% end
% end
% end
% end
%
% imDst = uint8(imDst(2:hei+1,2:wid+1,:));
% figure,imshow(imDst);
%% RGGB
% R G R G R G
% G B G B G B
% R G R G R G
% for ver = 1:hei;
% for hor = 1:wid
% if((1 == mod(ver,2)) && (1 == mod(hor,2)))
% bayer(ver,hor) = imSrc(ver,hor,1);
% elseif((0 == mod(ver,2)) && (0 == mod(hor,2)))
% bayer(ver,hor) = imSrc(ver,hor,3);
% else
% bayer(ver,hor) = imSrc(ver,hor,2);
% end
% end
% end
%
% figure,imshow(bayer);
%
% bayerPadding = zeros(hei+2,wid+2);
% bayerPadding(2:hei+1,2:wid+1) = bayer;
% bayerPadding(1,:) = bayerPadding(3,:);
% bayerPadding(hei+2,:) = bayerPadding(hei,:);
% bayerPadding(:,1) = bayerPadding(:,3);
% bayerPadding(:,wid+2) = bayerPadding(:,wid);
% imDst = zeros(hei+2, wid+2, chan);
%
% for ver = 2:hei+1
% for hor = 2:wid+1
% if(1 == mod(ver-1,2))
% if(1 == mod(hor-1,2))
% imDst(ver,hor,1) = bayerPadding(ver,hor);
% imDst(ver,hor,3) = (bayerPadding(ver-