opencv之模板匹配

模板(TTemplate Match)匹配简介

  • 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域
  • 所以模板匹配首先需要一个模板图像T(给定的子图像)
  • 另外需要一个待检测的图像-原图像S
  • 工作方法,在待检测图像上,从左到右,从上到下计算模板图像与重叠子图像的匹配度,匹配度越大,两者相同的可能性越大
  • opencv提供了六种常见的匹配算法:
    • 计算平方不同,越小越好
    • 计算相关性,越大越好
    • 计算相关系数,越大越好
    • 计算归一化平方不同,越小越好
    • 计算归一化相关性,越大越好
    • 计算归一化相关系数,越大越好

函数API

寻找最值:minMaxLoc()函数
功能:查找全局最小和最大数组元素并返回它们的值和它们的位置。

void minMaxLoc(
InputArray src, 
CV_OUT double* minVal,
CV_OUT double* maxVal=0, 
CV_OUT Point* minLoc=0,
CV_OUT Point* maxLoc=0, 
InputArray mask=noArray()
);

参数介绍

  • 参数1:InputArray类型的src,输入单通道数组(图像)。
  • 参数2:double类型的minVal*,返回最小值的指针。若无须返回,此值置为NULL。
  • 参数3:double类型的maxVal*,返回最大值的指针。若无须返回,此值置为NULL。
  • 参数4:Point类型的minLoc*,返回最小位置的指针(二维情况下)。- 若无须返回,此值置为NULL。
  • 参数5:Point类型的maxLoc*,返回最大位置的指针(二维情况下)。若无须返回,此值置为NULL。
  • 参数6:InputArray类型的mask,用于选择子阵列的可选掩膜。

图像匹配函数API

void cv::matchTemplate(
InputArray image, // 用于搜索的输入图像, 8U 或 32F, 大小 W-H
InputArray templ, // 用于匹配的模板,和image类型相同, 大小 w-h
OutputArray result, // 匹配结果图像, 类型 32F, 大小 (W-w+1)-(H-h+1)
int method // 用于比较的方法
	);

参数介绍

  • 第一个参数是源图像
  • 第二个参数是模板图像
  • 第三个参数是匹配的结果图像,输出结果,必须是单通道32位浮点数,假设源图像WxH,模板图像wxh,则结果必须为W-w+1, H-h+1的大小
  • 第四个参数是用于指定比较的方法六种:
名称
平方不同TM_SQDIFF=0
归一化平方不同TM_SQDIFF_NORMED=1
相关性TM_CCORR=2
归一化相关性TM_CCORR_NORMED=3
相关系数TM_CCOEFF=4
归一化相关系数TM_CCOEFF_NORMED=5

## 代码演示

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

#define Pic_Path "/home/image/Pictures/my_picture/"
#define Pic_Name "model_1.jpeg"
#define Pic_Name1 "model_1_mouse.jpeg"

int type=0;
cv::Mat src,sub;
void Match_Demo(int ,void *);
int main(void)
{
    string pic = string(Pic_Path) + string(Pic_Name);
    cout << pic << endl;

    string pic1 = string(Pic_Path) + string(Pic_Name1);
    cout << pic1 << endl;
    //读取原始图片
    src      = cv::imread(pic.c_str());
    sub      = cv::imread(pic1.c_str());
    
    
    //判断图像是否存在
    if( src.empty() || sub.empty())
    {
        cout << "图片不存在" << endl;
        return -1;
    }

    //显示原始图像也就是检测图像
    cv::namedWindow("原始图片",cv::WINDOW_AUTOSIZE);
    cv::imshow("原始图片",src);
   
    //显示模板图像
    cv::namedWindow("子图片",cv::WINDOW_AUTOSIZE);
    cv::imshow("子图片",sub);

    //创建滑动条用来切换匹配方法
    cv::createTrackbar("方法","原始图片",&type,5,Match_Demo);
    Match_Demo(0,0);   //调用回调函数一次  否则程序运行不调整滑动条匹配图片将不显示
    
    cv::waitKey(0);
    cv::destroyAllWindows();

}

void Match_Demo(int ,void *)
{
    int width = src.cols - sub.cols + 1;
    int height= src.rows - sub.rows + 1;
    //目标图像大小
    Mat match_result(width,height,CV_32FC1);

    //图像匹配
    cv::matchTemplate(src,sub,match_result,type);
    
    //得出的匹配图像进行归一化处理
    cv::normalize(match_result,match_result,0,1,cv::NORM_MINMAX,-1,Mat());

    //查找位置
    double min,max;
    Point minLoc,maxLoc;
    Point tmpLoc;

    minMaxLoc(match_result,&min,&max,&minLoc,&maxLoc,Mat());

    if(type == TM_SQDIFF || type == TM_SQDIFF_NORMED)  //平方不同越小越好
    {
        tmpLoc = minLoc;
    } else    //相关因子  相关性 越大越好
    {
        tmpLoc = maxLoc;
    }
    Mat result; 
    
    //复制原图用来在原图显示检测位置
    src.copyTo(result);
    
    //在匹配图上绘制检测位置
    cv::rectangle(match_result,Rect(tmpLoc.x,tmpLoc.y,sub.cols,sub.rows),Scalar(0,0,255),2,LINE_8,0);
    cv::imshow("匹配结果",match_result);
    
    //在原图上绘制检测位置
    cv::rectangle(result,Rect(tmpLoc.x,tmpLoc.y,sub.cols,sub.rows),Scalar(0,0,255),2,LINE_8,0);
    cv::imshow("原图匹配结果",result);

    return;
}

程序运行结果

待检测图像与模板图像
在这里插入图片描述
检测结果
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值