【分享帖】立体匹配中图像重叠分块的实现方法
转自:http://blog.csdn.net/visualman_whu/article/details/38663039

本文分三部分:

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

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

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

1. 图像直接分块的问题

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

20140818171139528.jpg

20140818171204972.jpg


图 1. 左图为直接分块处理结果,右图为重叠分块处理结果

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

20140818171957278.jpg


图 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所示)。

20140818182258163.jpg


图 3. 无初始视差驱动的航空影像分块处理

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

基于此方法,立体匹配的分块处理方法框架如下:


[cpp] view plain copy



  • 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;



  • }


  • 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);


  • }


  • }


请问这篇文章对你有用吗?
【分享帖】立体匹配中图像重叠分块的实现方法
所有评论
暂无更多
暂无更多
关于作者
哈哈哈
哈哈哈
0 关注Ta
0 文章
0 经验值
0 获赞