手动实现拜仁到RGB [英] Manual implementation bayern to RGB

查看:127
本文介绍了手动实现拜仁到RGB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to implement image transformation Bayern Pattern -> RGB

我上传了这张图片:

以下是我的代码片段:

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]

在上面的例子中我使用这种模式:

In the above example I use this pattern:

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

I am supposed to interpolate the missing values but the places with 'no values' are actually filled with zeros. When I perform this:

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

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

I don't get the expected result as I'm using zeros in interpolation.

推荐答案

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

I am not using python nor opencv but was curious so here low level C++ approach for this:


  1. 分别按频段处理图像

  2. 每个像素需要强度累加器 acc [] [] 和计数器 cnt [] []

  1. process image by bands separately
  2. for each pixel you need intensity accumulator acc[][] and counter cnt[][]

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

the need for counter can be avoided. You can use predefined counts encoded in similar manner then the mask in my code but this mean handling special cases on edges and corners of image. I chose acc,cnt for simplicity (they fit into 32bit easily so there is no point to not using it).

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

The division can be done with bit-shift for speed (except on edges and corners)

清除 acc, cnt 零;

clear acc,cnt with zero

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

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

add the band intensity to acc and increment cnt to pixel position and also to all neighbors not containing this band.

整个图像处理后的计算像素频段值

简单地通过

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

通过这个你可以使用相同的缓冲区 acc,cnt 下一个乐队。

By this you can use the same buffer for acc,cnt for next band.

我的 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(颜色)使用颜色清除整个图像

调整大小(xs,ys)将图片大小调整为新分辨率

bmp VCL 封装 GDI 位图 Canvas 访问

pf 保存图像的实际像素格式:


xs,ys is size of image in pixels
p[y][x].dd is pixel at (x,y) position as 32 bit integer type
clear(color) clears entire image with color
resize(xs,ys) resizes image to new resolution
bmp is VCL encapsulated GDI Bitmap with Canvas access
pf holds actual pixel format of the image:

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 and pixels are encoded like this:

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] 。最后,结果是:对于您的输入图像:

The bayern mask has 1 for pixels that has the color band included and item mask[band][j=0][i=0] represents pixel[y=0][x=0]. Finally here the result: for your input image:

这篇关于手动实现拜仁到RGB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆