OpenCV圖像拼接改進(jìn)算法之完美拼接
點(diǎn)擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)
前言概述
之前寫了兩篇文章分別是圖像單應(yīng)性矩陣變換與圖像拼接,圖像拼接中使用單應(yīng)性矩陣實(shí)現(xiàn)圖像特征對(duì)齊,從而為圖像拼接特別是無縫拼接打下基礎(chǔ),看一下上一篇我的圖像拼接效果如下:

經(jīng)過分析發(fā)現(xiàn):效果不好的原因是像素疊加的時(shí)候沒有考慮左右兩側(cè)圖像的位置信息,直接通過手動(dòng)指定了融合區(qū)域跟閾值,而不是根據(jù)圖像實(shí)際位置由圖像生成mask層,根據(jù)mask層動(dòng)態(tài)生成融合圖像重疊區(qū)域的閾值,如此可以解決融合不夠自然或者看上去拼接效果不好。最終改進(jìn)之后的兩張圖像拼接效果如下:

是不是一個(gè)完美的無縫圖像拼接我說了不算,大家說了算,歡迎留言反饋!
改進(jìn)思路
想要完美的實(shí)現(xiàn)無縫拼接,有兩個(gè)關(guān)鍵技術(shù)點(diǎn):
特征提取與對(duì)齊階段要取得配準(zhǔn)對(duì)其好的單應(yīng)性矩陣H,要用好的特征提取,千萬別ORB。
拼接階段融合,要有好的圖像融合算法支持,別提金字塔融合,速度太感人了,所以最好一層搞定,間隔權(quán)重采樣是個(gè)好方法。
之前的實(shí)現(xiàn)中圖像對(duì)齊跟配準(zhǔn)做的不錯(cuò),就是最后的拼接效果不好,所以要改進(jìn)圖像融合,實(shí)現(xiàn)無縫融合。這里我觀察了右側(cè)圖像透視變換的結(jié)果,發(fā)現(xiàn)一般都是一個(gè)不規(guī)則的圖像,以我老家房屋的圖像為例:對(duì)齊+透視變換之后如下:

生成的mask圖像如下:

如果想要完美的融合,就不能隨便制定區(qū)域融合,而是根據(jù)右側(cè)透視變換之后的圖像,來生成每一行有多少列是跟左側(cè)圖像重疊的,然后自動(dòng)計(jì)算重疊區(qū)域大小,計(jì)算間隔值,完成最終mask權(quán)重圖像生成,如下圖:

代碼實(shí)現(xiàn)與步驟
我是一個(gè)比較懶的人,代碼已經(jīng)有注釋了,這里我就不過多解釋,只簡(jiǎn)單說一下代碼執(zhí)行流程。
首先是圖像特征提取與求單應(yīng)性矩陣,這步可以省略了。代碼可以參考上一篇文章即可。
使用單應(yīng)性矩陣求得右側(cè)變換之后的圖像跟mask
根據(jù)mask得權(quán)重mask層
最后跟之前的一致,直接融合即可。
特征提取部分代碼,參考之前文章,不寫廢話。融合部分,修改后的代碼如下:
1// 獲取全景圖大小
2int h = max(left.rows, right.rows);
3int w = left.cols + right.cols;
4Mat panorama_01 = Mat::zeros(Size(w, h), CV_8UC3);
5Rect roi;
6roi.x = 0;
7roi.y = 0;
8roi.width = left.cols;
9roi.height = left.rows;
10
11// 獲取左側(cè)與右側(cè)對(duì)齊圖像
12left.copyTo(panorama_01(roi));
13Mat panorama_02;
14warpPerspective(right, panorama_02, H, Size(w, h));
15imwrite("D:/panorama_02.png", panorama_02);
16
17// 計(jì)算融合重疊區(qū)域mask
18Mat mask = Mat::zeros(Size(w, h), CV_8UC1);
19generate_mask(panorama_02, mask);
20
21// 創(chuàng)建遮罩層并根據(jù)mask完成權(quán)重初始化
22Mat mask1 = Mat::ones(Size(w, h), CV_32FC1);
23Mat mask2 = Mat::ones(Size(w, h), CV_32FC1);
24
25// left mask
26linspace(mask1, 1, 0, left.cols, mask);
27
28// right mask
29linspace(mask2, 0, 1, left.cols, mask);
30
31// 左側(cè)融合
32Mat m1;
33vector<Mat> mv;
34mv.push_back(mask1);
35mv.push_back(mask1);
36mv.push_back(mask1);
37merge(mv, m1);
38panorama_01.convertTo(panorama_01, CV_32F);
39multiply(panorama_01, m1, panorama_01);
40
41// 右側(cè)融合
42mv.clear();
43mv.push_back(mask2);
44mv.push_back(mask2);
45mv.push_back(mask2);
46Mat m2;
47merge(mv, m2);
48panorama_02.convertTo(panorama_02, CV_32F);
49multiply(panorama_02, m2, panorama_02);
50
51// 合并全景圖
52Mat panorama;
53add(panorama_01, panorama_02, panorama);
54panorama.convertTo(panorama, CV_8U);
55imwrite("D:/panorama.png", panorama);測(cè)試了一張圖像,特征點(diǎn)匹配效果如下:

拼接融合之后圖像:

說明是真的沒問題了!(邊上還有點(diǎn)黑的,可以直接裁了,比較懶了!)



好消息!
小白學(xué)視覺知識(shí)星球
開始面向外開放啦??????
下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程 在「小白學(xué)視覺」公眾號(hào)后臺(tái)回復(fù):擴(kuò)展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。 下載2:Python視覺實(shí)戰(zhàn)項(xiàng)目52講 在「小白學(xué)視覺」公眾號(hào)后臺(tái)回復(fù):Python視覺實(shí)戰(zhàn)項(xiàng)目,即可下載包括圖像分割、口罩檢測(cè)、車道線檢測(cè)、車輛計(jì)數(shù)、添加眼線、車牌識(shí)別、字符識(shí)別、情緒檢測(cè)、文本內(nèi)容提取、面部識(shí)別等31個(gè)視覺實(shí)戰(zhàn)項(xiàng)目,助力快速學(xué)校計(jì)算機(jī)視覺。 下載3:OpenCV實(shí)戰(zhàn)項(xiàng)目20講 在「小白學(xué)視覺」公眾號(hào)后臺(tái)回復(fù):OpenCV實(shí)戰(zhàn)項(xiàng)目20講,即可下載含有20個(gè)基于OpenCV實(shí)現(xiàn)20個(gè)實(shí)戰(zhàn)項(xiàng)目,實(shí)現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。 交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請(qǐng)按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~

