1. 程式人生 > >python+opencv實現影象全景拼接

python+opencv實現影象全景拼接

一、演算法目的

隨便拍攝兩張圖片(圖一和圖二),兩圖之間有相同的拍攝區域,需要將兩幅影象無縫拼接在一起,完全接壤。

二、存在問題

由於鏡頭拍照的位置不同,會導致圖一和圖二雖然有相同的拍攝區域,但是並不能簡單的將圖二和圖一的重疊區域覆蓋進行拼接。因為拍攝圖一和圖二是,相機的世界座標位置基本會發生變化。試想一下,你首先在A位置看到物體一,然後換到B位置再看物體一,物體一雖然仍在你的視野裡,但是,它在你眼中與周圍參照物的距離會發生變化(除非你只是轉到一下眼珠),位置不同,光線也可能不同,這都是拼接過程中存在的問題

三、處理步驟

1、首先需要將影象進行桶形變換。該變換的主要目的是為了減少拼接後圖片的畸變,如果沒有進行桶形變換,拼接出來的圖片可能是這樣的:

如果還有更多的圖片,拼出來的效果可能更加誇張:

那為什麼桶形變換後就能改善拼接效果呢?作者認為由於圖1和圖2的重疊區域主要是在邊緣,進行桶形變換後縮減了邊緣影象匹配的發散,儘量讓匹配點的縱座標的差值減小,縮減透視變換後的變形。可是這一點我在網上看了好多,沒有介紹怎麼實現桶形變換的,大部分都是桶形變換的校正,如果哪位有相關的資料,希望能分享一下。

2、桶形變換後,需要找到兩幅圖中相同的特徵點,也就是特徵點匹配。

在此首先需要計算特徵點,然後將特徵點進行匹配(可用到的特徵有sift、surf、fast、角點等)。作者用的是sift,它具有旋轉不變性和縮放不變性,效果很好,理論資料以及程式碼都可以在網上找到,這裡不作詳解,只是速度非常慢,如果只是離線計算透視矩陣,可以考慮選用它。

3、經過上面步驟後,我們獲得了特徵匹配點(即圖1和圖2中同樣特徵點分別在兩圖中的座標),這時候使用BF匹配法(也可以使用FLANN),找到兩幅影象之間的最佳匹配點,如果最佳匹配點小於4,就返回None,因為計算變換矩陣時,最少要四個點。

通過計算得到變換矩陣

4、利用得到的變換矩陣執行透視變化,然後兩幅影象合併

可以看出來,合併以後效果並不好,有明顯顏色區分,所以我們要進行下一步,影象的配準。

5、影象合併修補

從上圖可以看出,兩圖的拼接並不自然,原因就在於拼接圖的交界處,兩圖因為光照色澤的原因使得兩圖交界處的過渡很糟糕,所以需要特定的處理解決這種不自然。這裡的處理思路是加權融合,在重疊部分由前一幅影象慢慢過渡到第二幅影象,即將影象的重疊區域的畫素值按一定的權值相加合成新的影象。

通過透視變換,會產生黑邊,所以還要特殊處理,通過對畫素值處理,可以消除黑邊問題,不過這又衍生了一個新的問題,當影象變換過大時,會產生鋸齒黑邊,通過黑色畫素處理並不能解決這個問題。如果哪位有好的思路,請留言,大家共同進步。

如果你仔細觀察的話,會發現中間的影象最上面中間部分其實有一點拼接的痕跡,這就是透視變換產生的鋸齒邊緣,由於顏色非常接近藍色,所以單純的黑色畫素值判斷識別不了,對此,我又對鋸齒邊緣部分做了特殊處理,但是還是有瑕疵,所以為了達到完美的效果,只能把這一點切除了。

四、總結

最後,我們再來總結一下,要進行影象的無縫拼接,我們的目標就是獲得透視矩陣H,而為了獲得透視矩陣,首先需要尋找到影象的特徵點(sift,surf等),然後把兩個影象中相同的特徵點找出來,再根據最佳匹配點(bf,flann)計算透視矩陣H

計算出透視矩陣以後,剩下的就是讓圖二經過H矩陣進行透視變換,讓圖二在圖一的座標系下表示,然後在經過加權融和,進行黑邊的處理,就可以實現無縫拼接了。

具體程式碼都放在:https://download.csdn.net/download/qq_36387683/10461258