我没有使用python nor opencv但很好奇所以这里水平较低C++对此的方法:
- 按波段分别处理图像
-
对于每个像素,您需要强度累加器acc[][]
和柜台cnt[][]
可以避免对计数器的需要。您可以使用以类似方式编码的预定义计数,然后mask
在我的代码中,但这意味着处理图像边缘和角落的特殊情况。我选择了acc,cnt
为了简单起见(它们很容易适应 32 位,所以没有必要不使用它)。
除法可以通过位移位来完成(边缘和角落除外)
clear acc,cnt
与零
-
处理包含已处理带的每个像素
将谱带强度添加到acc
和增量cnt
到像素位置以及不包含该带的所有邻居。
-
整个图像处理后计算像素带值
简单地通过
pixel[y][x].band = acc[y][x]/cnt[y][x]
这样你就可以使用相同的缓冲区acc,cnt
为下一个乐队。
My 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
is VCL封装的GDI位图与Canvas
access
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]
。最后是结果:对于您的输入图像: