diff --git a/modules/photo/src/denoising.cpp b/modules/photo/src/denoising.cpp index 3fe1f2b90..b41f83ec9 100644 --- a/modules/photo/src/denoising.cpp +++ b/modules/photo/src/denoising.cpp @@ -78,9 +78,14 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h, FastNlMeansDenoisingInvoker( src, dst, templateWindowSize, searchWindowSize, h)); break; + case CV_8UC4: + parallel_for_(cv::Range(0, src.rows), + FastNlMeansDenoisingInvoker( + src, dst, templateWindowSize, searchWindowSize, h)); + break; default: CV_Error(Error::StsBadArg, - "Unsupported image format! Only CV_8U, CV_8UC2, and CV_8UC3 are supported"); + "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3 and CV_8UC4 are supported"); } } @@ -112,6 +117,11 @@ void cv::fastNlMeansDenoisingAbs( InputArray _src, OutputArray _dst, float h, FastNlMeansDenoisingInvoker( src, dst, templateWindowSize, searchWindowSize, h)); break; + case CV_8UC4: + parallel_for_(cv::Range(0, src.rows), + FastNlMeansDenoisingInvoker( + src, dst, templateWindowSize, searchWindowSize, h)); + break; case CV_16U: parallel_for_(cv::Range(0, src.rows), FastNlMeansDenoisingInvoker( @@ -127,9 +137,14 @@ void cv::fastNlMeansDenoisingAbs( InputArray _src, OutputArray _dst, float h, FastNlMeansDenoisingInvoker, int64, uint64, DistAbs>( src, dst, templateWindowSize, searchWindowSize, h)); break; + case CV_16UC4: + parallel_for_(cv::Range(0, src.rows), + FastNlMeansDenoisingInvoker, int64, uint64, DistAbs>( + src, dst, templateWindowSize, searchWindowSize, h)); + break; default: CV_Error(Error::StsBadArg, - "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3, CV_16U, CV_16UC2, and CV_16UC3 are supported"); + "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3, CV_8UC4, CV_16U, CV_16UC2, CV_16UC3 and CV_16UC4 are supported"); } } @@ -240,9 +255,15 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds srcImgs, imgToDenoiseIndex, temporalWindowSize, dst, templateWindowSize, searchWindowSize, h)); break; + case CV_8UC4: + parallel_for_(cv::Range(0, srcImgs[0].rows), + FastNlMeansMultiDenoisingInvoker( + srcImgs, imgToDenoiseIndex, temporalWindowSize, + dst, templateWindowSize, searchWindowSize, h)); + break; default: CV_Error(Error::StsBadArg, - "Unsupported image format! Only CV_8U, CV_8UC2, and CV_8UC3 are supported"); + "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3 and CV_8UC4 are supported"); } } @@ -280,6 +301,12 @@ void cv::fastNlMeansDenoisingMultiAbs( InputArrayOfArrays _srcImgs, OutputArray srcImgs, imgToDenoiseIndex, temporalWindowSize, dst, templateWindowSize, searchWindowSize, h)); break; + case CV_8UC4: + parallel_for_(cv::Range(0, srcImgs[0].rows), + FastNlMeansMultiDenoisingInvoker( + srcImgs, imgToDenoiseIndex, temporalWindowSize, + dst, templateWindowSize, searchWindowSize, h)); + break; case CV_16U: parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker( @@ -298,9 +325,15 @@ void cv::fastNlMeansDenoisingMultiAbs( InputArrayOfArrays _srcImgs, OutputArray srcImgs, imgToDenoiseIndex, temporalWindowSize, dst, templateWindowSize, searchWindowSize, h)); break; + case CV_16UC4: + parallel_for_(cv::Range(0, srcImgs[0].rows), + FastNlMeansMultiDenoisingInvoker, int64, uint64, DistAbs>( + srcImgs, imgToDenoiseIndex, temporalWindowSize, + dst, templateWindowSize, searchWindowSize, h)); + break; default: CV_Error(Error::StsBadArg, - "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3, CV_16U, CV_16UC2, and CV_16UC3 are supported"); + "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3, CV_8UC4, CV_16U, CV_16UC2, CV_16UC3 and CV_16UC4 are supported"); } } diff --git a/modules/photo/src/fast_nlmeans_denoising_invoker.hpp b/modules/photo/src/fast_nlmeans_denoising_invoker.hpp index 468fa82f7..01588b03d 100644 --- a/modules/photo/src/fast_nlmeans_denoising_invoker.hpp +++ b/modules/photo/src/fast_nlmeans_denoising_invoker.hpp @@ -227,7 +227,7 @@ void FastNlMeansDenoisingInvoker::operator() (const Range& range) } // calc weights - IT estimation[3], weights_sum = 0; + IT estimation[pixelInfo::channels], weights_sum = 0; for (size_t channel_num = 0; channel_num < pixelInfo::channels; channel_num++) estimation[channel_num] = 0; diff --git a/modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp b/modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp index d55d93ce7..d77ca3e1f 100644 --- a/modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp +++ b/modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp @@ -110,6 +110,18 @@ class DistAbs } }; + template struct calcDist_, IT> + { + static inline IT f(const Vec a, const Vec b) + { + return + std::abs((IT)(a[0]-b[0])) + + std::abs((IT)(a[1]-b[1])) + + std::abs((IT)(a[2]-b[2])) + + std::abs((IT)(a[3]-b[3])); + } + }; + public: template static inline IT calcDist(const T a, const T b) { @@ -172,6 +184,18 @@ class DistSquared } }; + template struct calcDist_, IT> + { + static inline IT f(const Vec a, const Vec b) + { + return + (IT)(a[0]-b[0])*(IT)(a[0]-b[0]) + + (IT)(a[1]-b[1])*(IT)(a[1]-b[1]) + + (IT)(a[2]-b[2])*(IT)(a[2]-b[2]) + + (IT)(a[3]-b[3])*(IT)(a[3]-b[3]); + } + }; + template struct calcUpDownDist_ { static inline IT f(T a_up, T a_down, T b_up, T b_down) @@ -254,6 +278,17 @@ template struct incWithWeight_, IT> } }; +template struct incWithWeight_, IT> +{ + static inline void f(IT* estimation, IT weight, Vec p) + { + estimation[0] += weight * p[0]; + estimation[1] += weight * p[1]; + estimation[2] += weight * p[2]; + estimation[3] += weight * p[3]; + } +}; + template static inline void incWithWeight(IT* estimation, IT weight, T p) { @@ -291,6 +326,19 @@ template struct saturateCastFromArray_, IT } }; +template struct saturateCastFromArray_, IT> +{ + static inline Vec f(IT* estimation) + { + Vec res; + res[0] = saturate_cast(estimation[0]); + res[1] = saturate_cast(estimation[1]); + res[2] = saturate_cast(estimation[2]); + res[3] = saturate_cast(estimation[3]); + return res; + } +}; + template static inline T saturateCastFromArray(IT* estimation) { return saturateCastFromArray_::f(estimation); diff --git a/modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp b/modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp index 0a2bdd739..eb2078643 100644 --- a/modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp +++ b/modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp @@ -249,7 +249,7 @@ void FastNlMeansMultiDenoisingInvoker::operator() (const Range& r // calc weights IT weights_sum = 0; - IT estimation[3]; + IT estimation[pixelInfo::channels]; for (size_t channel_num = 0; channel_num < pixelInfo::channels; channel_num++) estimation[channel_num] = 0;