From ff48387a8a643f0b8c5095ad503d2249de88ab30 Mon Sep 17 00:00:00 2001 From: Owen Healy Date: Thu, 19 Mar 2015 20:50:49 -0400 Subject: [PATCH] Fix bug of uninitialized matrix in findTransformECC The matrix templateZM needs to be initialized because otherwise uninitialized values leak into the correlation in: const double correlation = templateZM.dot(imageWarped) In the worst case this will lead the correlation to be NaN ruining the whole routine. The subtraction does not initialize templateZM due to the mask. Unfortunately, the uninitialized values (by altering the correlation) have the side effect of dragging out the computation a little longer giving a slightly better error bound. This means that fixing this bug breaks perf_ecc where SANITY_CHECK(warpMat, 1e-3); is just a little too tight and happens to work due to the uninitialized values. Since this is a performance not a accuracy test I think it is OK to just relax the error bound a little bit (the tight error bound being after all the result of a bug). --- modules/video/perf/perf_ecc.cpp | 2 +- modules/video/src/ecc.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/video/perf/perf_ecc.cpp b/modules/video/perf/perf_ecc.cpp index 72410cf576..c706caa07f 100644 --- a/modules/video/perf/perf_ecc.cpp +++ b/modules/video/perf/perf_ecc.cpp @@ -67,5 +67,5 @@ PERF_TEST_P(TransformationType, findTransformECC, /*testing::ValuesIn(MotionType findTransformECC(templateImage, img, warpMat, transform_type, TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 5, -1)); } - SANITY_CHECK(warpMat, 1e-3); + SANITY_CHECK(warpMat, 3e-3); } diff --git a/modules/video/src/ecc.cpp b/modules/video/src/ecc.cpp index 8c5fbee790..6e4d6e9f05 100644 --- a/modules/video/src/ecc.cpp +++ b/modules/video/src/ecc.cpp @@ -465,6 +465,7 @@ double cv::findTransformECC(InputArray templateImage, meanStdDev(templateFloat, tmpMean, tmpStd, imageMask); subtract(imageWarped, imgMean, imageWarped, imageMask);//zero-mean input + templateZM = Mat::zeros(templateZM.rows, templateZM.cols, templateZM.type()); subtract(templateFloat, tmpMean, templateZM, imageMask);//zero-mean template const double tmpNorm = std::sqrt(countNonZero(imageMask)*(tmpStd.val[0])*(tmpStd.val[0]));