1
0
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:
Rishiii57
2026-05-22 02:39:41 +05:30
parent 723670c33d
commit 12eaf9bd4c
2 changed files with 36 additions and 5 deletions
+15
View File
@@ -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