Image Stitching with OpenCV and Python
在本教程中郊楣,您將學習如何使用Python祈纯,OpenCV和cv2.createStitcher和cv2.Stitcher_create函數執(zhí)行圖像拼接。
使用今天的代碼宦芦,您將可以將多張圖像拼接在一起,從而創(chuàng)建出拼接圖像的全景圖。
就在不到兩年前情竹,我發(fā)布了有關圖像拼接和全景圖構建的兩個指南:
這兩個教程都涵蓋了典型圖像拼接算法的基礎知識,該算法至少需要四個關鍵步驟:
- 從兩個輸入圖像中檢測關鍵點(DoG匀哄,Harris等)并提取局部不變描述符(SIFT秦效,SURF等)
- 在圖像之間匹配描述符
- 使用RANSAC算法通過匹配的特征向量估計單應矩陣(homography matrix)
- 使用從步驟#3獲得的單應性矩陣應用翹曲變換(warping transformation)
但是,我最初的實現(xiàn)最大的問題是它們不能處理兩個以上的輸入圖像涎嚼。
在今天的教程中阱州,我們將重新討論OpenCV的圖像拼接,包括如何將兩個以上的圖像拼接在一起成為全景圖像法梯。
第一部分將簡要回顧OpenCV的圖像拼接算法苔货,該算法通過cv2.createStitcher和cv2.Stitcher_create函數嵌入OpenCV庫本身。
從那里立哑,我們將審查我們的項目結構夜惭,并實現(xiàn)可用于圖像拼接的Python腳本。
我們將回顧第一個腳本的結果铛绰,注意其局限性诈茧,然后實施第二個Python腳本,該腳本可用于在美學上使圖像拼接效果更加令人滿意捂掰。
最后敢会,我們將檢查第二個腳本的結果,并再次注意任何限制或缺點这嚣。
OpenCV的圖像拼接算法
今天我們將在此處使用的算法類似于Brown和Lowe在2007年的論文《具有不變特征的自動全景圖像拼接》中提出的方法鸥昏。
Automatic Panoramic Image Stitching with Invariant Features
與以前的對圖像輸入順序敏感的圖像拼接算法不同,Brown and Lowe方法更健壯姐帚,使其對以下內容不敏感:
- 圖像順序
- 圖像方向
- 光照變化
- 實際上不是全景圖的一部分的有噪聲圖像
此外吏垮,通過使用增益補償和圖像融合來產生更加美觀的輸出全景圖像。
對該算法進行完整卧土,詳細的介紹超出了本文的范圍惫皱,因此,如果您有興趣了解更多信息尤莺,請參閱原始出版物旅敷。
cv2.createStitcher and cv2.Stitcher_create
OpenCV已經通過cv2.createStitcher(OpenCV 3.x)和cv2.Stitcher_create(OpenCV 4)函數實現(xiàn)了類似于Brown和Lowe論文的方法。
OpenCV 3.x的cv2.createStitcher的功能簽名:
createStitcher(...)
createStitcher([, try_use_gpu]) -> retval
請注意颤霎,此函數只有一個參數try_gpu媳谁,可用于改善整個圖像拼接管道涂滴。 OpenCV的GPU支持有限,而且我永遠無法使該參數正常工作晴音,因此我建議始終將其保留為False柔纵。
OpenCV 4的cv2.Stitcher_create函數具有類似的簽名:
Stitcher_create(...)
Stitcher_create([, mode]) -> retval
. @brief Creates a Stitcher configured in one of the stitching
. modes.
.
. @param mode Scenario for stitcher operation. This is usually
. determined by source of images to stitch and their transformation.
. Default parameters will be chosen for operation in given scenario.
. @return Stitcher class instance.
要執(zhí)行實際的圖像拼接,我們需要調用.stitch方法:
OpenCV 3.x:
stitch(...) method of cv2.Stitcher instance
stitch(images[, pano]) -> retval, pano
OpenCV 4.x:
stitch(...) method of cv2.Stitcher instance
stitch(images, masks[, pano]) -> retval, pano
. @brief These functions try to stitch the given images.
.
. @param images Input images.
. @param masks Masks for each input image specifying where to
. look for keypoints (optional).
. @param pano Final pano.
. @return Status code.
此方法接受輸入圖像列表锤躁,然后嘗試將它們拼接成全景圖搁料,然后將輸出的全景圖圖像返回給調用函數。
status變量指示圖像拼接是否成功系羞,并且可以是四個變量之一:
- OK = 0:圖像拼接成功郭计。
- ERR_NEED_MORE_IMGS = 1:如果您收到此狀態(tài)碼,則需要更多輸入圖像來構建全景圖椒振。
通常昭伸,如果在輸入圖像中沒有檢測到足夠的關鍵點,則會發(fā)生此錯誤澎迎。 - ERR_HOMOGRAPHY_EST_FAIL = 2:當RANSAC單應性估計失敗時庐杨,會發(fā)生此錯誤。
同樣夹供,您可能需要更多圖像灵份,或者圖像沒有足夠的可區(qū)分的獨特紋理/對象來精確匹配關鍵點。 - ERR_CAMERA_PARAMS_ADJUST_FAIL = 3:我之前從未遇到過此錯誤哮洽,所以我對此不太了解各吨,但是要點在于,這與無法從輸入圖像中正確估計相機的內在/外在特性有關袁铐。
如果遇到此錯誤,則可能需要參考OpenCV文檔横浑,甚至需要深入研究OpenCV C ++代碼剔桨。
現(xiàn)在,我們已經回顧了cv2.createStitcher徙融,cv2.Stitcher_create和.stitch方法洒缀,讓我們繼續(xù)實際使用OpenCV和Python實現(xiàn)圖像拼接。
基本圖像拼接結果
但是全景周圍的黑色區(qū)域呢欺冀? 那些是什么树绩?
這些區(qū)域從執(zhí)行構建全景所需的透視扭曲開始。
有一種方法可以消除它們……但是我們將需要在下一部分中實現(xiàn)一些其他邏輯隐轩。
使用OpenCV和Python更好的圖像拼接器
我們的第一個圖像拼接腳本是一個良好的開端饺饭,但是全景圖本身周圍的黑色區(qū)域并不是我們所謂的“美觀”。
更重要的是职车,您不會從內置于iOS瘫俊,Android等的流行圖像拼接應用程序中看到這樣的輸出圖像鹊杖。
因此,我們將對腳本進行一些修改扛芽,并包括一些其他邏輯以創(chuàng)建更美觀的全景圖骂蓖。
我將再次重申此方法是一種破解。
我們將審查基本的圖像處理操作川尖,包括閾值登下,輪廓提取,形態(tài)學操作等叮喳,以便獲得所需的結果被芳。
據我所知,OpenCV的Python綁定無法為我們提供手動提取全景圖的最大內部矩形區(qū)域所需的信息嘲更。 如果有筐钟,請在評論中讓我知道。
所有這些代碼都與我們之前的腳本相同赋朦,但有一個例外篓冲。
--crop命令行參數已添加。 在終端中為該參數提供1時宠哄,我們將繼續(xù)進行裁剪操作壹将。
下一步是我們開始實現(xiàn)其他功能的地方:
局限和缺點
在上一教程中,我演示了如何構建實時全景圖和圖像拼接算法-本教程基于以下事實:我們手動執(zhí)行關鍵點檢測毛嫉,特征提取和關鍵點匹配筋蓖,從而使我們能夠使用所用的單應性矩陣將我們的兩個輸入圖像扭曲成全景圖。
而且祖今,盡管OpenCV內置的cv2.createStitcher和cv2.Stitcher_create函數能夠構造準確,美觀的全景圖辛臊,但該方法的主要缺點之一是仙粱,它抽象了對單應性矩陣的所有訪問。
實時全景圖構建的一種假設是彻舰,場景本身在內容方面變化不大伐割。
一旦我們計算了初始單應性估計,我們只需要偶爾重新計算矩陣即可刃唤。
無需執(zhí)行全面的關鍵點匹配和RANSAC估計隔心,就可以在構建全景圖時極大地提高了速度,因此尚胞,如果無法訪問原始的單應性矩陣硬霍,采用OpenCV的內置圖像拼接算法并對其進行實時轉換將是一個挑戰(zhàn)。
總結
在今天的教程中辐真,您學習了如何使用OpenCV和Python執(zhí)行多個圖像拼接须尚。
使用OpenCV和Python崖堤,我們能夠將多個圖像拼接在一起并創(chuàng)建全景圖像。
我們輸出的全景圖像不僅在縫合位置上準確耐床,而且在美學上也令人愉悅密幔。
但是,使用OpenCV的內置圖像拼接類的最大缺點之一是撩轰,它抽象了許多內部計算胯甩,包括由此產生的單應性矩陣本身。
如果您嘗試執(zhí)行實時圖像拼接堪嫂,如我們在前一篇文章中所做的那樣偎箫,則可能會發(fā)現(xiàn)緩存單應性矩陣并且僅偶爾執(zhí)行關鍵點檢測,特征提取和特征匹配是有益的皆串。
跳過這些步驟并使用緩存的矩陣執(zhí)行透視變形可以減少管道的計算負擔淹办,并最終加快實時圖像拼接算法的速度,但是不幸的是恶复,OpenCV的cv2.createStitcher Python綁定無法為我們提供對原始矩陣怜森。