模板匹配的作用在图像识别领域作用可大了。那什么是模板匹配?

模板匹配,就是在一幅图像中寻找另一幅模板图像最匹配(也就是最相似)的部分的技术。

说的有点抽象,下面给个例子说明就很明白了。

在上面这幅全明星照中,我们想找出姚明头像的位置,并把它标记出来,可以做到吗?

可以,这就是模板匹配的要做的事情。

其实模板匹配实现的思想也是很简单很暴力的,就是拿着模板图片(姚明头像)在原图(全明星照)中从左上至右下依次滑动,直到遇到某个区域的相似度低于我们设定的阈值,那么我们就认为该区域与模板匹配了,也就是我们找到了姚明的位置,并把它标记出来。

OpenCV中是通过MtachTemplate函数完成。

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>using namespace std;
using namespace cv;int main()
{Mat img, templ, result;img = imread("nba.jpg");templ = imread("76.png");int result_cols = img.cols - templ.cols + 1;int result_rows = img.rows - templ.rows + 1;result.create(result_cols, result_rows, CV_32FC1);matchTemplate(img, templ, result, CV_TM_SQDIFF_NORMED);//这里我们使用的匹配算法是标准平方差匹配 method=CV_TM_SQDIFF_NORMED,数值越小匹配度越好normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());double minVal = -1;double maxVal;Point minLoc;Point maxLoc;Point matchLoc;cout << "匹配度:" << minVal << endl;minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());cout << "匹配度:" << minVal << endl;matchLoc = minLoc;rectangle(img, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar(0, 255, 0), 2, 8, 0);imshow("img", img);waitKey(0);return 0;
}

结果看来,大姚的头像位置确实被绿框标记出来了!很准!

我还在程序中特意打印出匹配度的最小值,因为我们知道这个算法是数值越小匹配度越高,由输出的结果看来这个数值还真的很小,说明匹配度真的相当高!

既然我们可以取得匹配度的数值,那我们是不是也可以利用该数值进行阈值对比呢?比如我想把在阈值范围之内的头像都标记出来。可以这么做:

//阈值判别,小于0.01才认为匹配成功,才将头像框出来
if (minVal < 0.001)
{rectangle(img, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar(0, 255, 0), 2, 8, 0);
}

同理,如果是数值越大表明匹配度越大的算法,就使用maxVal来对比就可以了。

上面的模板匹配我们使用了标准平方差匹配 CV_TM_SQDIFF_NORMED算法,看起来效果还不错,那还有其他算法吗?

问得好。OpenCV通过函数 matchTemplate 实现了模板匹配算法。可用的方法有6个:

通常,随着从简单的测量(平方差)到更复杂的测量(相关系数),我们可获得越来越准确的匹配(同时也意味着越来越大的计算代价)。
最好的办法是对所有这些设置多做一些测试实验,以便为自己的应用选择同时兼顾速度和精度的最佳方案。

你想采用哪种算法,只需要将对应的传进函数matchTemplate里就可以了。

下面给出利用trackbar显示出多种模板那匹配算法的代码。

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>using namespace cv;
using namespace std;Mat g_srcImage, g_tempalteImage, g_resultImage;
int g_nMatchMethod;
int g_nMaxTrackbarNum = 5;void on_matching(int, void*)
{Mat srcImage;g_srcImage.copyTo(srcImage);int resultImage_cols = g_srcImage.cols - g_tempalteImage.cols + 1;int resultImage_rows = g_srcImage.rows - g_tempalteImage.rows + 1;g_resultImage.create(resultImage_cols, resultImage_rows, CV_32FC1);matchTemplate(g_srcImage, g_tempalteImage, g_resultImage, g_nMatchMethod);normalize(g_resultImage, g_resultImage, 0, 2, NORM_MINMAX, -1, Mat());double minValue, maxValue;Point minLocation, maxLocation, matchLocation;minMaxLoc(g_resultImage, &minValue, &maxValue, &minLocation, &maxLocation);if (g_nMatchMethod == TM_SQDIFF || g_nMatchMethod == CV_TM_SQDIFF_NORMED){matchLocation = minLocation;}else{matchLocation = maxLocation;}rectangle(srcImage, matchLocation, Point(matchLocation.x + g_tempalteImage.cols, matchLocation.y + g_tempalteImage.rows), Scalar(0, 0, 255), 2, 8, 0);rectangle(g_resultImage, matchLocation, Point(matchLocation.x + g_tempalteImage.cols, matchLocation.y + g_tempalteImage.rows), Scalar(0, 0, 255), 2, 8, 0);imshow("原始图", srcImage);imshow("效果图", g_resultImage);}int main()
{g_srcImage = imread("nba.jpg");if (!g_srcImage.data){cout << "原始图读取失败" << endl;return -1;}g_tempalteImage = imread("76.png");if (!g_tempalteImage.data){cout << "模板图读取失败" << endl;return -1;}namedWindow("原始图", CV_WINDOW_AUTOSIZE);namedWindow("效果图", CV_WINDOW_AUTOSIZE);createTrackbar("方法", "原始图", &g_nMatchMethod, g_nMaxTrackbarNum, on_matching);on_matching(0, NULL);waitKey(0);return 0;
}

当然也会有一些算法匹配失败的.

实验证明,该段程序效果很不错,但注意的是,模板配在原图抠出模板图的形式下准确率才比较高,不然的话可能准确度就不太高了。

那么模板匹配能在哪些项目有应用呢?我说一下我的经验。

最近我在参与实验室的一个项目,做的是发票的分类,分类的方法我首先采用的是模板匹配,也就是从一类发票中抠出一些特征区域,以此作为模板,自己设定阈值,低于阈值就是算是跟该类发票匹配了,就可以 对其进行分类。在我的测试看来,准确率还可以,不过也隐藏这一个比较大的隐患就是,一旦发票种类多了,比如100种,那么检测时间就会指数上升,这是不可取的。

OpenCV精进之路(十):直方图匹配——模板匹配相关推荐

  1. OpenCV精进之路(十六):图像分解和融合技术——图像拼接和图像融合技术

    图像拼接在实际的应用场景很广,比如无人机航拍,遥感图像等等,图像拼接是进一步做图像理解基础步骤,拼接效果的好坏直接影响接下来的工作,所以一个好的图像拼接算法非常重要. 再举一个身边的例子吧,你用你的手 ...

  2. 【OpenCV 4开发详解】图像模板匹配

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  3. 定位匹配 模板匹配 地图_什么是地图匹配?

    定位匹配 模板匹配 地图 By Marie Douriez, James Murphy, Kerrick Staley 玛丽·杜里兹(Marie Douriez),詹姆斯·墨菲(James Murph ...

  4. 【视觉项目】【day2】8.21号实验记录(手机固定高度15cm拍摄+直方图均衡化+模板匹配,模板12个,测试28个,效果十分差)

    目录 均衡化代码 模板图片按照大小排序 总代码 测试效果 新思路 由于模板匹配是像素之间的比对,所以不同光照下的像素灰度值也会不同 所以在比对之前,我们需要对测试图和模板图进行直方图均衡化,这一步可以 ...

  5. Opencv学习笔记——直方图与模板匹配

    文章目录 一.直方图 1.画直方图 2.mask的使用 3.直方图均值化 4.自适应直方图均衡化 二.模板匹配 1.匹配单个对象 2.匹配多个对象 一.直方图 直方图是像素点数值分布的统计图形表示,也 ...

  6. opencv学习笔记十八:模板匹配(cv2.matchTemplate、cv2.minMaxLoc)

    1.目标匹配函数:cv2.matchTemplate() res=cv2.matchTemplate(image, templ, method, result=None, mask=None) ima ...

  7. OpenCV(项目)车牌识别3 -- 模板匹配

    目录 一.基础理论 1.思想 2.大致过程 二.详细过程 1.首先需要模板库 2.得到模板 3.原图限定大小 4.模板匹配 5.匹配所有子文件夹,保存最佳得分(最匹配项) 三.大致过程(细分类,节省时 ...

  8. Python OpenCV 正月十五轻松点,复习一下模板匹配吧

    Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧.本篇博客是这个系列的第 49 篇. 该系列文章导航参考:https://blog.csdn.net/hihell/categ ...

  9. OpenCV精进之路(十五):特征检测和特征匹配方法汇总

    一幅图像中总存在着其独特的像素点,这些点我们可以认为就是这幅图像的特征,成为特征点.计算机视觉领域中的很重要的图像特征匹配就是一特征点为基础而进行的,所以,如何定义和找出一幅图像中的特征点就非常重要. ...

最新文章

  1. Spring Cloud 2020.0.4 发布!
  2. 迅达云成参观学习---感谢信
  3. JVM-02内存区域与内存溢出异常(中)【hotspot虚拟机对象】
  4. MySQL线程共享内存参数
  5. 使用snmp4j实现Snmp功能(三)
  6. ubuntu安装jdk,ubuntu设置java环境变量
  7. Oracle SQL语句大全(二)
  8. 图论 公约数 找环和链 BZOJ [NOI2008 假面舞会]
  9. boost::mutex::scoped_lock
  10. qq浏览器网页翻译_iOS 14中直接在Safari浏览器中翻译网页的方法!
  11. dev c++ 代码补全_zsh配置与代码自动补全+tmux配置
  12. “webservice远程测试显示 “测试窗体只能用于来自本地计算机
  13. Python数据结构1-----基本数据结构和collections系列
  14. 启动计算机管理服务,win10系统打开服务管理器的五种方法
  15. 便利蜂创始人数字化经验分享:如何用全链路数字化 重塑零售业
  16. unity 烘焙模式——baked indirect/shadow mask/distance shadowmask/subtractive模式的区别
  17. 今日微语早报 每日精选12条新闻简报
  18. foss测试_2016年十大FOSS法律案例
  19. 数据挖掘技术具有哪些特点?
  20. 2021年第十二届蓝桥杯省赛C/C++B组题解总结

热门文章

  1. 如何优雅的定义 App 的界面设计
  2. 佛祖保佑代码无bug图片_程序员都有哪些奇趣的代码注释,细思极恐
  3. mysql 维护文档_mysql数据库维护文档
  4. linux检测是否安装eclipse,肿么看linux中eclipse是否安装成功
  5. Oracle数据同步接口中,对于NUMBER、DATE类型数据,从resultSet中直接获取造成精度丢失的解决方案
  6. 升级dedecms5.5后,出现提示保存目录数据时失败,请检查你的输入资料是否存在问题...
  7. 路由协议之间的经典对比
  8. “重疾险”和“重大疾病医疗保险”的区别
  9. JavaWeb——IOC
  10. 不使用ArcObjects直接查找SDE数据库信息