模式匹配。。。openCV

本文详细介绍了模板匹配的基本原理及其实现过程,并通过一个具体的OpenCV实现案例展示了六种不同的匹配方法及其效果。

参考http://www.cnblogs.com/xrwang/archive/2010/02/05/MatchTemplate.html和"learning openCV"


   

模板匹配的工作方式
    模板匹配的工作方式跟直方图的反向投影基本一样,大致过程是这样的:通过在输入图像上滑动图像块对实际的图像块和输入图像进行匹配。
    假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
  (1)从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像;
  (2)用临时图像和模板图像进行对比,对比结果记为c;
  (3)对比结果c,就是结果图像(0,0)处的像素值;
  (4)切割输入图像从(0,1)至(10,11)的临时图像,对比,并记录到结果图像;
  (5)重复(1)~(4)步直到输入图像的右下角。
    大家可以看到,直方图反向投影对比的是直方图,而模板匹配对比的是图像的像素值;模板匹配比直方图反向投影速度要快一些,但是我个人认为直方图反向投影的鲁棒性会更好。

 

模板匹配的匹配方式
    在OpenCv和EmguCv中支持以下6种对比方式:
    CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。
    CV_TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。
    CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
    CV_TM_SQDIFF_NORMED 归一化平方差匹配法
    CV_TM_CCORR_NORMED 归一化相关匹配法
    CV_TM_CCOEFF_NORMED 归一化相关系数匹配法

[code]#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <stdio.h>

int main( int argc, char** argv ) {
    IplImage *src, *templ,*ftmp[6]; //ftmp will hold results
    int i;
    if( argc == 3){
        //Read in the source image to be searched:
        if((src=cvLoadImage(argv[1], 1))== 0) {
            printf("Error on reading src image %s/n",argv[i]);
            return(-1);
        }
        //Read in the template to be used for matching:
        if((templ=cvLoadImage(argv[2], 1))== 0) {
            printf("Error on reading template %s/n",argv[2]);
                return(-1);
        }
        //ALLOCATE OUTPUT IMAGES:
        int iwidth = src->width - templ->width + 1;
        int iheight = src->height - templ->height + 1;
        for(i=0; i<6; ++i){
            ftmp[i] = cvCreateImage(
                              cvSize(iwidth,iheight),32,1);
        }
        //DO THE MATCHING OF THE TEMPLATE WITH THE IMAGE:
        for(i=0; i<6; ++i){
            cvMatchTemplate( src, templ, ftmp[i], i);
            cvNormalize(ftmp[i],ftmp[i],1,0,CV_MINMAX);
        }
        //DISPLAY
        cvNamedWindow( "Template", 0 );
        cvShowImage(   "Template", templ );
        cvNamedWindow( "Image", 0 );
        cvShowImage(   "Image", src );
        cvShowImage(   "SQDIFF", ftmp[0] );
        cvNamedWindow( "SQDIFF_NORMED", 0 );
        cvShowImage(   "SQDIFF_NORMED", ftmp[1] );
        cvNamedWindow( "CCORR", 0 );
        cvShowImage(   "CCORR", ftmp[2] );
        cvNamedWindow( "CCORR_NORMED", 0 );
        cvShowImage(   "CCORR_NORMED", ftmp[3] );
        cvNamedWindow( "CCOEFF", 0 );
        cvShowImage(   "CCOEFF", ftmp[4] );
        cvNamedWindow( "CCOEFF_NORMED", 0 );
        cvShowImage(   "CCOEFF_NORMED", ftmp[5] );
        //LET USER VIEW RESULTS:
        cvWaitKey(0);
    }
    else { printf("Call should be: "
                   "match Template image template /n");}
}
[/code]

 

测试结果:

模式匹配。。。openCV

### OpenCV 中模板匹配的功能及用法 #### 模板匹配简介 模板匹配是一种在目标图像中寻找与给定模板最相似区域的技术。它广泛应用于对象检测、字符识别等领域。OpenCV 提供了多种模板匹配算法,允许开发者根据具体应用场景选择合适的匹配方法。 #### 基本原理 模板匹配的核心在于计算模板图像与目标图像之间的相似度。OpenCV 支持六种主要的匹配方法,每种方法适用于不同场景[^2]: - **cv2.TM_SQDIFF**: 平方差匹配法,最小值表示最佳匹配。 - **cv2.TM_CCORR_NORMED**: 归一化互相关匹配法,最大值表示最佳匹配。 - **cv2.TM_CCOEFF_NORMED**: 归一化相关系数匹配法,最大值表示最佳匹配。 - **cv2.TM_SQDIFF_NORMED**: 归一化的平方差匹配法,最小值表示最佳匹配。 - **cv2.TM_CCORR**: 非归一化互相关匹配法,最大值表示最佳匹配。 - **cv2.TM_CCOEFF**: 非归一化相关系数匹配法,最大值表示最佳匹配。 #### 示例代码 以下是使用 OpenCV 进行模板匹配的一个简单示例代码,展示如何定位一幅大图中的子图案位置: ```cpp #include <opencv2/opencv.hpp> #include <iostream> int main() { // 加载原始图像和模板图像 cv::Mat img = cv::imread("source_image.png"); cv::Mat templ = cv::imread("template_image.png"); if (img.empty() || templ.empty()) { std::cout << "Could not open or find the images!" << std::endl; return -1; } // 创建结果矩阵 cv::Mat result; int match_method = cv::TM_CCOEFF_NORMED; // 选择匹配方法 int result_cols = img.cols - templ.cols + 1; int result_rows = img.rows - templ.rows + 1; // 执行模板匹配 result.create(result_rows, result_cols, CV_32FC1); cv::matchTemplate(img, templ, result, match_method); // 寻找匹配的最大值或最小值 double minVal, maxVal; cv::Point minLoc, maxLoc; cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat()); // 对于 TM_SQDIFF 和 TM_SQDIFF_NORMED 方法,取最小值作为最佳匹配点 cv::Point top_left = (match_method == cv::TM_SQDIFF || match_method == cv::TM_SQDIFF_NORMED) ? minLoc : maxLoc; // 计算矩形框右下角坐标 cv::Point bottom_right(top_left.x + templ.cols, top_left.y + templ.rows); // 在原图上绘制矩形框 cv::rectangle(img, top_left, bottom_right, cv::Scalar(0, 255, 0), 2); // 显示结果 cv::imshow("Result", img); cv::waitKey(0); return 0; } ``` 此代码展示了如何加载两张图片并执行模板匹配操作,最终在源图像中标记出找到的最佳匹配区域[^1]。 #### 多尺度模板匹配 对于需要跨缩放比例进行匹配的情况,可以通过构建图像金字塔实现多尺度匹配。这种方法能够有效提升匹配精度,但也增加了计算复杂度。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值