您的位置:首页 > 其它

立体匹配中图像重叠分块的实现方法

2014-08-18 18:34 323 查看
本文分三部分:

1. 图像直接分块的问题;

2. 图像重叠分块的实现原理介绍;

3. 立体匹配中的图像重叠分块的方法介绍;

1. 图像直接分块的问题

由于内存的限制或为了实现并行处理,对图像进行分块处理是必要的。如果仅仅对图像进行分块处理,然后把处理的图像块进行简单的拼接,容易导致界边处缝的问题(如下图所示)。所以,需要在图像分块时使得相邻图像块有一定的重叠,然后选择最优的处理结果填充重叠区域,从而消除接边缝。





图 1. 左图为直接分块处理结果,右图为重叠分块处理结果
2. 图像重叠分块的实现原理介绍



图 2. 图像分块原理示意图
如上图所示,图像重叠分块时,有三个Block,三个Position和一个Principle:
三个Block是:起始Block,中间Block和边缘Block;

三个Position是:Block在原始图像的读取和写入位置,处理结果有效内容在Block自身的位置;
一个
Principle是:各个Block处理结果的有效部分应该保持保持无缝连接;
基于以上思路,我们列出图像分块时的几个关键参数:
图像纵向块数:m_Tile = (height-BLOCKOVERLAP_Y-1)/(BLOCKHEIGHT-2*BLOCKOVERLAP_Y)+1
图像横向块数:nTile = (width-BLOCKOVERLAP_X-1)/(BLOCKWIDTH-2*BLOCKOVERLAP_X)+1
其中,width和height为原始图像的宽高,BLOCKWIDTH和BLOCKHEIGHT为图像块的宽高,BLOCKOVERLAP_X和BLOCKOVERLAP_Y为图像块横向和纵向的重叠尺寸。因为横向和纵向的公式是完全类似的,为了简便起见,下面我们用size,BLOCK,OVERLAP来相应代替上面的三个量。

图像重叠分块参数表

i_Readi_Writei_Offset
1st000
Middlei*(BLOCK-2*OVERLAP)i_Read+OVERLAPOVERLAP
Lastsize-BLOCK(i+1)*BLOCK-(2*i-1)*OVERLAP-size(i+1)*BLOCK-(2*i-1)*OVERLAP-size
上面的表中还有一项i_Offset表示的是Block处理结果的有效内容的起始位置,在写入图像时,要从Block的此位置开始读取内容并写入原始图像从i_Write开始的内存中。

3. 立体匹配中的图像重叠分块的方法介绍

立体匹配中使用分块处理的方法和一般的图像处理的分块方法不同,因为Block之间的对应需要一个初始的视差来驱动,否则可能导致图像块之间没有很好的重叠(如图3所示)。



图 3. 无初始视差驱动的航空影像分块处理
所以,如果有初始视差图来驱动,就可以很好地实现影像分块,而且这时不仅可以解除内存限制或者实现并行处理,还可以减小每个图像块的视差搜索范围,因此最终还有可能减少误匹配率。
基于此方法,立体匹配的分块处理方法框架如下:

int mTile = (height-BLOCKOVERLAP_Y-1)/(BLOCKHEIGHT-2*BLOCKOVERLAP_Y)+1;
int nTile = (width-BLOCKOVERLAP_X-1)/(BLOCKWIDTH-2*BLOCKOVERLAP_X)+1;

for (int m=0;m<mTile;m++)
{

int m_index= m*(BLOCKHEIGHT-2*BLOCKOVERLAP_Y);
int m_offset = BLOCKOVERLAP_Y;
int m_write = m_index+BLOCKOVERLAP_Y;
if (m==0)
{
m_offset = 0;
m_write = 0;
}
else if (m == mTile-1)
{
m_index = height-BLOCKHEIGHT;
m_offset = (m+1)*BLOCKHEIGHT-(2*m-1)*BLOCKOVERLAP_Y-height;
m_write = m*BLOCKHEIGHT-(2*m-1)*BLOCKOVERLAP_Y;
}

for (int n=0;n<nTile;n++)
{
int n_index = n*(BLOCKWIDTH-2*BLOCKOVERLAP_X);
int n_offset=BLOCKOVERLAP_X;
int n_write = n_index+BLOCKOVERLAP_X;

if (n==0)
{
n_offset = 0;
n_write = 0;
}
else if (n == nTile-1)
{
n_index = width-BLOCKWIDTH;
n_offset = (n+1)*BLOCKWIDTH-(2*n-1)*BLOCKOVERLAP_X-width;
n_write = n*BLOCKWIDTH-(2*n-1)*BLOCKOVERLAP_X;
}
CopyImgData(n_index,m_index,width,height,0,0,BLOCKWIDTH,BLOCKHEIGHT);
//计算整体视差平移量
int AvgBlockDisp = 0;
int num_disp = BLOCKWIDTH*BLOCKHEIGHT;
for (int i=0;i<num_disp;i++)
{

AvgBlockDisp += dm->disparity[i];

}
AvgBlockDisp /= num_disp;
int n_index_refer = n_index+AvgBlockDisp;

CopyImgData(bufl_block,bufl,n_index_refer,m_index,width,height,0,0,BLOCKWIDTH,BLOCKHEIGHT);
CopyImgData(bufr_block,bufr,n_index,m_index,width,height,0,0,BLOCKWIDTH,BLOCKHEIGHT);

Match();

//还原到原始视差范围
for (int i=0;i<BLOCKHEIGHT;i++)
{
for (int j=0;j<BLOCKWIDTH;j++)
{
dm->disparity[i*BLOCKWIDTH+j] += AvgBlockDisp;
}
}
//写入到内存
CopyImgData(n_offset,m_offset,BLOCKWIDTH,BLOCKHEIGHT,n_write,m_write,width,height);
CopyImgData(n_offset,m_offset,BLOCKWIDTH,BLOCKHEIGHT,n_write,m_write,width,height);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: