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