OpenCV 常用圖像拼接方法(二):基於模板匹配拼接


OpenCV常用圖像拼接方法將分為四個部分與大家共享,這里是第二種方法,歡迎關注后續,此處子系統與素材鏈接位於文章末尾。

    OpenCV常用圖像拼接方法(二):基於模板匹配的圖像拼接。基於模板的圖像拼接特征和適用范圍:圖像有重合區域,且待分割圖像之間無明顯尺度變化和畸變。常用實例:兩個相鄰相機水平拍攝圖像拼接。優點:簡單,快速(相比於SIFT特征匹配拼接)。

    這里沒有找到更好的實例圖片,所以仍使用上一篇文章中的圖片,截取如下兩部分ROI作為待拆分圖像。

   待拼接圖①:

    待拼接圖②:

    思路:在圖①中截取部分公共區域ROI作為模板,利用模板在圖②中匹配,得到最佳匹配位置后計算X和Y方向需要平移的距離,將圖②對應的拼接到大圖。如下,模板為青色區域:

    部分代碼和效果如下:

 
        
 1 // Image_Stitch_With_Matchtemplate.cpp  2 // 環境VS2017 + OpenCV4.4.0  3 // 功能:基於模板匹配的圖像拼接  4 // 特點:圖像有重合區域,且待拼接圖像之間無明顯尺度變換和畸變
 5  
 6 #include "pch.h"
 7 #include <iostream>
 8 #include <opencv2/opencv.hpp>
 9  
10 using namespace std; 11 using namespace cv; 12  
13 int main() 14 { 15   Mat imgL = imread("A.jpg"); 16   Mat imgR = imread("B.jpg"); 17   double start = getTickCount(); 18  Mat grayL, grayR; 19  cvtColor(imgL, grayL, COLOR_BGR2GRAY); 20  cvtColor(imgR, grayR, COLOR_BGR2GRAY); 21  
22   Rect rectCut = Rect(372, 122, 128, 360); 23   Rect rectMatched = Rect(0, 0, imgR.cols / 2, imgR.rows); 24   Mat imgTemp = grayL(Rect(rectCut)); 25   Mat imgMatched = grayR(Rect(rectMatched)); 26  
27   int width = imgMatched.cols - imgTemp.cols + 1; 28   int height = imgMatched.rows - imgTemp.rows + 1; 29  Mat matchResult(height, width, CV_32FC1); 30  matchTemplate(imgMatched, imgTemp, matchResult, TM_CCORR_NORMED); 31   normalize(matchResult, matchResult, 0, 1, NORM_MINMAX, -1);  //歸一化到0--1范圍
32  
33   double minValue, maxValue; 34  Point minLoc, maxLoc; 35   minMaxLoc(matchResult, &minValue, &maxValue, &minLoc, &maxLoc); 36  
37   Mat dstImg(imgL.rows, imgR.cols + rectCut.x - maxLoc.x, CV_8UC3, Scalar::all(0)); 38   Mat roiLeft = dstImg(Rect(0, 0, imgL.cols, imgL.rows)); 39  imgL.copyTo(roiLeft); 40  
41   Mat debugImg = imgR.clone(); 42   rectangle(debugImg, Rect(maxLoc.x, maxLoc.y, imgTemp.cols, imgTemp.rows), Scalar(0, 255, 0), 2, 8); 43   imwrite("match.jpg", debugImg); 44  
45   Mat roiMatched = imgR(Rect(maxLoc.x, maxLoc.y - rectCut.y, imgR.cols - maxLoc.x, imgR.rows - 1 - (maxLoc.y - rectCut.y))); 46   Mat roiRight = dstImg(Rect(rectCut.x, 0, roiMatched.cols, roiMatched.rows)); 47  
48  roiMatched.copyTo(roiRight); 49  
50   double end = getTickCount(); 51   double useTime = (end - start) / getTickFrequency(); 52   cout << "use-time : " << useTime << "s" << endl; 53  
54   imwrite("dst.jpg", dstImg); 55   cout << "Done!" << endl; 56   return 0; 57  
58 }

匹配結果:

    拼接結果:

    本次耗時如下圖:( 工業相機1200W圖片拼接大約200ms):


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM