diff --git a/modules/photo/include/opencv2/photo.hpp b/modules/photo/include/opencv2/photo.hpp
index 0a42424cb..c651b9ee3 100644
--- a/modules/photo/include/opencv2/photo.hpp
+++ b/modules/photo/include/opencv2/photo.hpp
@@ -142,7 +142,8 @@ CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, float h
with several computational
optimizations. Noise expected to be a gaussian white noise
-@param src Input 8-bit 1-channel, 2-channel, 3-channel or 4-channel image.
+@param src Input 8-bit or 16-bit (only with NORM_L1) 1-channel,
+2-channel, 3-channel or 4-channel image.
@param dst Output image with the same size and type as src .
@param templateWindowSize Size in pixels of the template patch that is used to compute weights.
Should be odd. Recommended value 7 pixels
@@ -153,7 +154,7 @@ denoising time. Recommended value 21 pixels
parameter applied to all channels or one per channel in dst. Big h value
perfectly removes noise but also removes image details, smaller h
value preserves details but also preserves some noise
-@param normType Type of norm used for weight calcluation. Can be either NORM_L2 or NORM_L1
+@param normType Type of norm used for weight calculation. Can be either NORM_L2 or NORM_L1
This function expected to be applied to grayscale images. For colored images look at
fastNlMeansDenoisingColored. Advanced usage of this functions can be manual denoising of colored
@@ -220,9 +221,9 @@ captured in small period of time. For example video. This version of the functio
images or for manual manipulation with colorspaces. For more details see
-@param srcImgs Input 8-bit 1-channel, 2-channel, 3-channel or
-4-channel images sequence. All images should have the same type and
-size.
+@param srcImgs Input 8-bit or 16-bit (only with NORM_L1) 1-channel,
+2-channel, 3-channel or 4-channel images sequence. All images should
+have the same type and size.
@param imgToDenoiseIndex Target image to denoise index in srcImgs sequence
@param temporalWindowSize Number of surrounding images to use for target image denoising. Should
be odd. Images from imgToDenoiseIndex - temporalWindowSize / 2 to
@@ -238,10 +239,13 @@ denoising time. Recommended value 21 pixels
parameter applied to all channels or one per channel in dst. Big h value
perfectly removes noise but also removes image details, smaller h
value preserves details but also preserves some noise
+@param normType Type of norm used for weight calculation. Can be either NORM_L2 or NORM_L1
*/
CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst,
- int imgToDenoiseIndex, int temporalWindowSize,
- const std::vector& h , int templateWindowSize = 7, int searchWindowSize = 21);
+ int imgToDenoiseIndex, int temporalWindowSize,
+ const std::vector& h,
+ int templateWindowSize = 7, int searchWindowSize = 21,
+ int normType = NORM_L2);
/** @brief Modification of fastNlMeansDenoisingMulti function for colored images sequences
diff --git a/modules/photo/src/denoising.cpp b/modules/photo/src/denoising.cpp
index 4e7922e40..c68d09b92 100644
--- a/modules/photo/src/denoising.cpp
+++ b/modules/photo/src/denoising.cpp
@@ -230,6 +230,64 @@ static void fastNlMeansDenoisingMultiCheckPreconditions(
}
}
+template
+static void fastNlMeansDenoisingMulti_( const std::vector& srcImgs, Mat& dst,
+ int imgToDenoiseIndex, int temporalWindowSize,
+ const std::vector& h,
+ int templateWindowSize, int searchWindowSize)
+{
+ int hn = (int)h.size();
+
+ switch (srcImgs[0].type())
+ {
+ case CV_8U:
+ parallel_for_(cv::Range(0, srcImgs[0].rows),
+ FastNlMeansMultiDenoisingInvoker(
+ srcImgs, imgToDenoiseIndex, temporalWindowSize,
+ dst, templateWindowSize, searchWindowSize, &h[0]));
+ break;
+ case CV_8UC2:
+ if (hn == 1)
+ parallel_for_(cv::Range(0, srcImgs[0].rows),
+ FastNlMeansMultiDenoisingInvoker, IT, UIT, D, int>(
+ srcImgs, imgToDenoiseIndex, temporalWindowSize,
+ dst, templateWindowSize, searchWindowSize, &h[0]));
+ else
+ parallel_for_(cv::Range(0, srcImgs[0].rows),
+ FastNlMeansMultiDenoisingInvoker, IT, UIT, D, Vec2i>(
+ srcImgs, imgToDenoiseIndex, temporalWindowSize,
+ dst, templateWindowSize, searchWindowSize, &h[0]));
+ break;
+ case CV_8UC3:
+ if (hn == 1)
+ parallel_for_(cv::Range(0, srcImgs[0].rows),
+ FastNlMeansMultiDenoisingInvoker, IT, UIT, D, int>(
+ srcImgs, imgToDenoiseIndex, temporalWindowSize,
+ dst, templateWindowSize, searchWindowSize, &h[0]));
+ else
+ parallel_for_(cv::Range(0, srcImgs[0].rows),
+ FastNlMeansMultiDenoisingInvoker, IT, UIT, D, Vec3i>(
+ srcImgs, imgToDenoiseIndex, temporalWindowSize,
+ dst, templateWindowSize, searchWindowSize, &h[0]));
+ break;
+ case CV_8UC4:
+ if (hn == 1)
+ parallel_for_(cv::Range(0, srcImgs[0].rows),
+ FastNlMeansMultiDenoisingInvoker, IT, UIT, D, int>(
+ srcImgs, imgToDenoiseIndex, temporalWindowSize,
+ dst, templateWindowSize, searchWindowSize, &h[0]));
+ else
+ parallel_for_(cv::Range(0, srcImgs[0].rows),
+ FastNlMeansMultiDenoisingInvoker, IT, UIT, D, Vec4i>(
+ srcImgs, imgToDenoiseIndex, temporalWindowSize,
+ dst, templateWindowSize, searchWindowSize, &h[0]));
+ break;
+ default:
+ CV_Error(Error::StsBadArg,
+ "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3 and CV_8UC4 are supported");
+ }
+}
+
void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
int imgToDenoiseIndex, int temporalWindowSize,
float h, int templateWindowSize, int searchWindowSize)
@@ -241,7 +299,7 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds
void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
int imgToDenoiseIndex, int temporalWindowSize,
const std::vector& h,
- int templateWindowSize, int searchWindowSize)
+ int templateWindowSize, int searchWindowSize, int normType)
{
std::vector srcImgs;
_srcImgs.getMatVector(srcImgs);
@@ -251,58 +309,51 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds
temporalWindowSize, templateWindowSize, searchWindowSize);
int hn = (int)h.size();
- CV_Assert(hn == 1 || hn == CV_MAT_CN(srcImgs[0].type()));
+ int type = srcImgs[0].type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
+ CV_Assert(hn == 1 || hn == cn);
_dst.create(srcImgs[0].size(), srcImgs[0].type());
Mat dst = _dst.getMat();
- switch (srcImgs[0].type())
- {
- case CV_8U:
- parallel_for_(cv::Range(0, srcImgs[0].rows),
- FastNlMeansMultiDenoisingInvoker(
- srcImgs, imgToDenoiseIndex, temporalWindowSize,
- dst, templateWindowSize, searchWindowSize, &h[0]));
+ switch (normType) {
+ case NORM_L2:
+ switch (depth) {
+ case CV_8U:
+ fastNlMeansDenoisingMulti_(srcImgs, dst,
+ imgToDenoiseIndex, temporalWindowSize,
+ h,
+ templateWindowSize, searchWindowSize);
+ break;
+ default:
+ CV_Error(Error::StsBadArg,
+ "Unsupported depth! Only CV_8U is supported for NORM_L2");
+ }
break;
- case CV_8UC2:
- if (hn == 1)
- parallel_for_(cv::Range(0, srcImgs[0].rows),
- FastNlMeansMultiDenoisingInvoker(
- srcImgs, imgToDenoiseIndex, temporalWindowSize,
- dst, templateWindowSize, searchWindowSize, &h[0]));
- else
- parallel_for_(cv::Range(0, srcImgs[0].rows),
- FastNlMeansMultiDenoisingInvoker(
- srcImgs, imgToDenoiseIndex, temporalWindowSize,
- dst, templateWindowSize, searchWindowSize, &h[0]));
- break;
- case CV_8UC3:
- if (hn == 1)
- parallel_for_(cv::Range(0, srcImgs[0].rows),
- FastNlMeansMultiDenoisingInvoker(
- srcImgs, imgToDenoiseIndex, temporalWindowSize,
- dst, templateWindowSize, searchWindowSize, &h[0]));
- else
- parallel_for_(cv::Range(0, srcImgs[0].rows),
- FastNlMeansMultiDenoisingInvoker(
- srcImgs, imgToDenoiseIndex, temporalWindowSize,
- dst, templateWindowSize, searchWindowSize, &h[0]));
- break;
- case CV_8UC4:
- if (hn == 1)
- parallel_for_(cv::Range(0, srcImgs[0].rows),
- FastNlMeansMultiDenoisingInvoker(
- srcImgs, imgToDenoiseIndex, temporalWindowSize,
- dst, templateWindowSize, searchWindowSize, &h[0]));
- else
- parallel_for_(cv::Range(0, srcImgs[0].rows),
- FastNlMeansMultiDenoisingInvoker(
- srcImgs, imgToDenoiseIndex, temporalWindowSize,
- dst, templateWindowSize, searchWindowSize, &h[0]));
+ case NORM_L1:
+ switch (depth) {
+ case CV_8U:
+ fastNlMeansDenoisingMulti_(srcImgs, dst,
+ imgToDenoiseIndex, temporalWindowSize,
+ h,
+ templateWindowSize, searchWindowSize);
+ break;
+ case CV_16U:
+ fastNlMeansDenoisingMulti_(srcImgs, dst,
+ imgToDenoiseIndex, temporalWindowSize,
+ h,
+ templateWindowSize, searchWindowSize);
+ break;
+ default:
+ CV_Error(Error::StsBadArg,
+ "Unsupported depth! Only CV_8U and CV_16U are supported for NORM_L1");
+ }
break;
default:
CV_Error(Error::StsBadArg,
- "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3 and CV_8UC4 are supported");
+ "Unsupported norm type! Only NORM_L2 and NORM_L1 are supported");
}
}