diff --git a/modules/photo/perf/opencl/perf_denoising.cpp b/modules/photo/perf/opencl/perf_denoising.cpp index 0a0a2d6b53..cd0d3a2420 100644 --- a/modules/photo/perf/opencl/perf_denoising.cpp +++ b/modules/photo/perf/opencl/perf_denoising.cpp @@ -45,7 +45,7 @@ OCL_PERF_TEST(Photo, DenoisingColored) SANITY_CHECK(result); } -OCL_PERF_TEST(Photo, DESABLED_DenoisingGrayscaleMulti) +OCL_PERF_TEST(Photo, DISABLED_DenoisingGrayscaleMulti) { const int imgs_count = 3; @@ -68,7 +68,7 @@ OCL_PERF_TEST(Photo, DESABLED_DenoisingGrayscaleMulti) SANITY_CHECK(result); } -OCL_PERF_TEST(Photo, DESABLED_DenoisingColoredMulti) +OCL_PERF_TEST(Photo, DISABLED_DenoisingColoredMulti) { const int imgs_count = 3; diff --git a/modules/photo/src/denoising.cpp b/modules/photo/src/denoising.cpp index a3aa0f41f9..c9670f452d 100644 --- a/modules/photo/src/denoising.cpp +++ b/modules/photo/src/denoising.cpp @@ -86,15 +86,20 @@ void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst, float h, float hForColorComponents, int templateWindowSize, int searchWindowSize) { - Mat src = _src.getMat(); - _dst.create(src.size(), src.type()); - Mat dst = _dst.getMat(); - - if (src.type() != CV_8UC3) { + if (_src.type() != CV_8UC3) + { CV_Error(Error::StsBadArg, "Type of input image should be CV_8UC3!"); return; } + CV_OCL_RUN(_src.dims() <= 2 && (_dst.isUMat() || _src.isUMat()), + ocl_fastNlMeansDenoisingColored(_src, _dst, h, hForColorComponents, + templateWindowSize, searchWindowSize)) + + Mat src = _src.getMat(); + _dst.create(src.size(), src.type()); + Mat dst = _dst.getMat(); + Mat src_lab; cvtColor(src, src_lab, COLOR_LBGR2Lab); diff --git a/modules/photo/src/fast_nlmeans_denoising_opencl.hpp b/modules/photo/src/fast_nlmeans_denoising_opencl.hpp index 3a7037aeaa..9e4cd06090 100644 --- a/modules/photo/src/fast_nlmeans_denoising_opencl.hpp +++ b/modules/photo/src/fast_nlmeans_denoising_opencl.hpp @@ -132,6 +132,38 @@ static bool ocl_fastNlMeansDenoising(InputArray _src, OutputArray _dst, float h, return k.run(2, globalsize, localsize, false); } +static bool ocl_fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst, + float h, float hForColorComponents, + int templateWindowSize, int searchWindowSize) +{ + UMat src = _src.getUMat(); + _dst.create(src.size(), src.type()); + UMat dst = _dst.getUMat(); + + UMat src_lab; + cvtColor(src, src_lab, COLOR_LBGR2Lab); + + UMat l(src.size(), CV_8U); + UMat ab(src.size(), CV_8UC2); + std::vector l_ab(2), l_ab_denoised(2); + l_ab[0] = l; + l_ab[1] = ab; + l_ab_denoised[0].create(src.size(), CV_8U); + l_ab_denoised[1].create(src.size(), CV_8UC2); + + int from_to[] = { 0,0, 1,1, 2,2 }; + mixChannels(std::vector(1, src_lab), l_ab, from_to, 3); + + fastNlMeansDenoising(l_ab[0], l_ab_denoised[0], h, templateWindowSize, searchWindowSize); + fastNlMeansDenoising(l_ab[1], l_ab_denoised[1], hForColorComponents, templateWindowSize, searchWindowSize); + + UMat dst_lab(src.size(), src.type()); + mixChannels(l_ab_denoised, std::vector(1, dst_lab), from_to, 3); + + cvtColor(dst_lab, dst, COLOR_Lab2LBGR); + return true; +} + } #endif diff --git a/modules/photo/test/ocl/test_denoising.cpp b/modules/photo/test/ocl/test_denoising.cpp index 6630b0291c..51de634622 100644 --- a/modules/photo/test/ocl/test_denoising.cpp +++ b/modules/photo/test/ocl/test_denoising.cpp @@ -98,7 +98,23 @@ OCL_TEST_P(FastNlMeansDenoising, Mat) } } +typedef FastNlMeansDenoisingTestBase fastNlMeansDenoisingColored; + +OCL_TEST_P(fastNlMeansDenoisingColored, Mat) +{ + for (int j = 0; j < test_loop_times; j++) + { + generateTestData(); + + OCL_OFF(cv::fastNlMeansDenoisingColored(src_roi, dst_roi, h, h, templateWindowSize, searchWindowSize)); + OCL_ON(cv::fastNlMeansDenoisingColored(usrc_roi, udst_roi, h, h, templateWindowSize, searchWindowSize)); + + OCL_EXPECT_MATS_NEAR(dst, 1) + } +} + OCL_INSTANTIATE_TEST_CASE_P(Photo, FastNlMeansDenoising, Combine(Values(1, 2), Bool())); +OCL_INSTANTIATE_TEST_CASE_P(Photo, fastNlMeansDenoisingColored, Combine(Values(Channels(3)), Bool())); } } // namespace cvtest::ocl