立體匹配中圖像重疊分塊的實現方法

本文分三部分:

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_Read i_Write i_Offset
1st 0 0 0
Middle i*(BLOCK-2*OVERLAP) i_Read+OVERLAP OVERLAP
Last size-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);
		}
	}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章