- 操作系统: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...w−1,y′=0...h−1
函数完成比较后,可以使用 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) (W−w+1)×(H−h+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;
}