1
1
Template Matching {#tutorial_template_matching}
2
2
=================
3
3
4
+ @prev_tutorial{tutorial_back_projection}
5
+ @next_tutorial{tutorial_find_contours}
6
+
4
7
Goal
5
8
----
6
9
7
10
In this tutorial you will learn how to:
8
11
9
- - Use the OpenCV function @ ref cv:: matchTemplate to search for matches between an image patch and
12
+ - Use the OpenCV function ** matchTemplate() ** to search for matches between an image patch and
10
13
an input image
11
- - Use the OpenCV function @ ref cv:: minMaxLoc to find the maximum and minimum values (as well as
14
+ - Use the OpenCV function ** minMaxLoc() ** to find the maximum and minimum values (as well as
12
15
their positions) in a given array.
13
16
14
17
Theory
@@ -42,7 +45,7 @@ that should be used to find the match.
42
45
- By ** sliding** , we mean moving the patch one pixel at a time (left to right, up to down). At
43
46
each location, a metric is calculated so it represents how "good" or "bad" the match at that
44
47
location is (or how similar the patch is to that particular area of the source image).
45
- - For each location of ** T** over ** I** , you * store* the metric in the * result matrix* ** (R) ** .
48
+ - For each location of ** T** over ** I** , you * store* the metric in the * result matrix* ** R ** .
46
49
Each location \f$(x,y)\f$ in ** R** contains the match metric:
47
50
48
51
![ ] ( images/Template_Matching_Template_Theory_Result.jpg )
@@ -51,9 +54,8 @@ that should be used to find the match.
51
54
The brightest locations indicate the highest matches. As you can see, the location marked by the
52
55
red circle is probably the one with the highest value, so that location (the rectangle formed by
53
56
that point as a corner and width and height equal to the patch image) is considered the match.
54
-
55
- - In practice, we use the function @ref cv::minMaxLoc to locate the highest value (or lower,
56
- depending of the type of matching method) in the * R* matrix.
57
+ - In practice, we locate the highest value (or lower, depending of the type of matching method) in
58
+ the * R* matrix, using the function ** minMaxLoc()**
57
59
58
60
### How does the mask work?
59
61
- If masking is needed for the match, three components are required:
@@ -81,7 +83,7 @@ that should be used to find the match.
81
83
82
84
### Which are the matching methods available in OpenCV?
83
85
84
- Good question. OpenCV implements Template matching in the function @ ref cv:: matchTemplate . The
86
+ Good question. OpenCV implements Template matching in the function ** matchTemplate() ** . The
85
87
available methods are 6:
86
88
87
89
-# ** method=CV_TM_SQDIFF**
@@ -117,119 +119,176 @@ Code
117
119
118
120
- ** What does this program do?**
119
121
- Loads an input image, an image patch (* template* ), and optionally a mask
120
- - Perform a template matching procedure by using the OpenCV function @ ref cv:: matchTemplate
122
+ - Perform a template matching procedure by using the OpenCV function ** matchTemplate() **
121
123
with any of the 6 matching methods described before. The user can choose the method by
122
124
entering its selection in the Trackbar. If a mask is supplied, it will only be used for
123
125
the methods that support masking
124
126
- Normalize the output of the matching procedure
125
127
- Localize the location with higher matching probability
126
128
- Draw a rectangle around the area corresponding to the highest match
129
+
130
+ @add_toggle_cpp
131
+
127
132
- ** Downloadable code** : Click
128
133
[ here] ( https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp )
129
134
- ** Code at glance:**
130
135
@include samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp
131
136
137
+ @end_toggle
138
+
139
+ @add_toggle_java
140
+
141
+ - ** Downloadable code** : Click
142
+ [ here] ( https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java )
143
+ - ** Code at glance:**
144
+ @include samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java
145
+
146
+ @end_toggle
147
+
148
+ @add_toggle_python
149
+
150
+ - ** Downloadable code** : Click
151
+ [ here] ( https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/imgProc/match_template/match_template.py )
152
+ - ** Code at glance:**
153
+ @include samples/python/tutorial_code/imgProc/match_template/match_template.py
154
+
155
+ @end_toggle
156
+
132
157
Explanation
133
158
-----------
134
159
135
- -# Declare some global variables, such as the image, template and result matrices, as well as the
160
+ - Declare some global variables, such as the image, template and result matrices, as well as the
136
161
match method and the window names:
137
- @code {.cpp}
138
- Mat img; Mat templ; Mat result;
139
- char* image_window = "Source Image";
140
- char* result_window = "Result window";
141
-
142
- int match_method;
143
- int max_Trackbar = 5;
144
- @endcode
145
- -# Load the source image, template, and optionally, if supported for the matching method, a mask:
146
- @code {.cpp}
147
- bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method == CV_TM_CCORR_NORMED);
148
- if (use_mask && method_accepts_mask)
149
- { matchTemplate( img, templ, result, match_method, mask); }
150
- else
151
- { matchTemplate( img, templ, result, match_method); }
152
-
153
- @endcode
154
- -# Create the windows to show the results:
155
- @code {.cpp}
156
- namedWindow( image_window, WINDOW_AUTOSIZE );
157
- namedWindow( result_window, WINDOW_AUTOSIZE );
158
- @endcode
159
- -# Create the Trackbar to enter the kind of matching method to be used. When a change is detected
160
- the callback function ** MatchingMethod** is called.
161
- @code {.cpp}
162
- char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";
163
- createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );
164
- @endcode
165
- -# Wait until user exits the program.
166
- @code {.cpp}
167
- waitKey(0);
168
- return 0;
169
- @endcode
170
- -# Let's check out the callback function. First, it makes a copy of the source image:
171
- @code {.cpp}
172
- Mat img_display;
173
- img.copyTo( img_display );
174
- @endcode
175
- -# Next, it creates the result matrix that will store the matching results for each template
176
- location. Observe in detail the size of the result matrix (which matches all possible locations
177
- for it)
178
- @code {.cpp}
179
- int result_cols = img.cols - templ.cols + 1;
180
- int result_rows = img.rows - templ.rows + 1;
181
-
182
- result.create( result_rows, result_cols, CV_32FC1 );
183
- @endcode
184
- -# Perform the template matching operation:
185
- @code {.cpp}
186
- bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method == CV_TM_CCORR_NORMED);
187
- if (use_mask && method_accepts_mask)
188
- { matchTemplate( img, templ, result, match_method, mask); }
189
- else
190
- { matchTemplate( img, templ, result, match_method); }
191
- @endcode
192
- the arguments are naturally the input image ** I** , the template ** T** , the result ** R** , the
193
- match_method (given by the Trackbar), and optionally the mask image ** M**
194
-
195
- -# We normalize the results:
196
- @code {.cpp}
197
- normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
198
- @endcode
199
- -# We localize the minimum and maximum values in the result matrix ** R** by using @ref
200
- cv::minMaxLoc .
201
- @code {.cpp}
202
- double minVal; double maxVal; Point minLoc; Point maxLoc;
203
- Point matchLoc;
204
-
205
- minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
206
- @endcode
207
- the function calls as arguments:
208
-
209
- - **result:** The source array
210
- - **&minVal** and **&maxVal:** Variables to save the minimum and maximum values in **result**
211
- - **&minLoc** and **&maxLoc:** The Point locations of the minimum and maximum values in the
212
- array.
213
- - **Mat():** Optional mask
214
-
215
- -# For the first two methods ( TM_SQDIFF and MT_SQDIFF_NORMED ) the best match are the lowest
162
+
163
+ @add_toggle_cpp
164
+ @snippet samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp declare
165
+ @end_toggle
166
+
167
+ @add_toggle_java
168
+ @snippet samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java declare
169
+ @end_toggle
170
+
171
+ @add_toggle_python
172
+ @snippet samples/python/tutorial_code/imgProc/match_template/match_template.py global_variables
173
+ @end_toggle
174
+
175
+ - Load the source image, template, and optionally, if supported for the matching method, a mask:
176
+
177
+ @add_toggle_cpp
178
+ @snippet samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp load_image
179
+ @end_toggle
180
+
181
+ @add_toggle_java
182
+ @snippet samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java load_image
183
+ @end_toggle
184
+
185
+ @add_toggle_python
186
+ @snippet samples/python/tutorial_code/imgProc/match_template/match_template.py load_image
187
+ @end_toggle
188
+
189
+ - Create the Trackbar to enter the kind of matching method to be used. When a change is detected
190
+ the callback function is called.
191
+
192
+ @add_toggle_cpp
193
+ @snippet samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp create_trackbar
194
+ @end_toggle
195
+
196
+ @add_toggle_java
197
+ @snippet samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java create_trackbar
198
+ @end_toggle
199
+
200
+ @add_toggle_python
201
+ @snippet samples/python/tutorial_code/imgProc/match_template/match_template.py create_trackbar
202
+ @end_toggle
203
+
204
+ - Let's check out the callback function. First, it makes a copy of the source image:
205
+
206
+ @add_toggle_cpp
207
+ @snippet samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp copy_source
208
+ @end_toggle
209
+
210
+ @add_toggle_java
211
+ @snippet samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java copy_source
212
+ @end_toggle
213
+
214
+ @add_toggle_python
215
+ @snippet samples/python/tutorial_code/imgProc/match_template/match_template.py copy_source
216
+ @end_toggle
217
+
218
+ - Perform the template matching operation. The arguments are naturally the input image ** I** ,
219
+ the template ** T** , the result ** R** and the match_method (given by the Trackbar),
220
+ and optionally the mask image ** M** .
221
+
222
+ @add_toggle_cpp
223
+ @snippet samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp match_template
224
+ @end_toggle
225
+
226
+ @add_toggle_java
227
+ @snippet samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java match_template
228
+ @end_toggle
229
+
230
+ @add_toggle_python
231
+ @snippet samples/python/tutorial_code/imgProc/match_template/match_template.py match_template
232
+ @end_toggle
233
+
234
+ - We normalize the results:
235
+
236
+ @add_toggle_cpp
237
+ @snippet samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp normalize
238
+ @end_toggle
239
+
240
+ @add_toggle_java
241
+ @snippet samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java normalize
242
+ @end_toggle
243
+
244
+ @add_toggle_python
245
+ @snippet samples/python/tutorial_code/imgProc/match_template/match_template.py normalize
246
+ @end_toggle
247
+
248
+ - We localize the minimum and maximum values in the result matrix ** R** by using ** minMaxLoc()** .
249
+
250
+ @add_toggle_cpp
251
+ @snippet samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp best_match
252
+ @end_toggle
253
+
254
+ @add_toggle_java
255
+ @snippet samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java best_match
256
+ @end_toggle
257
+
258
+ @add_toggle_python
259
+ @snippet samples/python/tutorial_code/imgProc/match_template/match_template.py best_match
260
+ @end_toggle
261
+
262
+ - For the first two methods ( TM_SQDIFF and MT_SQDIFF_NORMED ) the best match are the lowest
216
263
values. For all the others, higher values represent better matches. So, we save the
217
264
corresponding value in the ** matchLoc** variable:
218
- @code {.cpp}
219
- if( match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED )
220
- { matchLoc = minLoc; }
221
- else
222
- { matchLoc = maxLoc; }
223
- @endcode
224
- -# Display the source image and the result matrix. Draw a rectangle around the highest possible
265
+
266
+ @add_toggle_cpp
267
+ @snippet samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp match_loc
268
+ @end_toggle
269
+
270
+ @add_toggle_java
271
+ @snippet samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java match_loc
272
+ @end_toggle
273
+
274
+ @add_toggle_python
275
+ @snippet samples/python/tutorial_code/imgProc/match_template/match_template.py match_loc
276
+ @end_toggle
277
+
278
+ - Display the source image and the result matrix. Draw a rectangle around the highest possible
225
279
matching area:
226
- @code {.cpp}
227
- rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
228
- rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
229
280
230
- imshow( image_window, img_display );
231
- imshow( result_window, result );
232
- @endcode
281
+ @add_toggle_cpp
282
+ @snippet samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp imshow
283
+ @end_toggle
284
+
285
+ @add_toggle_java
286
+ @snippet samples/java/tutorial_code/ImgProc/tutorial_template_matching/MatchTemplateDemo.java imshow
287
+ @end_toggle
288
+
289
+ @add_toggle_python
290
+ @snippet samples/python/tutorial_code/imgProc/match_template/match_template.py imshow
291
+ @end_toggle
233
292
234
293
Results
235
294
-------
0 commit comments