我正在尝试实施图像转换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]
我应该插入缺失的值,但是“无值”的地方实际上是用零填充的。当我执行此操作时:
kernel = np.ones((4,4), np.float)/16
new_image[:,:,2] = cv2.filter2D(new_image[:, :, 2], -1, kernel)
我没有得到预期的结果,因为我在插值中使用了零。
答案 0 :(得分:2)
我没有使用 python ,也没有使用 opencv ,但很奇怪所以这里采用低级 C ++ 方法:
对于每个像素,您需要强度累加器acc[][]
和计数器cnt[][]
可以避免对计数器的需求。您可以使用与我的代码中mask
类似的方式编码的预定义计数,但这意味着处理图像边缘和角落的特殊情况。为简单起见,我选择了acc,cnt
(它们很容易适应32位,因此无需使用它)。
除法可以通过位移来实现速度(边缘和角落除外)
清除acc,cnt
零
处理包含已处理频段的每个像素
将频段强度添加到acc
并将cnt
增加到像素位置,并且还添加到不包含此频段的所有邻居。
计算像素带值
简单地通过
pixel[y][x].band = acc[y][x]/cnt[y][x]
通过这个,您可以为acc,cnt
使用相同的缓冲区用于下一个频段。
我的 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]
。最后,结果是:输入图像: