mirror of
https://github.com/zebrajr/opencv.git
synced 2025-12-06 12:19:50 +01:00
Merge pull request #27270 from gursimarsingh:bug_fix_unstable_crf
Bug fix unstable crf #27270 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake The PR resolves the issue for triangle Weights used by debevec algorithm being non zero at extremes. It resolves #24966 The fix needs ground truth data to be changed in order to pass existing tests. PR to opencv_extra: https://github.com/opencv/opencv_extra/pull/1253
This commit is contained in:
parent
d00738d97c
commit
c3fe92d813
|
|
@ -63,10 +63,12 @@ Mat triangleWeights()
|
||||||
{
|
{
|
||||||
// hat function
|
// hat function
|
||||||
Mat w(LDR_SIZE, 1, CV_32F);
|
Mat w(LDR_SIZE, 1, CV_32F);
|
||||||
int half = LDR_SIZE / 2;
|
int half = LDR_SIZE / 2;
|
||||||
for(int i = 0; i < LDR_SIZE; i++) {
|
int maxVal = LDR_SIZE - 1;
|
||||||
w.at<float>(i) = i < half ? i + 1.0f : LDR_SIZE - i;
|
for (int i = 0; i < LDR_SIZE; i++)
|
||||||
}
|
w.at<float>(i) = (i < half)
|
||||||
|
? static_cast<float>(i)
|
||||||
|
: static_cast<float>(maxVal - i);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,11 +187,9 @@ TEST(Photo_MergeDebevec, regression)
|
||||||
Mat result, expected;
|
Mat result, expected;
|
||||||
loadImage(test_path + "merge/debevec.hdr", expected);
|
loadImage(test_path + "merge/debevec.hdr", expected);
|
||||||
merge->process(images, result, times, response);
|
merge->process(images, result, times, response);
|
||||||
|
|
||||||
Ptr<Tonemap> map = createTonemap();
|
Ptr<Tonemap> map = createTonemap();
|
||||||
map->process(result, result);
|
map->process(result, result);
|
||||||
map->process(expected, expected);
|
map->process(expected, expected);
|
||||||
|
|
||||||
checkEqual(expected, result, 1e-2f, "Debevec");
|
checkEqual(expected, result, 1e-2f, "Debevec");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,16 +219,15 @@ TEST(Photo_CalibrateDebevec, regression)
|
||||||
loadExposureSeq(test_path + "exposures/", images, times);
|
loadExposureSeq(test_path + "exposures/", images, times);
|
||||||
loadResponseCSV(test_path + "calibrate/debevec.csv", expected);
|
loadResponseCSV(test_path + "calibrate/debevec.csv", expected);
|
||||||
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
|
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
|
||||||
|
|
||||||
calibrate->process(images, response, times);
|
calibrate->process(images, response, times);
|
||||||
Mat diff = abs(response - expected);
|
Mat diff = abs(response - expected);
|
||||||
diff = diff.mul(1.0f / response);
|
diff = diff.mul(1.0f / response);
|
||||||
double max;
|
double max;
|
||||||
minMaxLoc(diff, NULL, &max);
|
minMaxLoc(diff, NULL, &max);
|
||||||
#if defined(__arm__) || defined(__aarch64__)
|
#if defined(__arm__) || defined(__aarch64__)
|
||||||
ASSERT_LT(max, 0.2);
|
ASSERT_LT(max, 0.25);
|
||||||
#else
|
#else
|
||||||
ASSERT_LT(max, 0.1);
|
ASSERT_LT(max, 0.15);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,4 +263,46 @@ TEST(Photo_CalibrateRobertson, bug_18180)
|
||||||
EXPECT_EQ(0.0, cv::norm(response, response_no_nans, NORM_L2));
|
EXPECT_EQ(0.0, cv::norm(response, response_no_nans, NORM_L2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Photo_CalibrateDebevec, bug_24966)
|
||||||
|
{
|
||||||
|
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/";
|
||||||
|
vector<Mat> all_images;
|
||||||
|
vector<float> all_times;
|
||||||
|
loadExposureSeq(test_path + "exposures/", all_images, all_times);
|
||||||
|
// Use a balanced subset of exposures
|
||||||
|
vector<int> selected_indices = {1,2,3,4,5};
|
||||||
|
vector<Mat> images;
|
||||||
|
vector<float> times;
|
||||||
|
for (int idx : selected_indices) {
|
||||||
|
images.push_back(all_images[idx]);
|
||||||
|
times.push_back(all_times[idx]);
|
||||||
|
}
|
||||||
|
// Run CRF estimation for different sample points
|
||||||
|
vector<int> sample_points = {200,300,400};
|
||||||
|
vector<Mat> responses;
|
||||||
|
for (int samples : sample_points) {
|
||||||
|
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec(samples);
|
||||||
|
Mat response;
|
||||||
|
calibrate->process(images, response, times);
|
||||||
|
Mat roi = response.rowRange(15, 240); //Checking CRF only in the middle of the image
|
||||||
|
responses.push_back(roi);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare consecutive pairs of CRFs
|
||||||
|
for (size_t i = 0; i < responses.size()-1; ++i) {
|
||||||
|
Mat diff = abs(responses[i] - responses[i+1]);
|
||||||
|
double max_diff;
|
||||||
|
minMaxLoc(diff, nullptr, &max_diff);
|
||||||
|
cout << "max_diff = " << max_diff << endl;
|
||||||
|
#if defined(__aarch64__) && defined(__APPLE__)
|
||||||
|
ASSERT_LT(max_diff, 10) << "CRF instability detected between samples="
|
||||||
|
<< sample_points[i] << " and " << sample_points[i+1]
|
||||||
|
<< " (max diff = " << max_diff << ")";
|
||||||
|
#else
|
||||||
|
ASSERT_LT(max_diff, 5) << "CRF instability detected between samples="
|
||||||
|
<< sample_points[i] << " and " << sample_points[i+1]
|
||||||
|
<< " (max diff = " << max_diff << ")";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
}} // namespace
|
}} // namespace
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user