前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【OpenCV入门之七】详细剖析模板匹配

【OpenCV入门之七】详细剖析模板匹配

作者头像
小白学视觉
发布2019-10-24 12:14:09
8890
发布2019-10-24 12:14:09
举报

小白导读

学习计算机视觉最重要的能力应该就是编程了,为了帮助小伙伴尽快入门计算机视觉,小白准备了【OpenCV入门】系列。新的一年文章的内容进行了很大的完善,主要是借鉴了更多大神的文章,希望让小伙伴更加容易理解。如果小伙伴觉得有帮助,请点击一下文末的“好看”鼓励一下小白。

模板匹配介绍

我们需要2幅图像:

原图像 (I): 在这幅图像里,我们希望找到一块和模板匹配的区域

模板 (T): 将和原图像比照的图像块

  • 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域。
  • 所以模板匹配首先需要一个模板图像T(给定的子图像)
  • 另外需要一个待检测的图像-源图像S
  • 工作方法,在带检测图像上,从左到右,从上向下计算模板图像与重叠子图像的匹配度,匹配程度越大,两者相同的可能性越大。

模板匹配原理

我们的目标是检测最匹配模板的原图像的区域:

为了确定匹配模板区域, 我们不得不滑动模板图像和原图像进行比较 :

对于 模板(T) 覆盖在 原图像 (I) 上的每个位置,你把度量值保存 到 结果图像矩阵 ( R ) 中. 在 R 中的每个位置 (x,y) 都包含匹配度量值:

上图(右)就是 TM_CCORR_NORMED 方法处理后的结果图像 R . 最白的位置代表最高的匹配. 正如您所见, 黑色框住的位置很可能是结果图像矩阵中的最大数值, 所以这个区域 (以这个点为顶点,长宽和模板图像一样大小的矩阵) 被认为是匹配的.

实际上, 我们使用函数 minMaxLoc 来定位在矩阵 R 中的最大值点 (或者最小值, 根据函数输入的匹配参数) .

代码语言:javascript
复制
void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray())
  • src:输入图像。
  • minVal:在矩阵 src中存储的最小值,可输入NULL表示不需要。
  • maxVal :在矩阵 src中存储的最大值,可输入NULL表示不需要。
  • minLoc:在结果矩阵中最小值的坐标,可输入NULL表示不需要,Point类型。
  • maxLoc:在结果矩阵中最大值的坐标,可输入NULL表示不需要,Point类型。
  • mask:可选的掩模

模板匹配介绍 – 匹配算法介绍:

OpenCV中提供了六种常见的匹配算法如下:

  • 计算平方不同 : 计算出来的值越小,越相关 TM_SQDIFF = 0
  • 计算相关性: 计算出来的值越大,越相关 TM_CCORR = 2
  • 计算相关系数: 计算出来的值越大,越相关 TM_CCOEFF = 4
  • 计算归一化平方不同 : 计算出来的值越接近0,越相关 TM_SQDIFF_NORMED = 1
  • 计算归一化相关性: 计算出来的值越接近1,越相关 TM_CCORR_NORMED = 3
  • 计算归一化相关系数: 计算出来的值越接近1,越相关 TM_CCOEFF_NORMED = 5

总结如下:

相关API介绍cv::matchTemplate

代码语言:javascript
复制
matchTemplate(
InputArray image,// 源图像,必须是8-bit或者32-bit浮点数图像
InputArray templ,// 模板图像,类型与输入图像一致
OutputArray result,// 输出结果,必须是单通道32位浮点数,假设源图像WxH,模板图像wxh, 则结果必须为W-w+1, H-h+1的大小。
int method,//使用的匹配方法
InputArray mask=noArray()//(optional)
)

程序代码

代码语言:javascript
复制
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
 
// 定义一些全局变量, 例如原图像(img), 模板图像(templ) 和结果图像(result) , 
// 还有匹配方法以及窗口名称:
Mat img, templ, result;
char* image_window = "Source Image";
char* result_window = "Result window";
 
int match_method = TM_SQDIFF;
int max_Trackbar = 5;

void MatchingMethod( int, void* );
 
int main( int argc, char** argv )
{
  // 1. 载入原图像和模板块
  img = imread("E:/Experiment/OpenCV/Pictures/TargetSearch.jpg");
  templ = imread("E:/Experiment/OpenCV/Pictures/Target.jpg");
  imshow("模板图像",templ);
 
  // 创建窗口
  namedWindow( image_window, CV_WINDOW_AUTOSIZE );
  namedWindow( result_window, CV_WINDOW_AUTOSIZE );
 
  // 2. 创建滑动条并输入将被使用的匹配方法. 一旦滑动条发生改变,回调函数 MatchingMethod 就会被调用.
  char* trackbar_label = "模板匹配方式";
  createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );
 
  MatchingMethod( 0, 0 );
 
  waitKey(0);
  return 0;
}

void MatchingMethod( int, void* )
{
  // 将被显示的原图像
  Mat img_display;
  img.copyTo( img_display );
 
  // 创建输出结果的矩阵
  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, match_method );
  normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
 
  // 通过函数 minMaxLoc 定位最匹配的位置
  double minVal, maxVal; 
  Point minLoc, maxLoc;
  Point matchLoc;
  
  //通过使用函数 minMaxLoc ,我们确定结果矩阵 R 的最大值和最小值的位置.
  minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );//寻找result中最大值,最小值,及它们所在的位置
 
  // 对于方法 SQDIFF 和 SQDIFF_NORMED, 越小的数值代表更高的匹配结果. 而对于其他方法, 数值越大匹配越好
  if( match_method  == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED ){ 
    matchLoc = minLoc; 
  }else{ 
    matchLoc = maxLoc; 
  }
 
  // 绘制矩形
  rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
  rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
 
  imshow( image_window, img_display );
  imshow( result_window, result );
 
  return;
}

运行结果

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小白学视觉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档