OpenCV matchTemplate function tutorial to find matching template in source image

 In this article, I will show you how to find a template image in a bigger source image using OpenCV C++. This is a useful technique for object detection, especially template detection, as well as image processing and analysis.

opencv template finding

The main idea is to use the template matching function in OpenCV, which compares a template image with a source image and returns a similarity score for each pixel in the source image. The highest score indicates the best match location of the template image in the source image.

Template matching works by sliding the template image over the input image similarity at each location. The similarity comparison is done using a metric that measures how well the template matches the input image patch. The metric is stored in a result matrix, where each element corresponds to a location of the template over the input image. The location with the highest (or lowest) value in the result matrix is considered the best match.

The two methods that I will explain are cv::TM_CCOEFF_NORMED and cv::TM_SQDIFF_NORMED. These methods are normalized versions of cv::TM_CCOEFF and cv::TM_SQDIFF, respectively. Normalization means that the metric values are scaled to fall into the range [0, 1], where 1 indicates a perfect match and 0 indicates no match. This makes the comparison more robust to variations in illumination and contrast.

The formula for Opencv cv::TM_CCOEFF_NORMED is:

This metric calculates the correlation coefficient between the template and the input image patch, which is a measure of how linearly related they are. A high value of the metric means that the template and the input image patch have similar pixel values and variations.

The formula for Opencv cv::TM_SQDIFF_NORMED is:

This metric calculates the normalized squared difference between the template and the input image patch, which is a measure of how dissimilar they are. A low value means that the template and the input image patch have similar pixel values.

Opencv cv::matchTemplate

To use these methods in OpenCV, we can use the function cv::matchTemplate(), which takes four arguments: the input image, the template image, the result matrix, and the matching method. Optionally, we can also provide a mask image that defines which part of the template should be used for matching. For example:


To use the template matching function, we need to follow these steps:

1. Load the template image and the source image as grayscale images using cv::imread().

2. Create a result image with the same size as the source image, where we will store the similarity scores.

3. Choose a template matching method from the available options in OpenCV, such as cv::TM_CCOEFF_NORMED or cv::TM_SQDIFF_NORMED.

4. Call cv::matchTemplate() with the template image, the source image, the result image, and the chosen method as arguments.

5. Find the maximum or minimum value (depending on the method) and its location in the result image using cv::minMaxLoc().

6. Draw a rectangle around the best match location on the source image using cv::rectangle().

7. Display the source image and the result image using cv::imshow().


Example objective matchTemplate in Opencv

The following picture is our source image.

The goal is the find the template, which is the B bold icon below, 
The result of the code is to find the bold icon and draw the rectangle over it. 


Opencv C++ matchTemplate code :

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

int main()
{
// Load the template image and the source image as grayscale images
cv::Mat template_img = cv::imread("C:/blog/template.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat source_img = cv::imread("C:/blog/source.jpg", cv::IMREAD_GRAYSCALE);

// Check if the images are loaded correctly
if (template_img.empty() || source_img.empty())
{
std::cout << "Error: could not load images" << std::endl;
return -1;
}

// Create a result image with the same size as the source image
cv::Mat result_img;
result_img.create(source_img.rows - template_img.rows + 1, source_img.cols -
template_img.cols + 1, CV_32FC1);

// Choose a template matching method
int method = cv::TM_CCOEFF_NORMED;

// Perform template matching
cv::matchTemplate(source_img, template_img, result_img, method);

// Find the maximum value and its location in the result image
double max_val;
cv::Point max_loc;
cv::minMaxLoc(result_img, NULL, &max_val, NULL, &max_loc);

// Draw a rectangle around the best match location on the source image
cv::rectangle(source_img, max_loc, cv::Point(max_loc.x + template_img.cols, max_loc.y
+ template_img.rows), cv::Scalar(0, 255, 0), 2);

// Display the source image and the result image
cv::imshow("Source Image", source_img);
cv::imshow("Result Image", result_img);
cv::waitKey(0);

return 0;
}
Next Post Previous Post
No Comment
Add Comment
comment url