Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
ce05d6cb
Commit
ce05d6cb
authored
Jul 18, 2016
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6773 from acinader:add-mask-to-match-template-demo
parents
26bf5b5d
bd7c21d8
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
60 additions
and
12 deletions
+60
-12
Template_Matching_Mask_Example.jpg
...mplate_matching/images/Template_Matching_Mask_Example.jpg
+0
-0
template_matching.markdown
...c/histograms/template_matching/template_matching.markdown
+45
-8
MatchTemplate_Demo.cpp
.../tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp
+15
-4
No files found.
doc/tutorials/imgproc/histograms/template_matching/images/Template_Matching_Mask_Example.jpg
0 → 100644
View file @
ce05d6cb
77.2 KB
doc/tutorials/imgproc/histograms/template_matching/template_matching.markdown
View file @
ce05d6cb
...
...
@@ -19,6 +19,10 @@ Theory
Template matching is a technique for finding areas of an image that match (are similar) to a
template image (patch).
While the patch must be a rectangle it may be that not all of the
rectangle is relevant. In such a case, a mask can be used to isolate the portion of the patch
that should be used to find the match.
### How does it work?
-
We need two primary components:
...
...
@@ -51,6 +55,30 @@ template image (patch).
-
In practice, we use the function @ref cv::minMaxLoc to locate the highest value (or lower,
depending of the type of matching method) in the
*R*
matrix.
### How does the mask work?
-
If masking is needed for the match, three components are required:
-# **Source image (I):** The image in which we expect to find a match to the template image
-# **Template image (T):** The patch image which will be compared to the template image
-# **Mask image (M):** The mask, a grayscale image that masks the template
-
Only two matching methods currently accept a mask: CV_TM_SQDIFF and CV_TM_CCORR_NORMED (see
below for explanation of all the matching methods available in opencv).
-
The mask must have the same dimensions as the template
-
The mask should have a CV_8U or CV_32F depth and the same number of channels
as the template image. In CV_8U case, the mask values are treated as binary,
i.e. zero and non-zero. In CV_32F case, the values should fall into
[
0..1
]
range and the template pixels will be multiplied by the corresponding mask pixel
values. Since the input images in the sample have the CV_8UC3 type, the mask
is also read as color image.
![](images/Template_Matching_Mask_Example.jpg)
### Which are the matching methods available in OpenCV?
Good question. OpenCV implements Template matching in the function @ref cv::matchTemplate . The
...
...
@@ -88,10 +116,11 @@ Code
----
-
**What does this program do?**
-
Loads an input image
and a image patch (
*template*
)
-
Loads an input image
, an image patch (
*template*
), and optionally a mask
-
Perform a template matching procedure by using the OpenCV function @ref cv::matchTemplate
with any of the 6 matching methods described before. The user can choose the method by
entering its selection in the Trackbar.
entering its selection in the Trackbar. If a mask is supplied, it will only be used for
the methods that support masking
-
Normalize the output of the matching procedure
-
Localize the location with higher matching probability
-
Draw a rectangle around the area corresponding to the highest match
...
...
@@ -113,10 +142,14 @@ Explanation
int match_method;
int max_Trackbar = 5;
@endcode
-# Load the source image
and template
:
-# Load the source image
, template, and optionally, if supported for the matching method, a mask
:
@code{.cpp}
img = imread( argv
[
1
]
, 1 );
templ = imread( argv
[
2
]
, 1 );
bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method == CV_TM_CCORR_NORMED);
if (use_mask && method_accepts_mask)
{ matchTemplate( img, templ, result, match_method, mask); }
else
{ matchTemplate( img, templ, result, match_method); }
@endcode
-# Create the windows to show the results:
@code{.cpp}
...
...
@@ -150,10 +183,14 @@ Explanation
@endcode
-# Perform the template matching operation:
@code{.cpp}
matchTemplate( img, templ, result, match_method );
bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method == CV_TM_CCORR_NORMED);
if (use_mask && method_accepts_mask)
{ matchTemplate( img, templ, result, match_method, mask); }
else
{ matchTemplate( img, templ, result, match_method); }
@endcode
the arguments are naturally the input image
**I**
, the template
**T**
, the result
**R**
and
the
match_method (given by the Trackbar)
the arguments are naturally the input image
**I**
, the template
**T**
, the result
**R**
,
the
match_method (given by the Trackbar)
, and optionally the mask image
**M**
-# We normalize the results:
@code{.cpp}
...
...
samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp
View file @
ce05d6cb
...
...
@@ -13,7 +13,8 @@ using namespace std;
using
namespace
cv
;
/// Global Variables
Mat
img
;
Mat
templ
;
Mat
result
;
bool
use_mask
;
Mat
img
;
Mat
templ
;
Mat
mask
;
Mat
result
;
const
char
*
image_window
=
"Source Image"
;
const
char
*
result_window
=
"Result window"
;
...
...
@@ -31,7 +32,7 @@ int main( int argc, char** argv )
if
(
argc
<
3
)
{
cout
<<
"Not enough parameters"
<<
endl
;
cout
<<
"Usage:
\n
./MatchTemplate_Demo <image_name> <template_name>"
<<
endl
;
cout
<<
"Usage:
\n
./MatchTemplate_Demo <image_name> <template_name>
[<mask_name>]
"
<<
endl
;
return
-
1
;
}
...
...
@@ -39,7 +40,12 @@ int main( int argc, char** argv )
img
=
imread
(
argv
[
1
],
IMREAD_COLOR
);
templ
=
imread
(
argv
[
2
],
IMREAD_COLOR
);
if
(
img
.
empty
()
||
templ
.
empty
())
if
(
argc
>
3
)
{
use_mask
=
true
;
mask
=
imread
(
argv
[
3
],
IMREAD_COLOR
);
}
if
(
img
.
empty
()
||
templ
.
empty
()
||
(
use_mask
&&
mask
.
empty
()))
{
cout
<<
"Can't read one of the images"
<<
endl
;
return
-
1
;
...
...
@@ -76,7 +82,12 @@ void MatchingMethod( int, void* )
result
.
create
(
result_rows
,
result_cols
,
CV_32FC1
);
/// Do the Matching and Normalize
matchTemplate
(
img
,
templ
,
result
,
match_method
);
bool
method_accepts_mask
=
(
CV_TM_SQDIFF
==
match_method
||
match_method
==
CV_TM_CCORR_NORMED
);
if
(
use_mask
&&
method_accepts_mask
)
{
matchTemplate
(
img
,
templ
,
result
,
match_method
,
mask
);
}
else
{
matchTemplate
(
img
,
templ
,
result
,
match_method
);
}
normalize
(
result
,
result
,
0
,
1
,
NORM_MINMAX
,
-
1
,
Mat
()
);
/// Localizing the best match with minMaxLoc
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment