• 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

将一个模板与重叠的图像区域进行比较。
该函数在图像中滑动,使用指定的方法将大小为 w × h w \times h w×h的重叠块与模板 templ 进行比较,并将比较结果存储在 result 中。TemplateMatchModes 描述了可用比较方法的公式( I I I表示图像, T T T 表示模板, R R R 表示结果, M M M 表示可选的掩码)。求和是在模板和/或图像块上进行的: x ′ = 0... w − 1 , y ′ = 0... h − 1 x' = 0...w-1, y' = 0...h-1 x=0...w1,y=0...h1

函数完成比较后,可以使用 minMaxLoc 函数找到最佳匹配作为全局最小值(当使用 TM_SQDIFF 时)或最大值(当使用 TM_CCORR 或 TM_CCOEFF 时)。在彩色图像的情况下,模板在分子中的求和和分母中的每次求和都是在所有通道上进行的,并且每个通道使用单独的均值。也就是说,该函数可以接受一个彩色模板和一个彩色图像。结果仍然是一个单通道图像,这更容易分析。

OpenCV 中的 matchTemplate() 函数用于模板匹配,它可以在一幅图像中搜索另一个小图像(称为模板)的位置。该函数比较模板图像和输入图像中的所有位置,并返回一个灰度图,其中每个像素值表示模板与输入图像相应位置的匹配程度。

函数原型

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

参数

  • 参数image:正在其中进行搜索的图像。它必须是8位或32位浮点型。

  • 参数templ:被搜索的模板。它必须不大于源图像,并且具有相同的数据类型。

  • 参数result:比较结果的地图。它必须是单通道32位浮点型。如果 image 是 W × H W×H W×H,而 templ 是
    w × h w \times h w×h,那么 result 是 ( W − w + 1 ) × ( H − h + 1 ) (W-w+1) \times (H-h+1) (Ww+1)×(Hh+1)

  • 参数method:指定比较方法的参数,参见 TemplateMatchModes。

  • 参数mask:可选的掩码。它必须与 templ 具有相同的大小。它要么具有与模板相同的通道数,要么只有一个通道,后者则用于所有模板和图像通道。如果数据类型是 CV_8U,则掩码被视为二值掩码,这意味着只有掩码非零的元素被使用,并且它们的值保持不变,与实际掩码值无关(权重等于1)。对于数据类型 CV_32F,掩码值被用作权重。具体的公式在 TemplateMatchModes 中有记录。

代码示例


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

int main( int argc, char** argv )
{
    cv::Mat img   = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/qiu.jpg", cv::IMREAD_GRAYSCALE );
    cv::Mat templ = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/qiu2.png", cv::IMREAD_GRAYSCALE );

    if ( img.empty() || templ.empty() )
    {
        std::cout << "Could not open or find the images!" << std::endl;
        return -1;
    }

    // 创建结果矩阵
    cv::Mat result;
    // 使用归一化互相关匹配法
    int method = cv::TM_SQDIFF_NORMED; 
    cv::matchTemplate( img, templ, result, cv::TM_SQDIFF );

    // 查找最大最小值及其位置
    // 查找最大最小值及其位置
    double minVal, maxVal;
    cv::Point minLoc, maxLoc;
    cv::Point matchLoc;
    cv::minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat() );

    // 根据所选的方法,找到最佳匹配位置
    
    if ( cv::TM_SQDIFF == method || cv::TM_SQDIFF_NORMED == method )
    {
        matchLoc = minLoc;  // 对于平方差匹配方法,使用最小值位置
    }
    else
    {
        matchLoc = maxLoc;  // 对于其他匹配方法,使用最大值位置
    }

    // 绘制矩形框标记匹配区域
    cv::Rect matchRect( matchLoc.x, matchLoc.y, templ.cols, templ.rows );
    cv::rectangle( img, matchRect, cv::Scalar::all( 0 ), 2, 8, 0 );

    // 显示结果
    cv::imshow( "Image", img );
    cv::imshow( "Result", result );
    cv::waitKey( 0 );

    return 0;
}

运行结果

OpenCV目标检测(1)模板匹配函数matchTemplate()的使用-LMLPHP

09-25 06:02