Changed parameters of fastNlMeansDenoising[Multi][Abs] from float * to std::vector...
authorErik Karlsson <erik.r.karlsson@gmail.com>
Mon, 9 Mar 2015 14:52:16 +0000 (15:52 +0100)
committerErik Karlsson <erik.r.karlsson@gmail.com>
Mon, 9 Mar 2015 14:52:16 +0000 (15:52 +0100)
modules/photo/include/opencv2/photo.hpp
modules/photo/src/denoising.cpp
modules/photo/test/ocl/test_denoising.cpp

index 5e11333..d613c24 100644 (file)
@@ -149,10 +149,10 @@ Should be odd. Recommended value 7 pixels
 @param searchWindowSize Size in pixels of the window that is used to compute weighted average for
 given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater
 denoising time. Recommended value 21 pixels
-@param h Array of parameters regulating filter strength, one per
-channel. Big h value perfectly removes noise but also removes image
-details, smaller h value preserves details but also preserves some
-noise
+@param h Array of parameters regulating filter strength, either one
+parameter applied to all channels or one per channel in src. Big h value
+perfectly removes noise but also removes image details, smaller h
+value preserves details but also preserves some noise
 
 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
@@ -160,7 +160,7 @@ image in different colorspaces. Such approach is used in fastNlMeansDenoisingCol
 image to CIELAB colorspace and then separately denoise L and AB components with different h
 parameter.
  */
-CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, float *h,
+CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, std::vector<float> h,
         int templateWindowSize = 7, int searchWindowSize = 21);
 
 /** @brief Perform image denoising using Non-local Means Denoising
@@ -201,10 +201,10 @@ Should be odd. Recommended value 7 pixels
 @param searchWindowSize Size in pixels of the window that is used to compute weighted average for
 given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater
 denoising time. Recommended value 21 pixels
-@param h Array of parameters regulating filter strength, one per
-channel. Big h value perfectly removes noise but also removes image
-details, smaller h value preserves details but also preserves some
-noise
+@param h Array of parameters regulating filter strength, either one
+parameter applied to all channels or one per channel in src. Big h value
+perfectly removes noise but also removes image details, smaller h
+value preserves details but also preserves some noise
 
 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
@@ -212,7 +212,7 @@ image in different colorspaces. Such approach is used in fastNlMeansDenoisingCol
 image to CIELAB colorspace and then separately denoise L and AB components with different h
 parameter.
  */
-CV_EXPORTS_W void fastNlMeansDenoisingAbs( InputArray src, OutputArray dst, float *h,
+CV_EXPORTS_W void fastNlMeansDenoisingAbs( InputArray src, OutputArray dst, std::vector<float> h,
         int templateWindowSize = 7, int searchWindowSize = 21);
 
 /** @brief Modification of fastNlMeansDenoising function for colored images
@@ -283,14 +283,14 @@ Should be odd. Recommended value 7 pixels
 @param searchWindowSize Size in pixels of the window that is used to compute weighted average for
 given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater
 denoising time. Recommended value 21 pixels
-@param h Array of parameters regulating filter strength, one for each
-channel. Bigger h value perfectly removes noise but also removes image
-details, smaller h value preserves details but also preserves some
-noise
+@param h Array of parameters regulating filter strength, either one
+parameter applied to all channels or one per channel in src. Big h value
+perfectly removes noise but also removes image details, smaller h
+value preserves details but also preserves some noise
  */
 CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst,
         int imgToDenoiseIndex, int temporalWindowSize,
-        float *h , int templateWindowSize = 7, int searchWindowSize = 21);
+        std::vector<float> h , int templateWindowSize = 7, int searchWindowSize = 21);
 
 /** @brief Modification of fastNlMeansDenoising function for images
 sequence where consequtive images have been captured in small period
@@ -346,14 +346,14 @@ Should be odd. Recommended value 7 pixels
 @param searchWindowSize Size in pixels of the window that is used to compute weighted average for
 given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater
 denoising time. Recommended value 21 pixels
-@param h Array of parameters regulating filter strength, one for each
-channel. Bigger h value perfectly removes noise but also removes image
-details, smaller h value preserves details but also preserves some
-noise
+@param h Array of parameters regulating filter strength, either one
+parameter applied to all channels or one per channel in src. Big h value
+perfectly removes noise but also removes image details, smaller h
+value preserves details but also preserves some noise
  */
 CV_EXPORTS_W void fastNlMeansDenoisingMultiAbs( InputArrayOfArrays srcImgs, OutputArray dst,
         int imgToDenoiseIndex, int temporalWindowSize,
-        float *h, int templateWindowSize = 7, int searchWindowSize = 21);
+        std::vector<float> h, int templateWindowSize = 7, int searchWindowSize = 21);
 
 /** @brief Modification of fastNlMeansDenoisingMulti function for colored images sequences
 
index 9f63254..7251b64 100644 (file)
 void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h,
                                int templateWindowSize, int searchWindowSize)
 {
-    Size src_size = _src.size();
-    CV_OCL_RUN(_src.dims() <= 2 && (_src.isUMat() || _dst.isUMat()) &&
-               src_size.width > 5 && src_size.height > 5, // low accuracy on small sizes
-               ocl_fastNlMeansDenoising(_src, _dst, &h, 1,
-                                        templateWindowSize, searchWindowSize, false))
-
-    Mat src = _src.getMat();
-    _dst.create(src_size, src.type());
-    Mat dst = _dst.getMat();
-
-#ifdef HAVE_TEGRA_OPTIMIZATION
-    if(tegra::fastNlMeansDenoising(src, dst, h, templateWindowSize, searchWindowSize))
-        return;
-#endif
-
-    switch (src.type()) {
-        case CV_8U:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<uchar, int, unsigned, DistSquared, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC2:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec2b, int, unsigned, DistSquared, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC3:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistSquared, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC4:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        default:
-            CV_Error(Error::StsBadArg,
-                "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3 and CV_8UC4 are supported");
-    }
+    fastNlMeansDenoising(_src, _dst, std::vector<float>(1, h),
+                         templateWindowSize, searchWindowSize);
 }
 
-void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float *h,
+void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, std::vector<float> h,
                                int templateWindowSize, int searchWindowSize)
 {
+    int hn = h.size();
+    CV_Assert(hn == 1 || hn == CV_MAT_CN(_src.type()));
+
     Size src_size = _src.size();
     CV_OCL_RUN(_src.dims() <= 2 && (_src.isUMat() || _dst.isUMat()) &&
                src_size.width > 5 && src_size.height > 5, // low accuracy on small sizes
-               ocl_fastNlMeansDenoising(_src, _dst, h, CV_MAT_CN(_src.type()),
+               ocl_fastNlMeansDenoising(_src, _dst, &h[0], hn,
                                         templateWindowSize, searchWindowSize, false))
 
     Mat src = _src.getMat();
@@ -111,23 +76,38 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float *h,
     switch (src.type()) {
         case CV_8U:
             parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<uchar, int, unsigned, DistSquared, int>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+                          FastNlMeansDenoisingInvoker<uchar, int, unsigned, DistSquared, int>(
+                              src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC2:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec2b, int, unsigned, DistSquared, Vec2i>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec2b, int, unsigned, DistSquared, int>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec2b, int, unsigned, DistSquared, Vec2i>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC3:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistSquared, Vec3i>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistSquared, int>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistSquared, Vec3i>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC4:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared, Vec4i>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared, int>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared, Vec4i>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         default:
             CV_Error(Error::StsBadArg,
@@ -138,70 +118,20 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float *h,
 void cv::fastNlMeansDenoisingAbs( InputArray _src, OutputArray _dst, float h,
                                   int  templateWindowSize, int searchWindowSize)
 {
-    Size src_size = _src.size();
-    CV_OCL_RUN(_src.dims() <= 2 && (_src.isUMat() || _dst.isUMat()) &&
-               src_size.width > 5 && src_size.height > 5, // low accuracy on small sizes
-               ocl_fastNlMeansDenoising(_src, _dst, &h, 1,
-                                        templateWindowSize, searchWindowSize, true))
-
-    Mat src = _src.getMat();
-    _dst.create(src_size, src.type());
-    Mat dst = _dst.getMat();
-
-    switch (src.type()) {
-        case CV_8U:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<uchar, int, unsigned, DistAbs, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC2:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec2b, int, unsigned, DistAbs, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC3:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistAbs, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC4:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_16U:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<ushort, int64, uint64, DistAbs, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_16UC2:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec<ushort, 2>, int64, uint64, DistAbs, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_16UC3:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec<ushort, 3>, int64, uint64, DistAbs, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_16UC4:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec<ushort, 4>, int64, uint64, DistAbs, int>(
-                    src, dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        default:
-            CV_Error(Error::StsBadArg,
-                "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3, CV_8UC4, CV_16U, CV_16UC2, CV_16UC3 and CV_16UC4 are supported");
-    }
+    fastNlMeansDenoisingAbs(_src, _dst, std::vector<float>(1, h),
+                            templateWindowSize, searchWindowSize);
 }
 
-void cv::fastNlMeansDenoisingAbs( InputArray _src, OutputArray _dst, float *h,
+void cv::fastNlMeansDenoisingAbs( InputArray _src, OutputArray _dst, std::vector<float> h,
                                   int  templateWindowSize, int searchWindowSize)
 {
+    int hn = h.size();
+    CV_Assert(hn == 1 || hn == CV_MAT_CN(_src.type()));
+
     Size src_size = _src.size();
     CV_OCL_RUN(_src.dims() <= 2 && (_src.isUMat() || _dst.isUMat()) &&
                src_size.width > 5 && src_size.height > 5, // low accuracy on small sizes
-               ocl_fastNlMeansDenoising(_src, _dst, h, CV_MAT_CN(_src.type()),
+               ocl_fastNlMeansDenoising(_src, _dst, &h[0], hn,
                                         templateWindowSize, searchWindowSize, true))
 
     Mat src = _src.getMat();
@@ -211,43 +141,73 @@ void cv::fastNlMeansDenoisingAbs( InputArray _src, OutputArray _dst, float *h,
     switch (src.type()) {
         case CV_8U:
             parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<uchar, int, unsigned, DistAbs, int>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+                          FastNlMeansDenoisingInvoker<uchar, int, unsigned, DistAbs, int>(
+                              src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC2:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec2b, int, unsigned, DistAbs, Vec2i>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec2b, int, unsigned, DistAbs, int>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec2b, int, unsigned, DistAbs, Vec2i>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC3:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistAbs, Vec3i>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistAbs, int>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistAbs, Vec3i>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC4:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs, Vec4i>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs, int>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs, Vec4i>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_16U:
             parallel_for_(cv::Range(0, src.rows),
                     FastNlMeansDenoisingInvoker<ushort, int64, uint64, DistAbs, int>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+                    src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_16UC2:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec<ushort, 2>, int64, uint64, DistAbs, Vec2i>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec<ushort, 2>, int64, uint64, DistAbs, int>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec<ushort, 2>, int64, uint64, DistAbs, Vec2i>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_16UC3:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec<ushort, 3>, int64, uint64, DistAbs, Vec3i>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec<ushort, 3>, int64, uint64, DistAbs, int>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec<ushort, 3>, int64, uint64, DistAbs, Vec3i>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_16UC4:
-            parallel_for_(cv::Range(0, src.rows),
-                    FastNlMeansDenoisingInvoker<cv::Vec<ushort, 4>, int64, uint64, DistAbs, Vec4i>(
-                    src, dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec<ushort, 4>, int64, uint64, DistAbs, int>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, src.rows),
+                              FastNlMeansDenoisingInvoker<cv::Vec<ushort, 4>, int64, uint64, DistAbs, Vec4i>(
+                                  src, dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         default:
             CV_Error(Error::StsBadArg,
@@ -332,51 +292,14 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds
                                     int imgToDenoiseIndex, int temporalWindowSize,
                                     float h, int templateWindowSize, int searchWindowSize)
 {
-    std::vector<Mat> srcImgs;
-    _srcImgs.getMatVector(srcImgs);
-
-    fastNlMeansDenoisingMultiCheckPreconditions(
-        srcImgs, imgToDenoiseIndex,
-        temporalWindowSize, templateWindowSize, searchWindowSize);
-
-    _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<uchar, int, unsigned, DistSquared, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC2:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec2b, int, unsigned, DistSquared, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC3:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec3b, int, unsigned, DistSquared, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC4:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        default:
-            CV_Error(Error::StsBadArg,
-                "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3 and CV_8UC4 are supported");
-    }
+    fastNlMeansDenoisingMulti(_srcImgs, _dst, imgToDenoiseIndex, temporalWindowSize,
+                              std::vector<float>(1, h), templateWindowSize, searchWindowSize);
 }
 
 void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
                                     int imgToDenoiseIndex, int temporalWindowSize,
-                                    float *h, int templateWindowSize, int searchWindowSize)
+                                    std::vector<float> h,
+                                    int templateWindowSize, int searchWindowSize)
 {
     std::vector<Mat> srcImgs;
     _srcImgs.getMatVector(srcImgs);
@@ -385,6 +308,9 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds
         srcImgs, imgToDenoiseIndex,
         temporalWindowSize, templateWindowSize, searchWindowSize);
 
+    int hn = h.size();
+    CV_Assert(hn == 1 || hn == CV_MAT_CN(srcImgs[0].type()));
+
     _dst.create(srcImgs[0].size(), srcImgs[0].type());
     Mat dst = _dst.getMat();
 
@@ -392,27 +318,45 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds
     {
         case CV_8U:
             parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<uchar, int, unsigned, DistSquared, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+                          FastNlMeansMultiDenoisingInvoker<uchar, int, unsigned, DistSquared, int>(
+                              srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                              dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC2:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec2b, int, unsigned, DistSquared, Vec2i>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec2b, int, unsigned, DistSquared, int>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec2b, int, unsigned, DistSquared, Vec2i>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC3:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec3b, int, unsigned, DistSquared, Vec3i>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec3b, int, unsigned, DistSquared, int>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec3b, int, unsigned, DistSquared, Vec3i>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC4:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared, Vec4i>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared, int>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared, Vec4i>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         default:
             CV_Error(Error::StsBadArg,
@@ -424,75 +368,14 @@ void cv::fastNlMeansDenoisingMultiAbs( InputArrayOfArrays _srcImgs, OutputArray
                                        int imgToDenoiseIndex, int temporalWindowSize,
                                        float h, int templateWindowSize, int searchWindowSize)
 {
-    std::vector<Mat> srcImgs;
-    _srcImgs.getMatVector(srcImgs);
-
-    fastNlMeansDenoisingMultiCheckPreconditions(
-        srcImgs, imgToDenoiseIndex,
-        temporalWindowSize, templateWindowSize, searchWindowSize);
-
-    _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<uchar, int, unsigned, DistAbs, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC2:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec2b, int, unsigned, DistAbs, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC3:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec3b, int, unsigned, DistAbs, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_8UC4:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_16U:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<ushort, int64, uint64, DistAbs, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_16UC2:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 2>, int64, uint64, DistAbs, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_16UC3:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 3>, int64, uint64, DistAbs, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        case CV_16UC4:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 4>, int64, uint64, DistAbs, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, &h));
-            break;
-        default:
-            CV_Error(Error::StsBadArg,
-                "Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3, CV_8UC4, CV_16U, CV_16UC2, CV_16UC3 and CV_16UC4 are supported");
-    }
+    fastNlMeansDenoisingMulti(_srcImgs, _dst, imgToDenoiseIndex, temporalWindowSize,
+                              std::vector<float>(1, h), templateWindowSize, searchWindowSize);
 }
 
 void cv::fastNlMeansDenoisingMultiAbs( InputArrayOfArrays _srcImgs, OutputArray _dst,
                                        int imgToDenoiseIndex, int temporalWindowSize,
-                                       float *h, int templateWindowSize, int searchWindowSize)
+                                       std::vector<float> h,
+                                       int templateWindowSize, int searchWindowSize)
 {
     std::vector<Mat> srcImgs;
     _srcImgs.getMatVector(srcImgs);
@@ -501,6 +384,9 @@ void cv::fastNlMeansDenoisingMultiAbs( InputArrayOfArrays _srcImgs, OutputArray
         srcImgs, imgToDenoiseIndex,
         temporalWindowSize, templateWindowSize, searchWindowSize);
 
+    int hn = h.size();
+    CV_Assert(hn == 1 || hn == CV_MAT_CN(srcImgs[0].type()));
+
     _dst.create(srcImgs[0].size(), srcImgs[0].type());
     Mat dst = _dst.getMat();
 
@@ -508,51 +394,87 @@ void cv::fastNlMeansDenoisingMultiAbs( InputArrayOfArrays _srcImgs, OutputArray
     {
         case CV_8U:
             parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<uchar, int, unsigned, DistAbs, int>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+                          FastNlMeansMultiDenoisingInvoker<uchar, int, unsigned, DistAbs, int>(
+                              srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                              dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC2:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec2b, int, unsigned, DistAbs, Vec2i>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec2b, int, unsigned, DistAbs, int>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec2b, int, unsigned, DistAbs, Vec2i>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC3:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec3b, int, unsigned, DistAbs, Vec3i>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec3b, int, unsigned, DistAbs, int>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec3b, int, unsigned, DistAbs, Vec3i>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_8UC4:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs, Vec4i>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs, int>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs, Vec4i>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_16U:
             parallel_for_(cv::Range(0, srcImgs[0].rows),
                 FastNlMeansMultiDenoisingInvoker<ushort, int64, uint64, DistAbs, int>(
                     srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+                    dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_16UC2:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 2>, int64, uint64, DistAbs, Vec2i>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 2>, int64, uint64, DistAbs, int>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 2>, int64, uint64, DistAbs, Vec2i>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_16UC3:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 3>, int64, uint64, DistAbs, Vec3i>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 3>, int64, uint64, DistAbs, int>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 3>, int64, uint64, DistAbs, Vec3i>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         case CV_16UC4:
-            parallel_for_(cv::Range(0, srcImgs[0].rows),
-                FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 4>, int64, uint64, DistAbs, Vec4i>(
-                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
-                    dst, templateWindowSize, searchWindowSize, h));
+            if (hn == 1)
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 4>, int64, uint64, DistAbs, int>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
+            else
+                parallel_for_(cv::Range(0, srcImgs[0].rows),
+                              FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 4>, int64, uint64, DistAbs, Vec4i>(
+                                  srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                                  dst, templateWindowSize, searchWindowSize, &h[0]));
             break;
         default:
             CV_Error(Error::StsBadArg,
index 3b6998f..360c162 100644 (file)
@@ -16,7 +16,7 @@ namespace ocl {
 PARAM_TEST_CASE(FastNlMeansDenoisingTestBase, Channels, bool, bool)
 {
     int cn, templateWindowSize, searchWindowSize;
-    float h[4];
+    std::vector<float> h;
     bool use_roi, use_image;
 
     TEST_DECLARE_INPUT_PARAMETER(src);
@@ -31,7 +31,7 @@ PARAM_TEST_CASE(FastNlMeansDenoisingTestBase, Channels, bool, bool)
         templateWindowSize = 7;
         searchWindowSize = 21;
 
-        ASSERT_TRUE(cn > 0 && cn <= 4);
+        h.resize(cn);
         for (int i=0; i<cn; i++)
             h[i] = 3.0f + 0.5f*i;
     }
@@ -51,6 +51,7 @@ PARAM_TEST_CASE(FastNlMeansDenoisingTestBase, Channels, bool, bool)
         Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
         randomSubMat(src, src_roi, roiSize, srcBorder, type, 0, 255);
         if (use_image) {
+            ASSERT_TRUE(cn > 0 && cn <= 4);
             if (cn == 2) {
                 int from_to[] = { 0,0, 1,1 };
                 src_roi.create(roiSize, type);