mirror of
https://github.com/opencv/opencv.git
synced 2025-06-11 03:33:28 +08:00
Merge pull request #6773 from acinader:add-mask-to-match-template-demo
This commit is contained in:
commit
ce05d6cb89
Binary file not shown.
After Width: | Height: | Size: 77 KiB |
@ -19,6 +19,10 @@ Theory
|
|||||||
Template matching is a technique for finding areas of an image that match (are similar) to a
|
Template matching is a technique for finding areas of an image that match (are similar) to a
|
||||||
template image (patch).
|
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?
|
### How does it work?
|
||||||
|
|
||||||
- We need two primary components:
|
- 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,
|
- 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.
|
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.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### Which are the matching methods available in OpenCV?
|
### Which are the matching methods available in OpenCV?
|
||||||
|
|
||||||
Good question. OpenCV implements Template matching in the function @ref cv::matchTemplate . The
|
Good question. OpenCV implements Template matching in the function @ref cv::matchTemplate . The
|
||||||
@ -88,10 +116,11 @@ Code
|
|||||||
----
|
----
|
||||||
|
|
||||||
- **What does this program do?**
|
- **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
|
- 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
|
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
|
- Normalize the output of the matching procedure
|
||||||
- Localize the location with higher matching probability
|
- Localize the location with higher matching probability
|
||||||
- Draw a rectangle around the area corresponding to the highest match
|
- Draw a rectangle around the area corresponding to the highest match
|
||||||
@ -113,10 +142,14 @@ Explanation
|
|||||||
int match_method;
|
int match_method;
|
||||||
int max_Trackbar = 5;
|
int max_Trackbar = 5;
|
||||||
@endcode
|
@endcode
|
||||||
-# Load the source image and template:
|
-# Load the source image, template, and optionally, if supported for the matching method, a mask:
|
||||||
@code{.cpp}
|
@code{.cpp}
|
||||||
img = imread( argv[1], 1 );
|
bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method == CV_TM_CCORR_NORMED);
|
||||||
templ = imread( argv[2], 1 );
|
if (use_mask && method_accepts_mask)
|
||||||
|
{ matchTemplate( img, templ, result, match_method, mask); }
|
||||||
|
else
|
||||||
|
{ matchTemplate( img, templ, result, match_method); }
|
||||||
|
|
||||||
@endcode
|
@endcode
|
||||||
-# Create the windows to show the results:
|
-# Create the windows to show the results:
|
||||||
@code{.cpp}
|
@code{.cpp}
|
||||||
@ -150,10 +183,14 @@ Explanation
|
|||||||
@endcode
|
@endcode
|
||||||
-# Perform the template matching operation:
|
-# Perform the template matching operation:
|
||||||
@code{.cpp}
|
@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
|
@endcode
|
||||||
the arguments are naturally the input image **I**, the template **T**, the result **R** and the
|
the arguments are naturally the input image **I**, the template **T**, the result **R**, the
|
||||||
match_method (given by the Trackbar)
|
match_method (given by the Trackbar), and optionally the mask image **M**
|
||||||
|
|
||||||
-# We normalize the results:
|
-# We normalize the results:
|
||||||
@code{.cpp}
|
@code{.cpp}
|
||||||
|
@ -13,7 +13,8 @@ using namespace std;
|
|||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
/// Global Variables
|
/// 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* image_window = "Source Image";
|
||||||
const char* result_window = "Result window";
|
const char* result_window = "Result window";
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ int main( int argc, char** argv )
|
|||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
{
|
{
|
||||||
cout << "Not enough parameters" << endl;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +40,12 @@ int main( int argc, char** argv )
|
|||||||
img = imread( argv[1], IMREAD_COLOR );
|
img = imread( argv[1], IMREAD_COLOR );
|
||||||
templ = imread( argv[2], 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;
|
cout << "Can't read one of the images" << endl;
|
||||||
return -1;
|
return -1;
|
||||||
@ -76,7 +82,12 @@ void MatchingMethod( int, void* )
|
|||||||
result.create( result_rows, result_cols, CV_32FC1 );
|
result.create( result_rows, result_cols, CV_32FC1 );
|
||||||
|
|
||||||
/// Do the Matching and Normalize
|
/// 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() );
|
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
|
||||||
|
|
||||||
/// Localizing the best match with minMaxLoc
|
/// Localizing the best match with minMaxLoc
|
||||||
|
Loading…
Reference in New Issue
Block a user