zoukankan      html  css  js  c++  java
  • OpenCV常用图像拼接方法(二):基于模板匹配拼接

        OpenCV常用图像拼接方法将分为四个部分与大家共享,这里是第二种方法,欢迎关注后续,此处子系统与素材链接位于文章末尾

        OpenCV常用图像拼接方法(二):基于模板匹配的图像拼接。基于模板的图像拼接特征和适用范围图像有重合区域,且待分割图像之间无明显尺度变化和畸变。常用实例:两个相邻相机水平拍摄图像拼接。优点:简单,快速(相比于SIFT特征匹配拼接)。

        这里没有找到更好的实例图片,所以仍使用上一篇文章中的图片,截取如下两部分ROI作为待拆分图像。

      待拼接图①:

     待拼接图②:

     思路:在图①中截取部分公共区域ROI作为模板,利用模板在图②中匹配,得到最佳匹配位置后计算X和Y方向需要平移的距离,将图②对应的拼接到大图。如下,模板为青色区域:

     

     部分代码和效果如下:

    // Image_Stitch_With_Matchtemplate.cpp
    // 环境VS2017 + OpenCV4.4.0
    // 功能:基于模板匹配的图像拼接
    // 特点:图像有重合区域,且待拼接图像之间无明显尺度变换和畸变
    
    #include "pch.h"
    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    int main()
    {
      Mat imgL = imread("A.jpg");
      Mat imgR = imread("B.jpg");
      double start = getTickCount();
      Mat grayL, grayR;
      cvtColor(imgL, grayL, COLOR_BGR2GRAY);
      cvtColor(imgR, grayR, COLOR_BGR2GRAY);
    
      Rect rectCut = Rect(372, 122, 128, 360);
      Rect rectMatched = Rect(0, 0, imgR.cols / 2, imgR.rows);
      Mat imgTemp = grayL(Rect(rectCut));
      Mat imgMatched = grayR(Rect(rectMatched));
    
      int width = imgMatched.cols - imgTemp.cols + 1;
      int height = imgMatched.rows - imgTemp.rows + 1;
      Mat matchResult(height, width, CV_32FC1);
      matchTemplate(imgMatched, imgTemp, matchResult, TM_CCORR_NORMED);
      normalize(matchResult, matchResult, 0, 1, NORM_MINMAX, -1);  //归一化到0--1范围
    
      double minValue, maxValue;
      Point minLoc, maxLoc;
      minMaxLoc(matchResult, &minValue, &maxValue, &minLoc, &maxLoc);
    
      Mat dstImg(imgL.rows, imgR.cols + rectCut.x - maxLoc.x, CV_8UC3, Scalar::all(0));
      Mat roiLeft = dstImg(Rect(0, 0, imgL.cols, imgL.rows));
      imgL.copyTo(roiLeft);
    
      Mat debugImg = imgR.clone();
      rectangle(debugImg, Rect(maxLoc.x, maxLoc.y, imgTemp.cols, imgTemp.rows), Scalar(0, 255, 0), 2, 8);
      imwrite("match.jpg", debugImg);
    
      Mat roiMatched = imgR(Rect(maxLoc.x, maxLoc.y - rectCut.y, imgR.cols - maxLoc.x, imgR.rows - 1 - (maxLoc.y - rectCut.y)));
      Mat roiRight = dstImg(Rect(rectCut.x, 0, roiMatched.cols, roiMatched.rows));
    
      roiMatched.copyTo(roiRight);
    
      double end = getTickCount();
      double useTime = (end - start) / getTickFrequency();
      cout << "use-time : " << useTime << "s" << endl;
    
      imwrite("dst.jpg", dstImg);
      cout << "Done!" << endl;
      return 0;
    
    }
    

      匹配结果:

     拼接结果:

      本次耗时如下图:( 工业相机1200W图片拼接大约200ms):

     

  • 相关阅读:
    设计tag的sql语句,支持每个tag的个数,Access数据库非msSql
    ulObj ul = new ulObj();
    Access 日期比较用 #扩住日期 代码如下
    dw中IMG标记的正则替换
    许涛的 repeater itemCommand 事件代码(经典代码,不难)
    n1视觉图片列表样式[jquery代码][A标记里面一个IMG一个EM]
    flashbox小组件开发~~开源~~
    动态读取一张图片到mc里,读取txt中的内容 flash as 全站flash专题
    简单的jQueryTab 自写的小代码
    flashCs3 按钮事件没了?原来As3已经改为监听模式了!
  • 原文地址:https://www.cnblogs.com/stq054188/p/13466483.html
Copyright © 2011-2022 走看看