Template Matching is a technique in image processing to find a smaller image (template) within a larger image. OpenCV provides robust functionality to perform template matching using different methods.
What You’ll Learn
1. Introduction to Template Matching
Template Matching involves sliding the template image over the larger image and comparing regions using a similarity metric. OpenCV’s cv2.matchTemplate() is the core function for this task.
Syntax
result = cv2.matchTemplate(image, template, method)
- image: The larger source image.
- template: The smaller template image.
- method: Matching method (e.g., cv2.TM_CCOEFF, cv2.TM_SQDIFF).
2. Basic Template Matching
Example: Single Template Matching
import cv2 # Load the main image and template image = cv2.imread("source.jpg") template = cv2.imread("template.jpg") # Perform template matching result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED) # Get the location of the best match min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) # Draw a rectangle around the matched region h, w, _ = template.shape top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) cv2.rectangle(image, top_left, bottom_right, (0, 255, 0), 2) # Display the result cv2.imshow("Matched Image", image) cv2.waitKey(0) cv2.destroyAllWindows()
3. Visualizing Matching Results
The result of cv2.matchTemplate is a grayscale image representing similarity. Peaks (or troughs) indicate potential matches.
Example: Display Matching Results
import cv2 import matplotlib.pyplot as plt # Load the main image and template image = cv2.imread("source.jpg", cv2.IMREAD_GRAYSCALE) template = cv2.imread("template.jpg", cv2.IMREAD_GRAYSCALE) # Perform template matching result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED) # Display the result plt.imshow(result, cmap="gray") plt.title("Matching Result") plt.colorbar() plt.show()
4. Matching Using Different Methods
OpenCV supports multiple matching methods:
- cv2.TM_CCOEFF: Correlation coefficient (higher is better).
- cv2.TM_CCOEFF_NORMED: Normalized correlation coefficient.
- cv2.TM_CCORR: Cross-correlation.
- cv2.TM_CCORR_NORMED: Normalized cross-correlation.
- cv2.TM_SQDIFF: Squared difference (lower is better).
- cv2.TM_SQDIFF_NORMED: Normalized squared difference.
Example: Compare Matching Methods
import cv2 import matplotlib.pyplot as plt # Load the main image and template image = cv2.imread("source.jpg", cv2.IMREAD_GRAYSCALE) template = cv2.imread("template.jpg", cv2.IMREAD_GRAYSCALE) methods = [ cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED, cv2.TM_CCORR, cv2.TM_CCORR_NORMED, cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED ] for method in methods: result = cv2.matchTemplate(image, template, method) plt.imshow(result, cmap="gray") plt.title(f"Method: {method}") plt.colorbar() plt.show()
5. Handling Multiple Matches
Example: Find All Matches Above a Threshold
import cv2 import numpy as np # Load the main image and template image = cv2.imread("source.jpg") template = cv2.imread("template.jpg") # Perform template matching result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED) # Define a threshold threshold = 0.8 locations = np.where(result >= threshold) # Draw rectangles around all matches h, w, _ = template.shape for pt in zip(*locations[::-1]): bottom_right = (pt[0] + w, pt[1] + h) cv2.rectangle(image, pt, bottom_right, (0, 255, 0), 2) # Display the result cv2.imshow("Detected Matches", image) cv2.waitKey(0) cv2.destroyAllWindows()
6. Practical Examples
6.1 Template Matching in Real-Time Video
import cv2 # Load the template template = cv2.imread("template.jpg", cv2.IMREAD_GRAYSCALE) h, w = template.shape # Open the video capture video = cv2.VideoCapture(0) while True: ret, frame = video.read() if not ret: break # Convert frame to grayscale gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Perform template matching result = cv2.matchTemplate(gray_frame, template, cv2.TM_CCOEFF_NORMED) # Get the best match _, max_val, _, max_loc = cv2.minMaxLoc(result) # Draw a rectangle if match is above a threshold if max_val > 0.8: top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) cv2.rectangle(frame, top_left, bottom_right, (0, 255, 0), 2) # Display the frame cv2.imshow("Video Template Matching", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break video.release() cv2.destroyAllWindows()
6.2 Template Matching with Mask
You can use a mask to ignore specific regions in the template during matching.
import cv2 # Load images image = cv2.imread("source.jpg") template = cv2.imread("template.jpg") mask = cv2.imread("mask.jpg", cv2.IMREAD_GRAYSCALE) # Perform template matching with a mask result = cv2.matchTemplate(image, template, cv2.TM_CCORR_NORMED, mask=mask) # Find the best match _, _, _, max_loc = cv2.minMaxLoc(result) h, w, _ = template.shape cv2.rectangle(image, max_loc, (max_loc[0] + w, max_loc[1] + h), (0, 255, 0), 2) # Display the result cv2.imshow("Matched Image with Mask", image) cv2.waitKey(0) cv2.destroyAllWindows()
6.3 Match Template Across Scaled Versions
For images where the template might appear at different scales, you can resize the template dynamically.
import cv2 # Load the images image = cv2.imread("source.jpg", cv2.IMREAD_GRAYSCALE) template = cv2.imread("template.jpg", cv2.IMREAD_GRAYSCALE) best_match = None best_value = -1 h, w = template.shape for scale in np.linspace(0.5, 1.5, 10): # Scale from 50% to 150% resized_template = cv2.resize(template, (int(w * scale), int(h * scale))) result = cv2.matchTemplate(image, resized_template, cv2.TM_CCOEFF_NORMED) _, max_val, _, max_loc = cv2.minMaxLoc(result) if max_val > best_value: best_value = max_val best_match = (max_loc, resized_template.shape) if best_match: top_left = best_match[0] h, w = best_match[1] bottom_right = (top_left[0] + w, top_left[1] + h) cv2.rectangle(image, top_left, bottom_right, (0, 255, 0), 2) cv2.imshow("Best Match", image) cv2.waitKey(0) cv2.destroyAllWindows()
7. Summary
Key Functions
- cv2.matchTemplate(): Perform template matching.
- cv2.minMaxLoc(): Find the best or worst match locations.
- np.where(): Find multiple matches above a threshold.
Best Practices
- Normalize images and templates for better results.
- Use different matching methods for specific tasks.
- Handle scaling and rotation for templates that might appear in different forms.
By mastering these techniques, you can effectively locate and identify patterns in images using OpenCV’s template matching capabilities!