Using the matchTemplate function in OpenCV to implement template matching [C++ version]

matchTemplate function prototype

void cv::matchTemplate(InputArray 	image,
	InputArray 	templ,
	OutputArray 	result,
	int 	method,
	InputArray 	mask = noArray()
)
parameter meaning
image The image the search is running on. It must be an 8-bit or 32-bit floating point number.
temp Searched templates. It must be no larger than the source image and have the same data type.
result Comparison results graph. It must be a single channel 32-bit floating point number. If image is W×H and template is w×h, then the result is (W−w+1)×(H−h+1)
method Specify parameters for the comparison method, seeTemplateMatchModes
mask Mask for search templates. It must be of the same data type and size as template. Not set by default. Currently, only TM_SQDIFFthe and TM_CCOEFF_NORMEDmethods are supported.

enum cv::TemplateMatchModes enumeration

Insert image description here

Compare the template to overlapping image areas.
This function slides through the image, compares overlapping blocks of size w × h to template using the specified method, and stores the comparison in result. Here are the formulas for the available comparison methods (I represents the image, T is the template, and R is the result). The summation is done on templates and/or image patches: x′=0…w−1,y′=0…h−1 After the function completes the comparison, you can use the function to take the global minimum (when used) or
the minMaxLocmaximum TM_SQDIFFvalue (When using TM_CCORRor TM_CCOEFF) Find the best match. In the case of color images, the template sum in the numerator and each sum in the denominator are done over all channels, and a separate average is used for each channel. That is, this function can obtain a color template and a color image. The result is still a single-channel image, which is easier to analyze.

normalize function prototype

void cv::normalize(InputArray 	src,
	InputOutputArray 	dst,
	double 	alpha = 1,
	double 	beta = 0,
	int 	norm_type = NORM_L2,
	int 	dtype = -1,
	InputArray 	mask = noArray()
)
parameter meaning
src input array
dst Output array of the same size as src
alpha In the case of range normalization, the normative value or the lower bound of the range.
beta The upper bound of the range in the case of range normalization; it is not used for specification normalization.
norm_type Normalized types, see cv::NormTypes
dtype When negative, the output array is of the same type as src; otherwise, it has the same number of channels and depth =CV_MAT_DEPTH(dtype) as src.
mask Optional operation mask

The norm or value range of a normalized array.

minMaxLoc function prototype

void cv::minMaxLoc(InputArray 	src,
	double* minVal,
	double* maxVal = 0,
	Point* minLoc = 0,
	Point* maxLoc = 0,
	InputArray 	mask = noArray()
)
parameter meaning
src Single channel input array
minVal Pointer to the minimum value returned; use NULL if not required.
maxVal Pointer to the maximum value returned; use NULL if not required.
minLoc Pointer to the minimum position returned (in the 2D case); use NULL if not required.
maxLoc Pointer to the maximum position returned (in the 2D case); use NULL if not required.
mask Optional mask for selecting subarrays

Find global minimum and maximum values ​​in an array.
Function cv::minMaxLocFinds the minimum and maximum element values ​​and their positions. Search for extreme values ​​in the entire array, or in the specified array region if mask is not an empty array.
This feature does not work with multi-channel arrays. If you need to find the smallest or largest element in all channels, first use Mat::reshape to reinterpret the array into a single channel. Alternatively, you can use extractImageCOI or mixChannels or split to extract specific channels.

Mat::create function prototype

void cv::Mat::create(int rows,
	int cols,
	int type
)

This is one of Mat's key methods. Most newer OpenCV functions and methods that produce arrays call this method for each output array.

template matching routine

Refer to the official routine: samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp

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

using namespace std;
using namespace cv;

int main()
{
    
    
	string srcPath = "./lena.jpg";
	string templPath = "./lena-templ.jpg";
	Mat result;
	Mat img = imread(srcPath);
	Mat templ = imread(templPath);

	int resultCols = img.cols - templ.cols + 1; //col = W - w + 1
	int resultRows = img.rows - templ.rows + 1; //row = H - h + 1

	result.create(resultRows, resultCols, CV_32FC1);

	int method = TM_CCORR_NORMED;
	matchTemplate(img, templ, result, method);

	normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

	double minVal, maxVal;
	Point minLoc, maxLoc;
	Point matchLoc;

	cout << "result_channel: " << result.channels() << endl;

	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);

	if (method == TM_SQDIFF || method == TM_SQDIFF_NORMED) {
    
    
		matchLoc = minLoc;
	}
	else {
    
    
		matchLoc = maxLoc;
	}

	
	rectangle(img, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar(255, 0, 0), 2, 8, 0);

	imshow("match-result", img);

	waitKey(0);
	return 0;
}

Match results

Insert image description here

Guess you like

Origin blog.csdn.net/Star_ID/article/details/124609507#comments_28490325