手动实现拜仁到RGB

时间:2017-01-21 03:40:27

标签: python opencv image-processing

我正在尝试实施图像转换Bayern Pattern - > RGB

我上传了这张图片:mosaic picture

以下是我的代码片段:

import cv2
import numpy as np
from matplotlib import pyplot as plt
import math
import os
PATH = 'data/'

file_path = os.path.join(PATH, 'oldwell_mosaic.png')
img = cv2.imread(file_path, 0)
w, h = img.shape
new_image = np.zeros((w, h, 3), dtype = np.uint8)
# Green
new_image[1::2,1::2,1] = img[1::2,1::2]
new_image[::2, ::2, 1] = img[::2, ::2]

# Blue
new_image[1::2,::2,0] = img[1::2,::2]

# Red
new_image[::2, 1::2, 2] = img[::2, 1::2]

在上面的例子中,我使用这种模式:
enter image description here

我应该插入缺失的值,但是“无值”的地方实际上是用零填充的。当我执行此操作时:

kernel = np.ones((4,4), np.float)/16
new_image[:,:,2] = cv2.filter2D(new_image[:, :, 2], -1, kernel)

我没有得到预期的结果,因为我在插值中使用了零。

1 个答案:

答案 0 :(得分:2)

我没有使用 python ,也没有使用 opencv ,但很奇怪所以这里采用低级 C ++ 方法:

  1. 分别按频段处理图片
  2. 对于每个像素,您需要强度累加器acc[][]和计数器cnt[][]

    可以避免对计数器的需求。您可以使用与我的代码中mask类似的方式编码的预定义计数,但这意味着处理图像边缘和角落的特殊情况。为简单起见,我选择了acc,cnt(它们很容易适应32位,因此无需使用它)。

    除法可以通过位移来实现速度(边缘和角落除外)

  3. 清除acc,cnt

  4. 处理包含已处理频段的每个像素

    将频段强度添加到acc并将cnt增加到像素位置,并且还添加到不包含此频段的所有邻居。

  5. 完整图像处理后的
  6. 计算像素带值

    简单地通过

    pixel[y][x].band = acc[y][x]/cnt[y][x]
    

    通过这个,您可以为acc,cnt使用相同的缓冲区用于下一个频段。

  7. 我的 C ++ 实施:

        picture pic0,pic1,pic2; // pic0 - original input image,pic1 output, pic2 temp band interpolation
        int x,y,a,b,i,j;
        const int mask[3][6][6]=    // bayern mask for eac band 3 bands and common size of 2x2 and 3x3 is 6x6
            {
            // blue
                {
                {0,0,0,0,0,0},
                {0,1,0,1,0,1},
                {0,0,0,0,0,0},
                {0,1,0,1,0,1},
                {0,0,0,0,0,0},
                {0,1,0,1,0,1},
                },
            // green
                {
                {0,1,0,1,0,1},
                {1,0,1,0,1,0},
                {0,1,0,1,0,1},
                {1,0,1,0,1,0},
                {0,1,0,1,0,1},
                {1,0,1,0,1,0},
                },
            // red
                {
                {1,0,1,0,1,0},
                {0,0,0,0,0,0},
                {1,0,1,0,1,0},
                {0,0,0,0,0,0},
                {1,0,1,0,1,0},
                {0,0,0,0,0,0},
                },
            };
        // prepare buffers
        pic1.resize(pic0.xs  ,pic0.ys  ); pic1.pf=_pf_rgba; pic1.clear(0);
        pic2.resize(pic0.xs+2,pic0.ys+2); pic2.pf=_pf_uu;   // size enlarged to avoid edge conditions statements
        // process bands
        for (b=0;b<3;b++)
            {
            pic2.clear(0);              // clear acc,cnt
            for (j=0,y=0;y<pic0.ys;y++,(j==5)?j=0:j++)
             for (i=0,x=0;x<pic0.xs;x++,(i==5)?i=0:i++)
              if (mask[b][j][i])        // process only band b pixels
                {
                a=pic0.p[y][x].db[0];   // grayscale intensity
                // add to 4 neighbors
                pic2.p[y+0][x+1].dw[0]+=a; pic2.p[y+0][x+1].dw[1]++;
                pic2.p[y+1][x+0].dw[0]+=a; pic2.p[y+1][x+0].dw[1]++;
                pic2.p[y+1][x+1].dw[0]+=a; pic2.p[y+1][x+1].dw[1]++;
                pic2.p[y+1][x+2].dw[0]+=a; pic2.p[y+1][x+2].dw[1]++;
                pic2.p[y+2][x+1].dw[0]+=a; pic2.p[y+2][x+1].dw[1]++;
                if (b==picture::_g) continue;
                // add to 8 neighbors (for r,b bands)
                pic2.p[y+0][x+0].dw[0]+=a; pic2.p[y+0][x+0].dw[1]++;
                pic2.p[y+0][x+2].dw[0]+=a; pic2.p[y+0][x+2].dw[1]++;
                pic2.p[y+2][x+0].dw[0]+=a; pic2.p[y+2][x+0].dw[1]++;
                pic2.p[y+2][x+2].dw[0]+=a; pic2.p[y+2][x+2].dw[1]++;
                }
            for (y=0;y<pic1.ys;y++) // convert to color band
             for (x=0;x<pic1.xs;x++)
              pic1.p[y][x].db[b]=pic2.p[y+1][x+1].dw[0]/pic2.p[y+1][x+1].dw[1];
            }
    

    我将自己的图片类用于图片,因此有些成员是:


    xs,ys是图像的大小(以像素为单位)
    p[y][x].dd(x,y)位置的像素,为32位整数类型
    clear(color)使用color清除整个图像
    resize(xs,ys)将图片调整为新分辨率
    bmp VCL 已封装 GDI 具有Canvas访问权限的位图
    pf保存图像的实际像素格式:

    enum _pixel_format_enum
        {
        _pf_none=0, // undefined
        _pf_rgba,   // 32 bit RGBA
        _pf_s,      // 32 bit signed int
        _pf_u,      // 32 bit unsigned int
        _pf_ss,     // 2x16 bit signed int
        _pf_uu,     // 2x16 bit unsigned int
        _pixel_format_enum_end
        };
    


    color和像素编码如下:

    union color
        {
        DWORD dd; WORD dw[2]; byte db[4];
        int i; short int ii[2];
        color(){}; color(color& a){ *this=a; }; ~color(){}; color* operator = (const color *a) { dd=a->dd; return this; }; /*color* operator = (const color &a) { ...copy... return this; };*/
        };
    

    这些乐队是:

    enum{
        _x=0,   // dw
        _y=1,
    
        _b=0,   // db
        _g=1,
        _r=2,
        _a=3,
    
        _v=0,   // db
        _s=1,
        _h=2,
        };
    

    对于包含色带且项目1代表mask[band][j=0][i=0]的像素,拜仁蒙版具有pixel[y=0][x=0]。最后,结果是:输入图像:

    colors