From 7cc7414a51cfcd189ce4311e84f992a42b7d6028 Mon Sep 17 00:00:00 2001 From: Vladislav Sovrasov Date: Tue, 13 Sep 2016 13:08:10 +0300 Subject: [PATCH] Fix numerical issue in guided filter --- modules/ximgproc/src/guided_filter.cpp | 9 ++++- modules/ximgproc/test/test_guided_filter.cpp | 41 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/modules/ximgproc/src/guided_filter.cpp b/modules/ximgproc/src/guided_filter.cpp index 502679ee5..b94d812f1 100644 --- a/modules/ximgproc/src/guided_filter.cpp +++ b/modules/ximgproc/src/guided_filter.cpp @@ -424,6 +424,13 @@ void GuidedFilterImpl::ComputeCovGuideInv_ParBody::operator()(const Range& range add_mul(det, a, ac, gf.w); } + if (gf.eps < 1e-2) + { + for (int j = 0; j < gf.w; j++) + if (abs(det[j]) < 1e-6f) + det[j] = 1.f; + } + for (int k = 0; k < gf.covarsInv.total(); k += 1) { div_1x(gf.covarsInv(k).ptr(i), det, gf.w); @@ -788,4 +795,4 @@ void guidedFilter(InputArray guide, InputArray src, OutputArray dst, int radius, } } -} \ No newline at end of file +} diff --git a/modules/ximgproc/test/test_guided_filter.cpp b/modules/ximgproc/test/test_guided_filter.cpp index 42a11a760..89fd9837b 100644 --- a/modules/ximgproc/test/test_guided_filter.cpp +++ b/modules/ximgproc/test/test_guided_filter.cpp @@ -387,6 +387,47 @@ TEST_P(GuidedFilterTest, accuracy) } } +TEST_P(GuidedFilterTest, smallParamsIssue) +{ + GFParams params = GetParam(); + string guideFileName = get<1>(params); + string srcFileName = get<2>(params); + int guideCnNum = 3; + int srcCnNum = get<0>(params); + + Mat guide = imread(getOpenCVExtraDir() + guideFileName); + Mat src = imread(getOpenCVExtraDir() + srcFileName); + ASSERT_TRUE(!guide.empty() && !src.empty()); + + Size dstSize(guide.cols, guide.rows); + guide = convertTypeAndSize(guide, CV_MAKE_TYPE(guide.depth(), guideCnNum), dstSize); + src = convertTypeAndSize(src, CV_MAKE_TYPE(src.depth(), srcCnNum), dstSize); + Mat output; + + ximgproc::guidedFilter(guide, src, output, 3, 1e-6); + + size_t whitePixels = 0; + for(int i = 0; i < output.cols; i++) + { + for(int j = 0; j < output.rows; j++) + { + if(output.channels() == 1) + { + if(output.ptr(i)[j] == 255) + whitePixels++; + } + else if(output.channels() == 3) + { + Vec3b currentPixel = output.ptr(i)[j]; + if(currentPixel == Vec3b(255, 255, 255)) + whitePixels++; + } + } + } + double whiteRate = whitePixels / (double) output.total(); + EXPECT_LE(whiteRate, 0.1); +} + INSTANTIATE_TEST_CASE_P(TypicalSet, GuidedFilterTest, Combine( Values(1, 3),