OpenCV数字图像处理实战二:模板匹配(C++)

这篇具有很好参考价值的文章主要介绍了OpenCV数字图像处理实战二:模板匹配(C++)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

OpenCV数字图像处理实战二:模板匹配(C++)

1、模板匹配原理

模板匹配(TemplateMatching)就是在一幅图像中寻找和模板图像(template)最相似的区域,模板匹配不是基于直方图的,而是通过在输入图像上滑动图像块(模板)同时对比相似度,来对模板和输入图像进行匹配的一种方法。该方法原理简单计算速度快,能够应用于目标识别,目标跟踪等多个领域。

2、具体步骤

(1)首先需要一个模板图像 T(子图像)和一个待检测的图像(源图像 S)

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

(2)在待检测图像从左到右,从上到下计算模板图像与重叠子图像的匹配度,匹配度越高,两者相同的可能性越大。

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

优点: 原理简单计算速度快
缺点:模板图像尺寸和待检测图像尺寸问题。模板尺寸必须小于待检测图片尺寸

3、OpenCV模板匹配实现

3.1 单模板匹配

int main()
{
    Mat temp = imread("E:\\img\\T2.jpg");
    Mat src = imread("E:\\img\\S.jpg");
    Mat dst = src.clone();
    imshow("temp", temp);
	//1.构建结果图像resultImg(注意大小和类型)
    //如果原图(待搜索图像)尺寸为W x H, 而模版尺寸为 w x h, 则结果图像尺寸一定是(W-w+1)x(H-h+1)
    //结果图像必须为单通道32位浮点型图像
    int width = src.cols - temp.cols + 1;//result宽度
    int height = src.rows - temp.rows + 1;//result高度
    Mat result(height, width, CV_32FC1);//创建结果映射图像
    //2.模版匹配
    //这里我们使用的匹配算法是标准平方差匹配 method=TM_SQDIFF_NORMED,数值越小匹配度越好
    //matchTemplate(src, temp, result, TM_SQDIFF); //平方差匹配法(最好匹配0)
    matchTemplate(src, temp, result, TM_SQDIFF_NORMED); //归一化平方差匹配法(最好匹配0)
    //matchTemplate(src, temp, result, TM_CCORR); //相关匹配法(最坏匹配0)
    //matchTemplate(src, temp, result, TM_CCORR_NORMED); //归一化相关匹配法(最坏匹配0)
    //matchTemplate(src, temp, result, TM_CCOEFF); //系数匹配法(最好匹配1)
    //matchTemplate(src, temp, result, TM_CCOEFF_NORMED);//化相关系数匹配,最佳值1
    imshow("result", result);
    //3.正则化(归一化到0-1)
    normalize(result, result, 0, 1, NORM_MINMAX, -1);//归一化到0-1范围
    //4.找出result中的最大值及其位置
    double minValue, maxValue;
    Point minLoc, maxLoc;
    // 定位极值的函数
    minMaxLoc(result, &minValue, &maxValue, &minLoc, &maxLoc);
    cout << "minValue=" << minValue << endl;
    cout << "maxValue=" << maxValue << endl;
	//5.根据result中的最大值位置在源图上画出矩形和中心点
    rectangle(dst, maxLoc, Point(maxLoc.x + temp.cols, maxLoc.y + temp.rows), Scalar(0, 255, 0), 2, 8);
    imshow("dst", dst);

    waitKey(0);
    return 0;
}

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

注意:result的长宽正好是(原图-模板图)的长宽,result图中白亮程度表示匹配程度

模板匹配函数cv::MatchTemplate一次计算模板与待测图像的相似度,并将结果存入映
图像result中,也就是result图像中的每一个点的值代表一次相似度比较结果;其中,模通过在待检测的图像上从左到右,从上到下滑动,每到达一个像素点,就会以这个像素点左上角顶点从原图像中截取一个与模板大小一样的图像进行像素比较的运算,模板在滑动过程中,将模板和当前截取的图像的比较计算结果储存在result矩阵中,result的大小为(W-w+1,H-h+1),在result中的每个位置(x,y)的值都表示以这个点为左上角顶点截取的图像模板像素计算后的计算结果;模板在待测图像上每次在横向或者纵向上每次移动一个像素点然后进行一次比较,所以横向比较W-w+1次,纵向比较H-h+1次,最终得到一个(W-w+1)x(H-h+1)的result矩阵。
ROI区域的获取
从result中提取最大值(相似度最高)以及最大值的位置(即在result中该最大值max_val的坐标位置max_loc,即模板滑行时左上角的坐标,类似于图中的坐标(x,y);由此得到rect=cvRect(max_loc.x,max_loc.y,tmp->width,tmp->height); 其中rect表示最佳的匹配的矩形区域。

3.2 多目标模板匹配一

 //  1.读入图片
    Mat srcImg = imread("E://img//S1.png");
    Mat templateImg = imread("E://img//T3.jpg");
    Mat resultImg;
    Mat showImg = srcImg.clone();
    //  设置result图片的大小
    int resultImg_cols = srcImg.cols - templateImg.cols + 1;
    int resultImg_rows = srcImg.rows - templateImg.rows + 1;

    resultImg.create(resultImg_cols, resultImg_rows, CV_32FC1);
    //  2.模板匹配
    matchTemplate(srcImg, templateImg, resultImg, TM_CCOEFF_NORMED); //化相关系数匹配法(最好匹配1)
    //  3.归一化
    normalize(resultImg, resultImg, 0, 1, NORM_MINMAX);
    Mat midImg = resultImg.clone();

    //多目标模板匹配---方法一
    double matchValue;
    int count0=0;
    int tempW=0, tempH=0;
    char matchRate[10];

    for(int i=0; i<resultImg_rows; i++)
    {
        for(int j=0; j<resultImg_cols; j++)
        {
            matchValue = resultImg.at<float>(i, j);
            sprintf_s(matchRate, "%0.2f", matchValue);
            if(matchValue>=0.85 && (abs(j - tempW)>5) && (abs(i - tempH)>5) )
            {
                count0++;
                //将文字显示在图片上
                putText(showImg, matchRate, Point(j-5, i-5), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 1);
                rectangle(showImg, Point(j, i), Point(j + templateImg.cols, i + templateImg.rows), Scalar(0, 255, 0), 2);
                tempW = j;
                tempH = i;
            }
        }
    }
    cout<<"count="<<count0<<endl;
    imshow("resultImg", resultImg);
    imshow("dst", showImg);

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

3.3 多目标模板匹配二

//多目标模板匹配---方法二
    double minValue, maxValue;
    Point minLoc, maxLoc;
    Point matchLoc;
    char matchRate[10];

    for (int i = 0; i < 100; i++)
    {
        int startX = maxLoc.x - 4;
        int startY = maxLoc.y - 4;
        int endX = maxLoc.x + 4;
        int endY = maxLoc.y + 4;
        if (startX < 0 || startY < 0)
        {
            startX = 0;
            startY = 0;
        }
        if (endX > resultImg.cols - 1 || endY > resultImg.rows - 1)
        {
            endX = resultImg.cols - 1;
            endY = resultImg.rows - 1;
        }
        Mat temp = Mat::zeros(endX - startX, endY - startY, CV_32FC1);
        //Mat ROI = resultImg(Rect(Point(startX, startY), temp.cols, temp.rows));
        temp.copyTo(resultImg(Rect(startX, startY, temp.cols, temp.rows)));
        minMaxLoc(resultImg, &minValue, &maxValue, &minLoc, &maxLoc);
        if (maxValue < 0.89)    break;

        cout << "max_value= " << maxValue << endl;
        sprintf_s(matchRate, "%0.2f", maxValue);
        putText(showImg, matchRate, Point(maxLoc.x - 5, maxLoc.y - 5), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255), 1);
        rectangle(showImg, maxLoc, Point(maxLoc.x + templateImg.cols, maxLoc.y + templateImg.rows), Scalar(0, 255, 0), 2);

    }
    imshow("midImg", midImg);
    imshow("resultImg", resultImg);
    imshow("dst", showImg);

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

模板匹配 --- matchTemplate()
CV_EXPORTS_W void matchTemplate(
InputArray image, 
InputArray temp1, 
OutputArray result, 
int method);
image:待搜索图像(大图)
temp1:搜索模板,需和原图一样数据类型且尺寸大小不能大于源图像
reuslt:比较结果的映射图像,其必须为单通道的,32位浮点型图像,如果原图(待搜索图像)尺寸为W*H,二temp1的尺寸为w*h,则result的尺寸一定是(W-w+1)*(H-h+1)
method:指定的匹配方法,有如下六种:

(1)平方差匹配 method=TM_SQDIFF

这类方法利用平方差来进行匹配,最好匹配为0。匹配越差,匹配值越大。

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

(2)标准平方差匹配 method=TM_SQDIFF_NORMED

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

(3)相关匹配 method=TM_CCORR

这类方法采用模板和图像间的乘法操作,所以较大的数表示匹配程度较高,0标识最坏的匹配效果。

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

(4)标准相关匹配 method=TM_CCORR_NORMED

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

(5)相关匹配 method=TM_CCOEFF

这类方法将模版对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,-1表示匹配很差,0表示没有任何相关性(随机序列)。

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

(6)标准相关匹配 method=TM_CCOEFF_NORMED

c++ opencv 模板匹配,opencv,opencv,计算机视觉,c++

矩阵归一化 --- normalize()	函数的作用是进行矩阵归一化。
void normalize(
    InputArray src,
    OutputArray dst, 
    double alpha=1, 
    double beta=0, 
    int norm_type=NORM_L2, 
    int dtype=-1, 
    InputArray mask=noArray() )
src:输入源图像,Mat类型
dst:输出结果图像,需要和原图一样的尺寸和类型
alpha:归一化后的最小值,默认为1
beta:归一化后的最大值,默认为0
norm_type:归一化类型,可选:NORM_INF, NORM_L1, NORM_L2(默认)等
dtype:默认值为-1,此参数为负值时,输出矩阵和src有同样的类型
mask:可选的掩码操作
寻找最值 --- minMaxLoc()	函数的作用是在数组中找到全局最小值和最大值
CV_EXPORTS_W 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());
src:输入源图像,单通道图像
minVal:返回最小值的指针,若无需返回,则置为0
maxVal:返回最大值的指针,若无需返回,则置为0
minLoc:返回最小位置的指针,若无需返回,则置为0
maxLoc:返回最大位置的指针,若无需返回,则置为0
mask:可选的掩码操作

部分参考来自22、【opencv入门】模板匹配 - 阿牧路泽 - 博客园 (cnblogs.com)文章来源地址https://www.toymoban.com/news/detail-611351.html

到了这里,关于OpenCV数字图像处理实战二:模板匹配(C++)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python数字图像处理基础(九)——特征匹配

    蛮力匹配(ORB匹配) Brute-Force匹配非常简单,首先在第一幅图像中选取一个关键点然后依次与第二幅图像的每个关键点进行(描述符)距离测试,最后返回距离最近的关键点. 对于BF匹配器,首先我们必须使用**cv2.BFMatcher()**创建 BFMatcher 对象。它需要两个可选的参数: normTyp

    2024年01月19日
    浏览(49)
  • OpenCV(图像处理)-基于Python-特征检测-特征点匹配

    图像特征就是指有意义的图像区域,具有独特性,易于识别性,比如角点、斑点以及高密度区。而为什么角点具有重要的特征呢? 看下图: 观察ABD三张图片,我们不容易得知图像的位置,而CEF三张图我们特别容易找到它们在原图中对应的位置,这是因为ABD比较平滑,我们不

    2024年02月03日
    浏览(47)
  • 《数字图像处理-OpenCV/Python》连载:形态学图像处理

    本书京东 优惠购书链接 https://item.jd.com/14098452.html 本书CSDN 独家连载专栏 https://blog.csdn.net/youcans/category_12418787.html 形态学图像处理是基于形状的图像处理,基本思想是利用各种形状的结构元进行形态学运算,从图像中提取表达和描绘区域形状的结构信息。形态学运算的数学原

    2024年02月19日
    浏览(74)
  • OpenCV数字图像处理基于C++:图像分割

    图像阈值化分割是一种常用的、传统的图像分割技术,因其 实现简单、计算量小、性能比较稳定 而成为图像分割中基本和应用广泛的分割技术。特别 适合于目标和背景占据不同灰度级范围的图像 。不仅 可以极大地压缩数据量 ,而且大大 简化了分析和处理的步骤 ,是进行

    2024年02月11日
    浏览(62)
  • OpenCV数字图像处理详细教程

    1.编写程序,将自选图像(如图 1)和 OpenCV 的 Logo 图像叠加现实,其中 Logo 图像做背景透明处理。(提示:OpenCV 的 Logo 图像背景是白色的)   实现代码及注释讲解 结果展示   编写程序,使用 cv2.warpAffine()函数使一幅图像放大为原来的二倍后,以图像中 心为原点,顺时针旋

    2024年04月17日
    浏览(44)
  • 《数字图像处理-OpenCV/Python》连载(41)图像的旋转

    本书京东优惠购书链接:https://item.jd.com/14098452.html 本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html 几何变换分为等距变换、相似变换、仿射变换和投影变换,是指对图像的位置、大小、形状和投影进行变换,将图像从原始平面投影到新的视平面。OpenCV图像的几

    2024年02月05日
    浏览(53)
  • 《数字图像处理-OpenCV/Python》连载(44)图像的投影变换

    本书京东优惠购书链接:https://item.jd.com/14098452.html 本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html 几何变换分为等距变换、相似变换、仿射变换和投影变换,是指对图像的位置、大小、形状和投影进行变换,将图像从原始平面投影到新的视平面。OpenCV图像的几

    2024年02月04日
    浏览(69)
  • 轻松入门数字图像处理,搞定OpenCV编程!

    在刚开始学习数字图像处理时,你是否也有这样的困扰: 教材的开篇介绍绪论和数学工具,看得似懂非懂,似乎还不涉及编程…… 接下来学习灰度变换、空间滤波和频域滤波,涉及内容丰富、方法繁多,试着编了几个程序就编不下去了…… 开始学习OpenCV,找了几本参考书,

    2024年02月09日
    浏览(47)
  • 《数字图像处理-OpenCV/Python》连载(4)图像的读取与保存

    本书京东优惠购书链接:https://item.jd.com/14098452.html 本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html 为了方便初学者从零开始学习OpenCV-Python,本书从图像的读取、保存和显示等基本操作开始介绍,使读者可以循序渐进地使用和理解本书的每一个例程。 本章内容

    2024年02月09日
    浏览(57)
  • 《数字图像处理-OpenCV/Python》连载(10)图像属性与数据类型

    本书京东优惠购书链接:https://item.jd.com/14098452.html 本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html 在Python语言中,OpenCV以Numpy数组存储图像,对图像的访问和处理都是通过Numpy数组的操作来实现的。 本章内容概要 介绍Python语言中OpenCV的数据结构,学习获取图像

    2024年02月07日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包