模板匹配(template matching)

本文介绍了模板匹配的基本原理,即通过在原图像上滑动模板并计算匹配度来寻找相似区域。讨论了如何实现匹配,并指出在使用OpenCV的matchTemplate函数时,第五种方法提供了最佳匹配效果。同时,提到了利用minMaxLoc函数来寻找全局最大匹配位置。
部署运行你感兴趣的模型镜像

原理

  • 什么是模板匹配?
    你有一副原图像,还有一小块模板(很小的图像,有可能来源于原图像),通过模板找出原图中和模板相似的位置。
  • 如何实现匹配?
    原图(I):我们需要在上面找到和模板匹配的图像
    模板(T):一小块图像,是我们需要在原图中找到和它相似的区域位置的图像
    方法:一直用模板在原图上进行移动,从左到右,从上到下,每移动一个像素,便去在模板区域内计算 “一种度量(度量)”,然后将"度量"结果存到Mat 对象中,最大值(或者最小值,根据计算方法不同)的位置,就是原图中最佳的匹配位置


代码

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

const char* src_window = "src";
const char* image_window = "ResultInSrc";
const char* pathch_window = "template";
const char* result_wimdow = "ResulIntMatch";

Mat image,temp;

int method = 0;
#define MAX_METHOD 5

void Mathching(int, void*);

int main(void)
{
    image = imread("../res/image.jpg",cv::IMREAD_COLOR);
    temp = imread("../res/template.jpg",IMREAD_COLOR);

    if(image.empty() || temp.empty())
    {
	cout << "can't load the image" << endl;
    }

    namedWindow(src_window,cv::WINDOW_AUTOSIZE);
    namedWindow(pathch_window,WINDOW_AUTOSIZE);

    const char* Trackbar_Label = "method: \n 0:SQDIFF \n 1:SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";
    createTrackbar(Trackbar_Label, src_window, &method, MAX_METHOD, Mathching); //选择匹配方法


    imshow(pathch_window, temp);
    imshow(src_window,image);
    Mathching(0,0);

    waitKey();

	return 0;
};


void Mathching(int, void*)
{
    int result_cols = image.cols-temp.cols+1;
    int result_rows = image.rows-temp.rows+1;

    Mat image_display ;  //copy原图,用来显示匹配结果
    image.copyTo(image_display);

    Mat result;
    result.create(result_rows,result_cols,CV_32FC1);

    cv::matchTemplate(image, temp, result,method); //进行匹配
    normalize(result,result,0,1,NORM_MINMAX, -1,Mat()); //归一化

    double minValue, maxValue; Point minLoc, maxLoc; Point matchLoc;
    cv::minMaxLoc(result,&minValue, &maxValue, &minLoc, &maxLoc,Mat()); //在结果中找最大和最小值 和他们位置

    if(method == cv::TM_SQDIFF || method == cv::TM_CCORR_NORMED) //这两种匹配方法,最小值才是最佳匹配
	matchLoc = minLoc;
    else
	matchLoc = maxLoc;

//将匹配在原图和结果中画出来
    cv::rectangle(image_display, matchLoc,Point(matchLoc.x+temp.cols,   matchLoc.y+temp.rows),Scalar::all(0),2,8,0);
    cv::rectangle(result, matchLoc,Point(matchLoc.x+temp.cols, matchLoc.y+temp.rows),Scalar::all(0),2,8,0);

    imshow(image_window, image_display);
    imshow(result_wimdow,result);
}

结果:

只有在第5种方法的时候才得到很好的匹配,其他都效果不好
在这里插入图片描述


OpenCV API

  1. 模板匹配,返回匹配结果(存在result中)
    void cv::matchTemplate
    (
    InputArray image,     // 输入图像,必须是8位或者32float型
    InputArray templ,    //模板,不能大于输入图像,且和它具有相同的数据类型
    OutputArray result,    // 输出结果,必须是单通道的32位float类型,输入:W × \times ×H,模板:w × \times ×h,结果: W − w + 1 , H − h + 1 W-w+1,H-h+1 Ww+1,Hh+1,每个点代表的不是模板在原图的中心,而是左上
    int method,    // 使用匹配的方法,见下面
    InputArray mask = noArray()     
    )
    在这里插入图片描述


  2. 在一副图像中找全局最大和最小值和他们的位置
    void cv::minMaxLoc
    (
    InputArray src,    // 输入的单通道的图像
    double * minVal,    // 指向最小值,如果不需要填NULL
    double * maxVal = 0,    //指向最大值如,果不需要填NULL
    Point * minLoc = 0,    //指向最小值的位置,如果不需要填NULL
    Point * maxLoc = 0,    //指向最大值的位置,如果不需要填NULL
    InputArray mask = noArray()     //掩膜,用来选择子区域
    )

您可能感兴趣的与本文相关的镜像

Yolo-v8.3

Yolo-v8.3

Yolo

YOLO(You Only Look Once)是一种流行的物体检测和图像分割模型,由华盛顿大学的Joseph Redmon 和Ali Farhadi 开发。 YOLO 于2015 年推出,因其高速和高精度而广受欢迎

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值