Merge pull request #20054 from danielenricocahall:fix-robertson-calibration-bug
authorDanny <33044223+danielenricocahall@users.noreply.github.com>
Sun, 30 May 2021 20:29:39 +0000 (16:29 -0400)
committerGitHub <noreply@github.com>
Sun, 30 May 2021 20:29:39 +0000 (23:29 +0300)
Fix Robertson Calibration NaN Bug

* add epsilon value for numerical stability in robertson merge

* update test to use range based for loop

* add comment to test

* move the epsilon

* address test comments

fix windows build warnings

fix vector type for tests

update tests

make threshold float

address test comments

fix tests and move epsilon again

* use scalar::all, move epsilon, and remove print

modules/photo/src/merge.cpp
modules/photo/test/test_hdr.cpp

index fbeb4639b43af52723dea7641d6ed23cec934d2b..e6a00fedb857229345bf335d7281d43beab10059 100644 (file)
@@ -344,7 +344,7 @@ public:
             result += times.at<float>((int)i) * w.mul(im);
             wsum += times.at<float>((int)i) * times.at<float>((int)i) * w;
         }
-        result = result.mul(1 / wsum);
+        result = result.mul(1 / (wsum + Scalar::all(DBL_EPSILON)));
     }
 
     void process(InputArrayOfArrays src, OutputArray dst, InputArray times) CV_OVERRIDE
index 198b83470cc1c766d85decbe8f531f2723b71768..10050abbcbf39164382f17f3be1c265af33a519d 100644 (file)
@@ -249,4 +249,21 @@ TEST(Photo_CalibrateRobertson, regression)
     checkEqual(expected, response, 1e-1f, "CalibrateRobertson");
 }
 
+TEST(Photo_CalibrateRobertson, bug_18180)
+{
+    vector<Mat> images;
+    vector<cv::String> fn;
+    string test_path = cvtest::TS::ptr()->get_data_path() + "hdr/exposures/bug_18180/";
+    for(int i = 1; i <= 4; ++i)
+        images.push_back(imread(test_path + std::to_string(i) + ".jpg"));
+    vector<float> times {15.0f, 2.5f, 0.25f, 0.33f};
+    Mat response, expected;
+    Ptr<CalibrateRobertson> calibrate = createCalibrateRobertson(2, 0.01f);
+    calibrate->process(images, response, times);
+    Mat response_no_nans = response.clone();
+    patchNaNs(response_no_nans);
+    // since there should be no NaNs, original response vs. response with NaNs patched should be identical
+    EXPECT_EQ(0.0, cv::norm(response, response_no_nans, NORM_L2));
+}
+
 }} // namespace