mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 08:13:04 +04:00
Merge pull request #15214 from jumostedu:matchtemplmask
* imgproc: templmatch: Add support for mask for all methods Add support for masked template matching. Fix/scrub old implementation for masked matching, as it did partly not even really do a meaningful masking, and only supported limited template matching methods. Add documentation including formulas for masked matching. * imgproc: test: Add tests for masked template matching Test accuracy by comparing to naive implementation for one point. Test compatibility/correctness by comparing results without mask and with all ones mask. All tests are done for all methods, all supported depths, and for 1 and 3 channels. * imgproc: test: templmatch: Add test for crossCorr Add a test for the crossCorr function in templmatch.cpp. crossCorr() had to be added to exported functions to be testable. This test can maybe help to identify the problem with template matching on MacOSX. * fix: Fixed wrong evaluations of the MatExpr on Clang * fix: removed crossCorr from public interface. If it should be exported, it should be done as separate PR. Co-authored-by: Vadim Levin <vadim.levin@xperience.ai>
This commit is contained in:
@@ -3658,14 +3658,43 @@ CV_EXPORTS_W void HuMoments( const Moments& m, OutputArray hu );
|
||||
|
||||
//! type of the template matching operation
|
||||
enum TemplateMatchModes {
|
||||
TM_SQDIFF = 0, //!< \f[R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2\f]
|
||||
TM_SQDIFF_NORMED = 1, //!< \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
|
||||
TM_CCORR = 2, //!< \f[R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y'))\f]
|
||||
TM_CCORR_NORMED = 3, //!< \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
|
||||
TM_CCOEFF = 4, //!< \f[R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I'(x+x',y+y'))\f]
|
||||
//!< where
|
||||
//!< \f[\begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}\f]
|
||||
TM_CCOEFF_NORMED = 5 //!< \f[R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }\f]
|
||||
TM_SQDIFF = 0, /*!< \f[R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2\f]
|
||||
with mask:
|
||||
\f[R(x,y)= \sum _{x',y'} \left( (T(x',y')-I(x+x',y+y')) \cdot
|
||||
M(x',y') \right)^2\f] */
|
||||
TM_SQDIFF_NORMED = 1, /*!< \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{
|
||||
x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
|
||||
with mask:
|
||||
\f[R(x,y)= \frac{\sum _{x',y'} \left( (T(x',y')-I(x+x',y+y')) \cdot
|
||||
M(x',y') \right)^2}{\sqrt{\sum_{x',y'} \left( T(x',y') \cdot
|
||||
M(x',y') \right)^2 \cdot \sum_{x',y'} \left( I(x+x',y+y') \cdot
|
||||
M(x',y') \right)^2}}\f] */
|
||||
TM_CCORR = 2, /*!< \f[R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y'))\f]
|
||||
with mask:
|
||||
\f[R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y') \cdot M(x',y')
|
||||
^2)\f] */
|
||||
TM_CCORR_NORMED = 3, /*!< \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{
|
||||
\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
|
||||
with mask:
|
||||
\f[R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y') \cdot
|
||||
M(x',y')^2)}{\sqrt{\sum_{x',y'} \left( T(x',y') \cdot M(x',y')
|
||||
\right)^2 \cdot \sum_{x',y'} \left( I(x+x',y+y') \cdot M(x',y')
|
||||
\right)^2}}\f] */
|
||||
TM_CCOEFF = 4, /*!< \f[R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I'(x+x',y+y'))\f]
|
||||
where
|
||||
\f[\begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum _{
|
||||
x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h)
|
||||
\cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}\f]
|
||||
with mask:
|
||||
\f[\begin{array}{l} T'(x',y')=M(x',y') \cdot \left( T(x',y') -
|
||||
\frac{1}{\sum _{x'',y''} M(x'',y'')} \cdot \sum _{x'',y''}
|
||||
(T(x'',y'') \cdot M(x'',y'')) \right) \\ I'(x+x',y+y')=M(x',y')
|
||||
\cdot \left( I(x+x',y+y') - \frac{1}{\sum _{x'',y''} M(x'',y'')}
|
||||
\cdot \sum _{x'',y''} (I(x+x'',y+y'') \cdot M(x'',y'')) \right)
|
||||
\end{array} \f] */
|
||||
TM_CCOEFF_NORMED = 5 /*!< \f[R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{
|
||||
\sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2}
|
||||
}\f] */
|
||||
};
|
||||
|
||||
/** @example samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp
|
||||
@@ -3675,9 +3704,10 @@ An example using Template Matching algorithm
|
||||
/** @brief Compares a template against overlapped image regions.
|
||||
|
||||
The function slides through image , compares the overlapped patches of size \f$w \times h\f$ against
|
||||
templ using the specified method and stores the comparison results in result . Here are the formulae
|
||||
for the available comparison methods ( \f$I\f$ denotes image, \f$T\f$ template, \f$R\f$ result ). The summation
|
||||
is done over template and/or the image patch: \f$x' = 0...w-1, y' = 0...h-1\f$
|
||||
templ using the specified method and stores the comparison results in result . #TemplateMatchModes
|
||||
describes the formulae for the available comparison methods ( \f$I\f$ denotes image, \f$T\f$
|
||||
template, \f$R\f$ result, \f$M\f$ the optional mask ). The summation is done over template and/or
|
||||
the image patch: \f$x' = 0...w-1, y' = 0...h-1\f$
|
||||
|
||||
After the function finishes the comparison, the best matches can be found as global minimums (when
|
||||
#TM_SQDIFF was used) or maximums (when #TM_CCORR or #TM_CCOEFF was used) using the
|
||||
@@ -3692,8 +3722,12 @@ data type.
|
||||
@param result Map of comparison results. It must be single-channel 32-bit floating-point. If image
|
||||
is \f$W \times H\f$ and templ is \f$w \times h\f$ , then result is \f$(W-w+1) \times (H-h+1)\f$ .
|
||||
@param method Parameter specifying the comparison method, see #TemplateMatchModes
|
||||
@param mask Mask of searched template. It must have the same datatype and size with templ. It is
|
||||
not set by default. Currently, only the #TM_SQDIFF and #TM_CCORR_NORMED methods are supported.
|
||||
@param mask Optional mask. It must have the same size as templ. It must either have the same number
|
||||
of channels as template or only one channel, which is then used for all template and
|
||||
image channels. If the data type is #CV_8U, the mask is interpreted as a binary mask,
|
||||
meaning only elements where mask is nonzero are used and are kept unchanged independent
|
||||
of the actual mask value (weight equals 1). For data tpye #CV_32F, the mask values are
|
||||
used as weights. The exact formulas are documented in #TemplateMatchModes.
|
||||
*/
|
||||
CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
|
||||
OutputArray result, int method, InputArray mask = noArray() );
|
||||
|
||||
Reference in New Issue
Block a user