Added support for 4-component input for fastNlMeansDenoising[Multi][Abs]
authorErik Karlsson <erik.r.karlsson@gmail.com>
Tue, 3 Mar 2015 00:19:34 +0000 (01:19 +0100)
committerErik Karlsson <erik.r.karlsson@gmail.com>
Tue, 3 Mar 2015 00:19:34 +0000 (01:19 +0100)
modules/photo/src/denoising.cpp
modules/photo/src/fast_nlmeans_denoising_invoker.hpp
modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp
modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp

index 3fe1f2b..b41f83e 100644 (file)
@@ -78,9 +78,14 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h,
                     FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistSquared>(
                     src, dst, templateWindowSize, searchWindowSize, h));
             break;
+        case CV_8UC4:
+            parallel_for_(cv::Range(0, src.rows),
+                    FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared>(
+                    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<cv::Vec3b, int, unsigned, DistAbs>(
                     src, dst, templateWindowSize, searchWindowSize, h));
             break;
+        case CV_8UC4:
+            parallel_for_(cv::Range(0, src.rows),
+                FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs>(
+                    src, dst, templateWindowSize, searchWindowSize, h));
+            break;
         case CV_16U:
             parallel_for_(cv::Range(0, src.rows),
                 FastNlMeansDenoisingInvoker<ushort, int64, uint64, DistAbs>(
@@ -127,9 +137,14 @@ void cv::fastNlMeansDenoisingAbs( InputArray _src, OutputArray _dst, float h,
                 FastNlMeansDenoisingInvoker<cv::Vec<ushort, 3>, int64, uint64, DistAbs>(
                     src, dst, templateWindowSize, searchWindowSize, h));
             break;
+        case CV_16UC4:
+            parallel_for_(cv::Range(0, src.rows),
+                FastNlMeansDenoisingInvoker<cv::Vec<ushort, 4>, 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<cv::Vec4b, int, unsigned, DistSquared>(
+                    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<cv::Vec4b, int, unsigned, DistAbs>(
+                    srcImgs, imgToDenoiseIndex, temporalWindowSize,
+                    dst, templateWindowSize, searchWindowSize, h));
+            break;
         case CV_16U:
             parallel_for_(cv::Range(0, srcImgs[0].rows),
                 FastNlMeansMultiDenoisingInvoker<ushort, int64, uint64, DistAbs>(
@@ -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<cv::Vec<ushort, 4>, 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");
     }
 }
 
index 468fa82..01588b0 100644 (file)
@@ -227,7 +227,7 @@ void FastNlMeansDenoisingInvoker<T, IT, UIT, D>::operator() (const Range& range)
             }
 
             // calc weights
-            IT estimation[3], weights_sum = 0;
+            IT estimation[pixelInfo<T>::channels], weights_sum = 0;
             for (size_t channel_num = 0; channel_num < pixelInfo<T>::channels; channel_num++)
                 estimation[channel_num] = 0;
 
index d55d93c..d77ca3e 100644 (file)
@@ -110,6 +110,18 @@ class DistAbs
         }
     };
 
+    template <typename ET, typename IT> struct calcDist_<Vec<ET, 4>, IT>
+    {
+        static inline IT f(const Vec<ET, 4> a, const Vec<ET, 4> 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 <typename T, typename IT> static inline IT calcDist(const T a, const T b)
     {
@@ -172,6 +184,18 @@ class DistSquared
         }
     };
 
+    template <typename ET, typename IT> struct calcDist_<Vec<ET, 4>, IT>
+    {
+        static inline IT f(const Vec<ET, 4> a, const Vec<ET, 4> 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 <typename T, typename IT> struct calcUpDownDist_
     {
         static inline IT f(T a_up, T a_down, T b_up, T b_down)
@@ -254,6 +278,17 @@ template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 3>, IT>
     }
 };
 
+template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 4>, IT>
+{
+    static inline void f(IT* estimation, IT weight, Vec<ET, 4> p)
+    {
+        estimation[0] += weight * p[0];
+        estimation[1] += weight * p[1];
+        estimation[2] += weight * p[2];
+        estimation[3] += weight * p[3];
+    }
+};
+
 template <typename T, typename IT>
 static inline void incWithWeight(IT* estimation, IT weight, T p)
 {
@@ -291,6 +326,19 @@ template <typename ET, typename IT> struct saturateCastFromArray_<Vec<ET, 3>, IT
     }
 };
 
+template <typename ET, typename IT> struct saturateCastFromArray_<Vec<ET, 4>, IT>
+{
+    static inline Vec<ET, 4> f(IT* estimation)
+    {
+        Vec<ET, 4> res;
+        res[0] = saturate_cast<ET>(estimation[0]);
+        res[1] = saturate_cast<ET>(estimation[1]);
+        res[2] = saturate_cast<ET>(estimation[2]);
+        res[3] = saturate_cast<ET>(estimation[3]);
+        return res;
+    }
+};
+
 template <typename T, typename IT> static inline T saturateCastFromArray(IT* estimation)
 {
     return saturateCastFromArray_<T, IT>::f(estimation);
index 0a2bdd7..eb20786 100644 (file)
@@ -249,7 +249,7 @@ void FastNlMeansMultiDenoisingInvoker<T, IT, UIT, D>::operator() (const Range& r
             // calc weights
             IT weights_sum = 0;
 
-            IT estimation[3];
+            IT estimation[pixelInfo<T>::channels];
             for (size_t channel_num = 0; channel_num < pixelInfo<T>::channels; channel_num++)
                 estimation[channel_num] = 0;