From bb798d15e143967da5309eb8b4f934f0bf3ad929 Mon Sep 17 00:00:00 2001 From: Skreg <85214856+shyama7004@users.noreply.github.com> Date: Wed, 29 Jan 2025 18:15:40 +0530 Subject: [PATCH] Merge pull request #26831 from shyama7004:fix-denoising.cpp Added 16-bit support to fastNlMeansDenoising and updated tests #26831 Fixes : #26582 ### 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 - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- modules/photo/src/denoising.cpp | 17 ++++++++-------- modules/photo/test/test_denoising.cpp | 29 +++++++++++++++++++++++++++ modules/photo/test/test_precomp.hpp | 1 + 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/modules/photo/src/denoising.cpp b/modules/photo/src/denoising.cpp index d81795e42b..df7794ce2d 100644 --- a/modules/photo/src/denoising.cpp +++ b/modules/photo/src/denoising.cpp @@ -249,16 +249,15 @@ static void fastNlMeansDenoisingMulti_( const std::vector& srcImgs, Mat& ds int hn = (int)h.size(); double granularity = (double)std::max(1., (double)dst.total()/(1 << 16)); - switch (srcImgs[0].type()) - { - case CV_8U: + switch (CV_MAT_CN(srcImgs[0].type())) { + case 1: parallel_for_(cv::Range(0, srcImgs[0].rows), - FastNlMeansMultiDenoisingInvoker( + FastNlMeansMultiDenoisingInvoker( srcImgs, imgToDenoiseIndex, temporalWindowSize, dst, templateWindowSize, searchWindowSize, &h[0]), granularity); break; - case CV_8UC2: + case 2: if (hn == 1) parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker, IT, UIT, D, int>( @@ -272,7 +271,7 @@ static void fastNlMeansDenoisingMulti_( const std::vector& srcImgs, Mat& ds dst, templateWindowSize, searchWindowSize, &h[0]), granularity); break; - case CV_8UC3: + case 3: if (hn == 1) parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker, IT, UIT, D, int>( @@ -286,7 +285,7 @@ static void fastNlMeansDenoisingMulti_( const std::vector& srcImgs, Mat& ds dst, templateWindowSize, searchWindowSize, &h[0]), granularity); break; - case CV_8UC4: + case 4: if (hn == 1) parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker, IT, UIT, D, int>( @@ -300,9 +299,9 @@ static void fastNlMeansDenoisingMulti_( const std::vector& srcImgs, Mat& ds dst, templateWindowSize, searchWindowSize, &h[0]), granularity); break; - default: + default: CV_Error(Error::StsBadArg, - "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3 and CV_8UC4 are supported"); + "Unsupported number of channels! Only 1, 2, 3, and 4 are supported"); } } diff --git a/modules/photo/test/test_denoising.cpp b/modules/photo/test/test_denoising.cpp index fa330b85a0..2e57369171 100644 --- a/modules/photo/test/test_denoising.cpp +++ b/modules/photo/test/test_denoising.cpp @@ -165,4 +165,33 @@ TEST(Photo_Denoising, speed) printf("execution time: %gms\n", t*1000./getTickFrequency()); } +// Related issue : https://github.com/opencv/opencv/issues/26582 +TEST(Photo_DenoisingGrayscaleMulti16bitL1, regression) +{ + const int imgs_count = 3; + string folder = string(cvtest::TS::ptr()->get_data_path()) + "denoising/"; + + vector original_8u(imgs_count); + vector original_16u(imgs_count); + for (int i = 0; i < imgs_count; i++) + { + string original_path = format("%slena_noised_gaussian_sigma=20_multi_%d.png", folder.c_str(), i); + original_8u[i] = imread(original_path, IMREAD_GRAYSCALE); + ASSERT_FALSE(original_8u[i].empty()) << "Could not load input image " << original_path; + original_8u[i].convertTo(original_16u[i], CV_16U); + } + + Mat result_8u, result_16u; + std::vector h = {15}; + fastNlMeansDenoisingMulti(original_8u, result_8u, /*imgToDenoiseIndex*/ imgs_count / 2, /*temporalWindowSize*/ imgs_count, h, 7, 21, NORM_L1); + fastNlMeansDenoisingMulti(original_16u, result_16u, /*imgToDenoiseIndex*/ imgs_count / 2, /*temporalWindowSize*/ imgs_count, h, 7, 21, NORM_L1); + DUMP(result_8u, "8u.res.png"); + DUMP(result_16u, "16u.res.png"); + + cv::Mat expected; + result_8u.convertTo(expected, CV_16U); + + EXPECT_MAT_NEAR(result_16u, expected, 1); +} + }} // namespace diff --git a/modules/photo/test/test_precomp.hpp b/modules/photo/test/test_precomp.hpp index 5d33a42f01..33d7e5a9b7 100644 --- a/modules/photo/test/test_precomp.hpp +++ b/modules/photo/test/test_precomp.hpp @@ -5,6 +5,7 @@ #define __OPENCV_TEST_PRECOMP_HPP__ #include "opencv2/ts.hpp" +#include "opencv2/ts/ocl_test.hpp" #include "opencv2/photo.hpp" #endif