opencv基础--图像模板匹配

参考:https://blog.csdn.net/ivanhawking/article/details/83182692(该链接附载链接有处理多目标,旋转,缩放等匹配的方法)
1.概述
图像匹配是指图像之间的比较,得到图像之间的相似度,在机器识别的过程中把不同传感器或者同一个传感器在不同时间、不同成像条件下对同一景物获得的两幅或者多幅图像在空间上对准,或者根据已知模式到另一幅图像中寻找对应的模式。
匹配方法大体分为两类:基于灰度值的匹配,基于特征的匹配。
基于灰度值的匹配方法:原理简单且在光照良好的条件下可以得到比较满意的匹配结果。
基于特征的匹配方法:提取个图像中的特征再完成特征间的匹配,通过匹配的特征建立图像间的映射关系求出匹配图像。一般来说求取特征点相对容易,能够对图像间的分辨率、旋转、平移、光照变化保持不变,故在利用模板匹配得到抓取图像后进一步进行特征匹配。
基于特征匹配的方法有很多中如:SIFT、SURF、HARRIS、FAST、SUSAN 等。(sift最早提出鲁棒性好的尺度不变性特征描述方法,但是SIFT算法计算数据量大、时间复杂度高、算法耗时长。)
模板匹配原理
模板匹配是通过滑框在采集到的原图像上进行滑动寻找与模板图像相似的目标。模板匹配不是基于直方图的方式而是基于图像的灰度值匹配。将滑框在图像上以一定的像素步长滑动将窗口内的图像灰度矩阵与参考模板按照设定的相似度度量算法进行搜索比较。
图1模板选取
图1模板选取
图2模板匹配
图2模板匹配

如图1所示,为了利用模板匹配从源图像中得到匹配区域,从源图像选取该区域作为进行匹配的模板。模板从源图像左上角开始每次以一个像素点为单位进行移动,每到达一个位置,就会计算模板矩阵和源图像当前位置矩阵匹配的“好”“坏”程度即两个矩阵的相似程度,如图2所示。
模板滑动与源图像匹配过程中,将模板和当前模板覆盖区域的矩阵的计算结果存储在矩阵®中。R中每一个位置(x, y)都包含了匹配矩阵的计算结果。在OpenCV中提供了6种匹配度量方法。
(1).平方差匹配法CV_TM_SQDIFF
在这里插入图片描述
(2)归一化平方差匹配法CV_TM_SQDIFF_NORMED
在这里插入图片描述
(3)相关匹配法CV_TM_CCORR
在这里插入图片描述
(4)归一化相关匹配法CV_TM_CCORR_NORMED
在这里插入图片描述
(5)系数匹配法CV_TM_CCOEFF
在这里插入图片描述
其中在这里插入图片描述
(6)化相关系数匹配法CV_TMCCOEFF_NORMED
在这里插入图片描述
通常来讲,随着从简单测量方法(平方差)到更复杂的测量方法(相关系数法),我们可以获得越来越准确的匹配。然而这同时也会以越来越大的计算量为代价。对于选取何种方法,针对不同的匹配情况进行对此分析比较,选取更适合自己应用场景同时兼顾速度和精度的最佳方案。
注意
值得注意的是对于方法SQDIFF和SQDIFF_NORMED两种方式,其值越小就代表着更高的匹配结果,其余的方法数值越大则匹配效果越好。

opencv中提供的API
OpenCV中提供了matchTemplate()并配合minMaxLoc()函数实现图像的模板匹配过程。通过matchTemplate()函数根据输入模板搜寻输入图像中与模板相似的地方,获得匹配结果图像。通过minMaxLoc()函数来找到最大值和最小值.
matchTemplate

void cv::matchTemplate  (   InputArray      image,
        InputArray      templ,
        OutputArray     result,
        int     method,
        InputArray      mask = noArray() 
    )   

参数解释:
InputArray Image: 待搜索的图像,且图像必须为8-bit或32-bit的浮点型图像
InputArray templ: 用于进行模板匹配的模板图像,类型和原图像一致,但是尺寸不能大于原图像
OutputArray result: 模板搜索结果输出图像,必须为单通道32-bit位浮点型图像,如果图像尺寸是WxH而template尺寸是wxh,则此参数result一定是(W-w+1)x(H-h+1)
int method: 模板匹配计算类型,在匹配原理中已经介绍过这六种方法了,这里不再赘述
InputArray mask=noArray(): 图像匹配时用的掩膜板,必须和模板图像有相同的数据类型和尺寸

minMaxLos()

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

参数解释:
InputArray src:输入的单通道数组
*double minVal:double类型指针,返回最小值,如果没有定义返回NULL
double
maxVal:同上,返回最大值
Point
minLoc=0:Point类型的指针,在二维图像中返回最小值的位置坐标,如果没有定义返回NULL
*Point maxLoc=0: **Point同上,返回最大位置坐标
InputArray mask=noArray():可选掩膜板

4.示例代码

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

//定义全局变量
Mat srcImage, templateImage, dstImage;
const int trackbar_method_maxValue = 5;
int trackbar_method;

//定义回调函数
void method(int, void*);

int main()
{   
    srcImage=imread("src.jpg");
    templateImage=imread("template.jpg");

    //判断文件是否加载成功
    if(srcImage.empty() || templateImage.empty())
    {
        cout << "图像加载失败!" << endl;
        return -1;
    }
    else
        cout << "图像加载成功..." << endl << endl;

    namedWindow("原图像", WINDOW_AUTOSIZE);
    namedWindow("模板图像", WINDOW_AUTOSIZE);
    imshow("原图像", srcImage);
    imshow("模板图像", templateImage);

    //定义轨迹条参数
    trackbar_method=1;
    char mathodName[50];
    namedWindow("匹配图像", WINDOW_AUTOSIZE);
    sprintf(mathodName, "匹配方式%d\n 0:SQDIFF\n 1:SQDIFF_NORMED\n 2:TM_CCORR\n 3:TM_CCORR_NORMEND\n 4:TM_COEFF\n 5:TM_COEFF_NORMED", trackbar_method_maxValue);
    createTrackbar(mathodName, "匹配图像",&trackbar_method, trackbar_method_maxValue,method);
    method(trackbar_method, 0);

    waitKey(0);

    return 0;
}

void method(int, void*)
{
    Mat display;
    srcImage.copyTo(display);
    //创建输出矩阵
    int dstImage_rows=srcImage.rows-templateImage.rows + 1;
    int dstImage_cols=srcImage.cols-templateImage.cols + 1;
    dstImage.create(dstImage_rows, dstImage_cols, srcImage.type());

    matchTemplate(srcImage, templateImage, dstImage,trackbar_method);   //模板匹配
    normalize(dstImage, dstImage, 0, 1, NORM_MINMAX);       //归一化处理

    //通过minMaxLoc定位最佳匹配位置
    double minValue, maxValue;
    Point minLocation, maxLocation;
    Point matchLocation;
    minMaxLoc(dstImage, &minValue, &maxValue, &minLocation, &maxLocation, Mat());

    //对于方法SQDIFF和SQDIFF_NORMED两种方法来讲,越小的值就有着更高的匹配结果
    //而其余的方法则是数值越大匹配效果越好
    if(trackbar_method==CV_TM_SQDIFF||trackbar_method==CV_TM_SQDIFF_NORMED)
    {
        matchLocation=minLocation;
    }
    else
    {
        matchLocation=maxLocation;
    }
    rectangle(display, matchLocation, Point(matchLocation.x+templateImage.cols, matchLocation.y+templateImage.rows),Scalar(0,0,255));

    imshow("匹配图像", display);
}
OpenCV-Python提供了一系列用于图像处理和计算机视觉任务的功能,其中包括图像匹配图像匹配是指在一幅图像中寻找与目标图像相似的区域。通过OpenCV-Python,你可以使用模板匹配技术来实现图像匹配模板匹配是一种基于像素值相似度的匹配方法,它通过在输入图像中滑动一个模板图像,并计算模板与滑动窗口区域的相似度来找到最佳匹配位置。在OpenCV-Python中,你可以使用cv2.matchTemplate()函数来实现模板匹配。 下面是一个简单的图像匹配的例子代码: ```python import cv2 import numpy as np # 读取输入图像和目标图像 input_img = cv2.imread('input_img.jpg') target_img = cv2.imread('target_img.jpg') # 将输入图像和目标图像转换为灰度图像 input_gray = cv2.cvtColor(input_img, cv2.COLOR_BGR2GRAY) target_gray = cv2.cvtColor(target_img, cv2.COLOR_BGR2GRAY) # 执行模板匹配 result = cv2.matchTemplate(input_gray, target_gray, cv2.TM_CCOEFF_NORMED) # 获取最佳匹配位置 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) top_left = max_loc # 获取目标图像的宽度和高度 target_width, target_height = target_gray.shape[::-1] # 绘制矩形框标记目标图像 cv2.rectangle(input_img, top_left, (top_left + target_width, top_left + target_height), (0, 255, 0), 2) # 显示结果图像 cv2.imshow('Result', input_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在这个例子中,我们首先读取了输入图像和目标图像,并将它们转换为灰度图像。然后,我们使用cv2.matchTemplate()函数执行模板匹配,并通过获取最佳匹配位置来找到目标图像在输入图像中的位置。最后,我们使用cv2.rectangle()函数在输入图像上绘制一个矩形框来标记目标图像的位置,并显示结果图像。 请注意,这只是一个简单的图像匹配示例,你可以根据自己的需求进行更复杂的图像匹配操作,例如使用不同的匹配方法、应用阈值、使用多个目标图像等。同时,确保你已经安装了OpenCV-Python库,并准备好了输入图像和目标图像以供匹配使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值