去马赛克(Demosaic)一

前言

\quad\quad 关于为什么要做去马赛克参加博文Understanding ISP Pipeline - Demosaicking。简单来说就是当前使用较多的CCD和CMOS sensor用的是Bayer CFA格式,或者Bayer mosaic格式,支持这种格式的成像器件(包括CCD和CMOS两种)输出的数据格式俗称RAW格式,特点是每个像素只提供RGB三种颜色中的一种,另外两种颜色需要后续处理环节中通过一定的软件算法进行插值补全。

去马赛克算法

参考博文ISP算法简述与逻辑实现-demosaic和ISP图像处理之Demosaic算法及相关

双线性插值

双线性插值是比较简单的算法,简而言之就是用周围相同颜色的像素值的平均来填补当前像素确实的颜色。
去马赛克(Demosaic)一_第1张图片
G通道上RB插值,以G23为例,

  • R23 = (R13+R33)/2
  • B23 = (B22+B24)/2

R通道上GB插值,以R33为例,

  • G33 = (G23+G32+G34+G43)/4
  • B33 = (B22+B24+B42+B44)/4

B通道上的RG插值,以B24为例

  • R24 = (R13+R15+R33+R35)/4
  • B24 = (G14+G23+G25+G34)/4
function imDst = Demosaic_bilinear(bayer,pattern)

[H,W]     = size(bayer);
imDst     = zeros(H,W,3);

g1        = [0 1/4 0; 1/4 0 1/4; 0 1/4 0];
g2        = [1/4 0 1/4; 0 0 0; 1/4 0 1/4];
h         = [0.5 0 0.5];

tmp1      = conv2(bayer,g1,'same');
tmp2      = conv2(bayer,g2,'same');
tmp3      = conv2(bayer,h,'same');
tmp4      = conv2(bayer,h','same');

switch pattern
    case 'grbg'
        G(1:2:H,1:2:W) = bayer(1:2:H,1:2:W);
        G(2:2:H,2:2:W) = bayer(2:2:H,2:2:W);
        G(1:2:H,2:2:W) = tmp1(1:2:H,2:2:W);
        G(2:2:H,1:2:W) = tmp1(2:2:H,1:2:W);

        R(1:2:H,2:2:W) = bayer(1:2:H,2:2:W);
        R(1:2:H,1:2:W) = tmp3(1:2:H,1:2:W);
        R(2:2:H,2:2:W) = tmp4(2:2:H,2:2:W);
        R(2:2:H,1:2:W) = tmp2(2:2:H,1:2:W);

        B(2:2:H,1:2:W) = bayer(2:2:H,1:2:W);
        B(1:2:H,1:2:W) = tmp4(1:2:H,1:2:W);
        B(2:2:H,2:2:W) = tmp3(2:2:H,2:2:W);
        B(1:2:H,2:2:W) = tmp2(1:2:H,2:2:W);
    case 'gbrg'
        G(1:2:H,1:2:W) = bayer(1:2:H,1:2:W);
        G(2:2:H,2:2:W) = bayer(2:2:H,2:2:W);
        G(1:2:H,2:2:W) = tmp1(1:2:H,2:2:W);
        G(2:2:H,1:2:W) = tmp1(2:2:H,1:2:W);

        R(2:2:H,1:2:W) = bayer(2:2:H,1:2:W);
        R(1:2:H,1:2:W) = tmp4(1:2:H,1:2:W);
        R(2:2:H,2:2:W) = tmp3(2:2:H,2:2:W);
        R(1:2:H,2:2:W) = tmp2(1:2:H,2:2:W);

        B(1:2:H,2:2:W) = bayer(1:2:H,2:2:W);
        B(1:2:H,1:2:W) = tmp3(1:2:H,1:2:W);
        B(2:2:H,2:2:W) = tmp4(2:2:H,2:2:W);
        B(2:2:H,1:2:W) = tmp2(2:2:H,1:2:W);
    case 'rggb'
        G(1:2:H,2:2:W) = bayer(1:2:H,2:2:W);
        G(2:2:H,1:2:W) = bayer(2:2:H,1:2:W);
        G(1:2:H,1:2:W) = tmp1(1:2:H,1:2:W);
        G(2:2:H,2:2:W) = tmp1(2:2:H,2:2:W);

        R(1:2:H,1:2:W) = bayer(1:2:H,1:2:W);
        R(1:2:H,2:2:W) = tmp3(1:2:H,2:2:W);
        R(2:2:H,1:2:W) = tmp4(2:2:H,1:2:W);
        R(2:2:H,2:2:W) = tmp2(2:2:H,2:2:W);

        B(2:2:H,2:2:W) = bayer(2:2:H,2:2:W);
        B(1:2:H,2:2:W) = tmp4(1:2:H,2:2:W);
        B(2:2:H,1:2:W) = tmp3(2:2:H,1:2:W);
        B(1:2:H,1:2:W) = tmp2(1:2:H,1:2:W);
    case 'bggr'
        G(1:2:H,2:2:W) = bayer(1:2:H,2:2:W);
        G(2:2:H,1:2:W) = bayer(2:2:H,1:2:W);
        G(1:2:H,1:2:W) = tmp1(1:2:H,1:2:W);
        G(2:2:H,2:2:W) = tmp1(2:2:H,2:2:W);

        R(2:2:H,2:2:W) = bayer(2:2:H,2:2:W);
        R(1:2:H,2:2:W) = tmp4(1:2:H,2:2:W);
        R(2:2:H,1:2:W) = tmp3(2:2:H,1:2:W);
        R(1:2:H,1:2:W) = tmp2(1:2:H,1:2:W);

        B(1:2:H,1:2:W) = bayer(1:2:H,1:2:W);
        B(1:2:H,2:2:W) = tmp3(1:2:H,2:2:W);
        B(2:2:H,1:2:W) = tmp4(2:2:H,1:2:W);
        B(2:2:H,2:2:W) = tmp2(2:2:H,2:2:W);    
end
imDst = cat(3,R,G,B);

基于色差恒定的插值

色差恒定准则与色比恒定准则都是基于颜色通道之间的相关性,目的都是把颜色通道之间的相关性信息引入颜色插值算法,提高插值的准确性。具体算法参考博文ISP算法简述与逻辑实现-demosaic,算法流程如下:

  • 先对G通道进行双线性插值,得到全分辨率的G’通道
  • 计算色彩 Kr = G-R 和 Kb = G-B,然后将Kr和Kb进行双线性插值,得到全分辨率的Kr和Kb:
    Kr11 = G’11-R11
    Kb22 = G’22 - R22
  • R = G-Kr, B = G-Kb

去马赛克(Demosaic)一_第2张图片

function imDst = Demosaic_color_diff(raw_img,pattern)
[hei,wid] = size(raw_img);
imDst     = zeros(hei,wid,3);
Kr        = zeros(hei,wid);
Kb        = zeros(hei,wid);
bayerPadding = zeros(hei+2,wid+2);
bayerPadding(2:hei+1,2:wid+1) = raw_img;
bayerPadding(1,:) = bayerPadding(3,:);
bayerPadding(hei+2,:) = bayerPadding(hei,:);
bayerPadding(:,1) = bayerPadding(:,3);
bayerPadding(:,wid+2) = bayerPadding(:,wid);

if pattern == 'grbg'
    % g
    imDst(1:2:hei,1:2:wid,2) = bayerPadding(2:2:hei+1,2:2:wid+1);
    imDst(2:2:hei,2:2:wid,2) = bayerPadding(3:2:hei+1,3:2:wid+1);
    imDst(1:2:hei,2:2:wid,2) = (bayerPadding(1:2:hei,3:2:wid+2)+bayerPadding(3:2:hei+2,3:2:wid+2)+...
                                bayerPadding(2:2:hei+1,2:2:wid+1)+bayerPadding(2:2:hei+1,4:2:wid+2))/4;
    imDst(2:2:hei,1:2:wid,2) = (bayerPadding(2:2:hei+1,2:2:wid+1)+bayerPadding(4:2:hei+2,2:2:wid+1)+...
                                bayerPadding(3:2:hei+2,1:2:wid)+bayerPadding(3:2:hei+2,3:2:wid+2))/4;

    % Kr Kb
    Kr(1:2:hei,2:2:wid)      = imDst(1:2:hei,2:2:wid,2) - bayerPadding(2:2:hei+1,3:2:wid+1);
    Kb(2:2:hei,1:2:wid)      = imDst(2:2:hei,1:2:wid,2) - bayerPadding(3:2:hei+2,2:2:wid+1);

    Kr                       = Demosaic_bilinear(Kr,pattern);
    Kr                       = Kr(:,:,1);

    Kb                       = Demosaic_bilinear(Kb,pattern);
    Kb                       = Kb(:,:,3);   

    imDst(:,:,1)             = imDst(:,:,2) - Kr;
    imDst(:,:,3)             = imDst(:,:,2) - Kb;
elseif pattern == 'gbrg'
    % g
    imDst(1:2:hei,1:2:wid,2) = bayerPadding(2:2:hei+1,2:2:wid+1);
    imDst(2:2:hei,2:2:wid,2) = bayerPadding(3:2:hei+1,3:2:wid+1);
    imDst(1:2:hei,2:2:wid,2) = (bayerPadding(1:2:hei,3:2:wid+2)+bayerPadding(3:2:hei+2,3:2:wid+2)+...
                                bayerPadding(2:2:hei+1,2:2:wid+1)+bayerPadding(2:2:hei+1,4:2:wid+2))/4;
    imDst(2:2:hei,1:2:wid,2) = (bayerPadding(2:2:hei+1,2:2:wid+1)+bayerPadding(4:2:hei+2,2:2:wid+1)+...
                                bayerPadding(3:2:hei+2,1:2:wid)+bayerPadding(3:2:hei+2,3:2:wid+2))/4;

    % Kr Kb
    Kb(1:2:hei,2:2:wid)      = imDst(1:2:hei,2:2:wid,2) - bayerPadding(2:2:hei+1,3:2:wid+1);
    Kr(2:2:hei,1:2:wid)      = imDst(2:2:hei,1:2:wid,2) - bayerPadding(3:2:hei+2,2:2:wid+1);

    Kr                       = Demosaic_bilinear(Kr,pattern);
    Kr                       = Kr(:,:,1);

    Kb                       = Demosaic_bilinear(Kb,pattern);
    Kb                       = Kb(:,:,3);   

    imDst(:,:,1)             = imDst(:,:,2) - Kr;
    imDst(:,:,3)             = imDst(:,:,2) - Kb;
elseif pattern == 'rggb'
    % g
    imDst(1:2:hei,2:2:wid,2) = bayerPadding(2:2:hei+1,3:2:wid+2);
    imDst(2:2:hei,1:2:wid,2) = bayerPadding(3:2:hei+2,2:2:wid+1);
    imDst(1:2:hei,1:2:wid,2) = (bayerPadding(1:2:hei,2:2:wid+1)+bayerPadding(3:2:hei+2,2:2:wid+1)+...
                                bayerPadding(2:2:hei+1,1:2:wid)+bayerPadding(2:2:hei+1,3:2:wid+2))/4;
    imDst(2:2:hei,2:2:wid,2) = (bayerPadding(2:2:hei+1,3:2:wid+2)+bayerPadding(4:2:hei+2,3:2:wid+2)+...
                                bayerPadding(3:2:hei+2,2:2:wid+1)+bayerPadding(3:2:hei+2,4:2:wid+2))/4;

    % Kr Kb
    Kr(1:2:hei,1:2:wid)      = imDst(1:2:hei,1:2:wid,2) - bayerPadding(2:2:hei+1,2:2:wid+1);
    Kb(2:2:hei,2:2:wid)      = imDst(2:2:hei,2:2:wid,2) - bayerPadding(3:2:hei+2,3:2:wid+2);

    Kr                       = Demosaic_bilinear(Kr,pattern);
    Kr                       = Kr(:,:,1);

    Kb                       = Demosaic_bilinear(Kb,pattern);
    Kb                       = Kb(:,:,3);   

    imDst(:,:,1)             = imDst(:,:,2) - Kr;
    imDst(:,:,3)             = imDst(:,:,2) - Kb; 
elseif pattern == 'bggr'
    % g
    imDst(1:2:hei,2:2:wid,2) = bayerPadding(2:2:hei+1,3:2:wid+2);
    imDst(2:2:hei,1:2:wid,2) = bayerPadding(3:2:hei+2,2:2:wid+1);
    imDst(1:2:hei,1:2:wid,2) = (bayerPadding(1:2:hei,2:2:wid+1)+bayerPadding(3:2:hei+2,2:2:wid+1)+...
                                bayerPadding(2:2:hei+1,1:2:wid)+bayerPadding(2:2:hei+1,3:2:wid+2))/4;
    imDst(2:2:hei,2:2:wid,2) = (bayerPadding(2:2:hei+1,3:2:wid+2)+bayerPadding(4:2:hei+2,3:2:wid+2)+...
                                bayerPadding(3:2:hei+2,2:2:wid+1)+bayerPadding(3:2:hei+2,4:2:wid+2))/4;

    % Kr Kb
    Kb(1:2:hei,1:2:wid)      = imDst(1:2:hei,1:2:wid,2) - bayerPadding(2:2:hei+1,2:2:wid+1);
    Kr(2:2:hei,2:2:wid)      = imDst(2:2:hei,2:2:wid,2) - bayerPadding(3:2:hei+2,3:2:wid+2);

    Kr                       = Demosaic_bilinear(Kr,pattern);
    Kr                       = Kr(:,:,1);

    Kb                       = Demosaic_bilinear(Kb,pattern);
    Kb                       = Kb(:,:,3);   

    imDst(:,:,1)             = imDst(:,:,2) - Kr;
    imDst(:,:,3)             = imDst(:,:,2) - Kb;     
end

你可能感兴趣的:(ISP-Pipeline,图像处理)