1. 程式人生 > >360全景影象拼接

360全景影象拼接

剛到實驗室,做了一個全景影象拼接的training project,自己前前後後搞了1個多月(汗啊,只能自我安慰是接觸到的第一個圖形學的東西),嘗試了幾種方法,寫了很多無用程式碼,下面把我一路曲曲折折的過程丟擲來,希望能對大家有些許幫助吧。

    一. 做拼接的第一步一定是warp,就是把每張影象投影到柱面或者球面,我將每張圖片做了柱面投影,而這麼做的理由呢,就是將影象投影到統一的面上以方便拼接,根據我做的過程中的理解就是使拼接的影象很平滑,當然如果只是拼接兩張圖片的話,完全可以省略這一步。

    二. 影象拼接的第二步就是提取特徵點(也可以採用邊特徵的提取),特徵點的提取方法有很多,我使用了lowe的SIFT,SIFT是一個非常魯棒的演算法,但是速度很慢,如果想程式執行速度很快,可以使用其他特徵點提取方法,lowe提供了SIFT的原始碼,可以直接使用。

    三. 提取出兩張圖片的特徵點以後,就要找到特徵點間的對應關係,這一步是一個簡單的距離比值刪選的過程,我自己實現了一個暴力篩選的方法,還是比較簡單的,但是這樣肯定會很影響速度,所以要使用一個k-d tree的approximate nearest neighbour演算法,可以用ann庫實現,當然也可以直接用rob hess的特徵點匹配演算法實現。

    四. 上一步找到對應特徵點以後,接下就是用RANSAC對已有匹配進行篩選並求出對應的homography,實際上就是一個簡單的迭代過程。

    五. 求出homography以後就可以進行alignment了,這一步可以用opencv提供的WarpPerspective函式實現,但是用這個函式一張影象經過幾次align之後,拼接後圖像越靠右邊越有發散效果,所以用這個函式只有兩張圖片好用(如果有人知道多張圖片怎麼用這個函式進行拼接,請您不吝賜教),這一步還有一個很重要的邊界問題,及拼接影象轉換後的座標可能出現負值,這一點一定要考慮進去,否則會出現拼接後的影象包含不全的情況。

    六. alignment之後就是blend的問題,以使拼接邊界不那麼明顯,我採用了一個簡單的線性的距離權值演算法,效果還可以看,即pixel=pixel_a*alpha+pixel_b*(1-alpha),alpha為當前畫素點距拼接左邊界的距離除以整個重疊區域的寬度。下面兩張圖分別是4張,3張影象用WarpPerspective函式拼接的。



    七. 如果你只需要拼接兩張圖片,那到上一步就可以了,以下是360度拼接的額外過程,即圖片有n張的情況,我只考慮了所有圖片都屬於一個全景圖沒有噪音圖片的亂序圖片的情況。要先將圖片排好序,以下為排序過程:①在所有影象對間找到inliers個數最多兩張影象②在兩張圖片的基礎上向前向後依次找出與當前影象鄰接的影象直到結束。

    八. 經過上一步就可以進行alignment了,因為之前用提過的WarpPerspective函式使用中的問題,這一步只使用了homography中的水平和垂直平移分量tx,ty,依舊採用線性權值的方法進行blend,多長影象拼接還有一個很重要的問題就是拼接後首尾不能相接的情況,這就需要驚醒調整,比較好的方法是bundle adjustment,我也分別用opencv和sba實現了,但是估計還是實現的方法不對,調了好長時間沒有出效果,無奈只能先放棄了,以後比較閒的時候再實現吧(如果有人在這一步用bundle adjustment實現,請賜教)。轉去實現了一個比較簡單的線性調整的方法,最後結果看起來還可以,有些模糊的地方,我估計可能是blend方法的問題,但是沒有繼續實現multi-blend,所以結果只能是現在這樣了。

    總之呢,整個拼接程式還比較粗糙,有很多地方有待完善,歡迎大家有問題可以和我交流。下面為兩個17張圖片的全景圖