mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
imgproc: fix matchTemplate TM_SQDIFF precision loss for CV_8U images
When computing TM_SQDIFF for 8-bit images, crossCorr stores intermediate results in CV_32F which loses precision for large patch sums (e.g. 25x25 patch of value 255 gives sum=40603125, exceeding float32's ~7 significant digits). This causes the final SQDIFF result to have incorrect non-zero values even when image and template are identical. Fix: use a CV_64F intermediate buffer for crossCorr and common_matchTemplate when depth==CV_8U and method is TM_SQDIFF or TM_SQDIFF_NORMED, then convert back to CV_32F for the final output. Fixes #21786
This commit is contained in:
@@ -342,4 +342,19 @@ INSTANTIATE_TEST_CASE_P(/**/,
|
||||
testing::Values(TM_SQDIFF, TM_SQDIFF_NORMED, TM_CCORR, TM_CCORR_NORMED, TM_CCOEFF, TM_CCOEFF_NORMED)));
|
||||
|
||||
|
||||
TEST(Imgproc_MatchTemplate, bug_21786)
|
||||
{
|
||||
// CV_8U identical image/template with large patch sums triggers float32
|
||||
// catastrophic cancellation in TM_SQDIFF. Result must be exactly zero.
|
||||
Mat img(100, 100, CV_8U, Scalar(255));
|
||||
Mat templ(25, 25, CV_8U, Scalar(255));
|
||||
Mat result;
|
||||
|
||||
matchTemplate(img, templ, result, TM_SQDIFF);
|
||||
EXPECT_NEAR(0.0, cv::norm(result, cv::NORM_INF), 1e-6);
|
||||
|
||||
matchTemplate(img, templ, result, TM_SQDIFF_NORMED);
|
||||
EXPECT_NEAR(0.0, cv::norm(result, cv::NORM_INF), 1e-6);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
Reference in New Issue
Block a user