Change denoising strength parameter from int to float
authorAndrey Kamaev <andrey.kamaev@itseez.com>
Thu, 20 Sep 2012 13:27:48 +0000 (17:27 +0400)
committerAndrey Kamaev <andrey.kamaev@itseez.com>
Thu, 20 Sep 2012 13:27:48 +0000 (17:27 +0400)
modules/photo/include/opencv2/photo/photo.hpp
modules/photo/src/denoising.cpp
modules/photo/src/fast_nlmeans_denoising_invoker.hpp
modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp

index 07b27ab..6697377 100644 (file)
@@ -68,20 +68,20 @@ CV_EXPORTS_W void inpaint( InputArray src, InputArray inpaintMask,
                            OutputArray dst, double inpaintRadius, int flags );
 
 
-CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, int h = 3,
+CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, float h = 3,
                                         int templateWindowSize = 7, int searchWindowSize = 21);
 
 CV_EXPORTS_W void fastNlMeansDenoisingColored( InputArray src, OutputArray dst,
-                                               int h = 3, int hColor = 3,
+                                               float h = 3, float hColor = 3,
                                                int templateWindowSize = 7, int searchWindowSize = 21);
 
 CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst,
                                              int imgToDenoiseIndex, int temporalWindowSize,
-                                             int h = 3, int templateWindowSize = 7, int searchWindowSize = 21);
+                                             float h = 3, int templateWindowSize = 7, int searchWindowSize = 21);
 
 CV_EXPORTS_W void fastNlMeansDenoisingColoredMulti( InputArrayOfArrays srcImgs, OutputArray dst,
                                                     int imgToDenoiseIndex, int temporalWindowSize,
-                                                    int h = 3, int hColor = 3,
+                                                    float h = 3, float hColor = 3,
                                                     int templateWindowSize = 7, int searchWindowSize = 21);
 
 }
index f71c37c..770df13 100644 (file)
@@ -45,7 +45,7 @@
 #include "fast_nlmeans_denoising_invoker.hpp"
 #include "fast_nlmeans_multi_denoising_invoker.hpp"
 
-void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, int h,
+void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h,
                                int templateWindowSize, int searchWindowSize)
 {
     Mat src = _src.getMat();
@@ -75,7 +75,7 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, int h,
 }
 
 void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst,
-                                      int h, int hForColorComponents,
+                                      float h, float hForColorComponents,
                                       int templateWindowSize, int searchWindowSize)
 {
     Mat src = _src.getMat();
@@ -140,7 +140,7 @@ static void fastNlMeansDenoisingMultiCheckPreconditions(
 
 void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
                                     int imgToDenoiseIndex, int temporalWindowSize,
-                                    int h, int templateWindowSize, int searchWindowSize)
+                                    float h, int templateWindowSize, int searchWindowSize)
 {
     vector<Mat> srcImgs;
     _srcImgs.getMatVector(srcImgs);
@@ -179,7 +179,7 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds
 
 void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
                                            int imgToDenoiseIndex, int temporalWindowSize,
-                                           int h, int hForColorComponents,
+                                           float h, float hForColorComponents,
                                            int templateWindowSize, int searchWindowSize)
 {
     vector<Mat> srcImgs;
index 5f7d1fe..1dcb6b3 100644 (file)
@@ -58,7 +58,7 @@ template <typename T>
 struct FastNlMeansDenoisingInvoker {
     public:
         FastNlMeansDenoisingInvoker(const Mat& src, Mat& dst,
-            int template_window_size, int search_window_size, const double h);
+            int template_window_size, int search_window_size, const float h);
 
         void operator() (const BlockedRange& range) const;
 
@@ -109,7 +109,7 @@ FastNlMeansDenoisingInvoker<T>::FastNlMeansDenoisingInvoker(
     cv::Mat& dst,
     int template_window_size,
     int search_window_size,
-    const double h) : src_(src), dst_(dst)
+    const float h) : src_(src), dst_(dst)
 {
     CV_Assert(src.channels() == sizeof(T)); //T is Vec1b or Vec2b or Vec3b
 
@@ -133,21 +133,21 @@ FastNlMeansDenoisingInvoker<T>::FastNlMeansDenoisingInvoker(
     almost_template_window_size_sq_bin_shift_ = getNearestPowerOf2(template_window_size_sq);
     double almost_dist2actual_dist_multiplier = ((double)(1 << almost_template_window_size_sq_bin_shift_)) / template_window_size_sq;
 
-    int max_dist = 256 * 256 * src_.channels();
+    int max_dist = 255 * 255 * sizeof(T);
     int almost_max_dist = (int) (max_dist / almost_dist2actual_dist_multiplier + 1);
     almost_dist2weight_.resize(almost_max_dist);
 
     const double WEIGHT_THRESHOLD = 0.001;
     for (int almost_dist = 0; almost_dist < almost_max_dist; almost_dist++) {
         double dist = almost_dist * almost_dist2actual_dist_multiplier;
-        int weight = cvRound(fixed_point_mult_ * std::exp(- dist / (h * h * src_.channels())));
+        int weight = cvRound(fixed_point_mult_ * std::exp(-dist / (h * h * sizeof(T))));
 
-        if (weight < WEIGHT_THRESHOLD * fixed_point_mult_) {
+        if (weight < WEIGHT_THRESHOLD * fixed_point_mult_)
             weight = 0;
-        }
 
         almost_dist2weight_[almost_dist] = weight;
     }
+    CV_Assert(almost_dist2weight_[0] == fixed_point_mult_);
     // additional optimization init end
 
     if (dst_.empty()) {
@@ -237,7 +237,7 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const BlockedRange& range) cons
             int weights_sum = 0;
 
             int estimation[3];
-            for (int channel_num = 0; channel_num < src_.channels(); channel_num++) {
+            for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++) {
                 estimation[channel_num] = 0;
             }
 
@@ -256,15 +256,10 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const BlockedRange& range) cons
                 }
             }
 
-            if (weights_sum > 0) {
-                for (int channel_num = 0; channel_num < src_.channels(); channel_num++)
-                    estimation[channel_num] = (estimation[channel_num] + weights_sum/2) / weights_sum;
-
-                dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation);
+            for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++)
+                estimation[channel_num] = (estimation[channel_num] + weights_sum/2) / weights_sum;
 
-            } else { // weights_sum == 0
-                dst_.at<T>(i,j) = src_.at<T>(i,j);
-            }
+            dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation);
         }
     }
 }
index 4151f32..870760b 100644 (file)
@@ -59,18 +59,15 @@ struct FastNlMeansMultiDenoisingInvoker {
     public:
         FastNlMeansMultiDenoisingInvoker(
             const std::vector<Mat>& srcImgs, int imgToDenoiseIndex, int temporalWindowSize,
-            Mat& dst, int template_window_size, int search_window_size, const double h);
+            Mat& dst, int template_window_size, int search_window_size, const float h);
 
         void operator() (const BlockedRange& range) const;
 
-        void operator= (const FastNlMeansMultiDenoisingInvoker&) {
-            CV_Error(CV_StsNotImplemented, "Assigment operator is not implemented");
-        }
-
     private:
+        void operator= (const FastNlMeansMultiDenoisingInvoker&);
+
         int rows_;
         int cols_;
-        int channels_count_;
 
         Mat& dst_;
 
@@ -113,14 +110,13 @@ FastNlMeansMultiDenoisingInvoker<T>::FastNlMeansMultiDenoisingInvoker(
     cv::Mat& dst,
     int template_window_size,
     int search_window_size,
-    const double h) : dst_(dst), extended_srcs_(srcImgs.size())
+    const float h) : dst_(dst), extended_srcs_(srcImgs.size())
 {
     CV_Assert(srcImgs.size() > 0);
-    CV_Assert(srcImgs[0].channels() <= 3);
+    CV_Assert(srcImgs[0].channels() == sizeof(T));
 
     rows_ = srcImgs[0].rows;
     cols_ = srcImgs[0].cols;
-    channels_count_ = srcImgs[0].channels();
 
     template_window_half_size_ = template_window_size / 2;
     search_window_half_size_ = search_window_size / 2;
@@ -155,14 +151,14 @@ FastNlMeansMultiDenoisingInvoker<T>::FastNlMeansMultiDenoisingInvoker(
     double almost_dist2actual_dist_multiplier =
         ((double) almost_template_window_size_sq) / template_window_size_sq;
 
-    int max_dist = 256 * 256 * channels_count_;
+    int max_dist = 255 * 255 * sizeof(T);
     int almost_max_dist = (int) (max_dist / almost_dist2actual_dist_multiplier + 1);
     almost_dist2weight.resize(almost_max_dist);
 
     const double WEIGHT_THRESHOLD = 0.001;
     for (int almost_dist = 0; almost_dist < almost_max_dist; almost_dist++) {
         double dist = almost_dist * almost_dist2actual_dist_multiplier;
-        int weight = cvRound(fixed_point_mult_ * std::exp(- dist / (h * h * channels_count_)));
+        int weight = cvRound(fixed_point_mult_ * std::exp(-dist / (h * h * sizeof(T))));
 
         if (weight < WEIGHT_THRESHOLD * fixed_point_mult_) {
             weight = 0;
@@ -170,6 +166,7 @@ FastNlMeansMultiDenoisingInvoker<T>::FastNlMeansMultiDenoisingInvoker(
 
         almost_dist2weight[almost_dist] = weight;
     }
+    CV_Assert(almost_dist2weight[0] == fixed_point_mult_);
     // additional optimization init end
 
     if (dst_.empty()) {
@@ -266,7 +263,7 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
             int weights_sum = 0;
 
             int estimation[3];
-            for (int channel_num = 0; channel_num < channels_count_; channel_num++) {
+            for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++) {
                 estimation[channel_num] = 0;
             }
             for (int d = 0; d < temporal_window_size_; d++) {
@@ -289,16 +286,11 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
                 }
             }
 
-            if (weights_sum > 0) {
-                for (int channel_num = 0; channel_num < channels_count_; channel_num++)
-                    estimation[channel_num] = (estimation[channel_num] + weights_sum / 2) / weights_sum;
+            for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++)
+                estimation[channel_num] = (estimation[channel_num] + weights_sum / 2) / weights_sum;
 
-                dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation);
+            dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation);
 
-            } else { // weights_sum == 0
-                const Mat& esrc = extended_srcs_[temporal_window_half_size_];
-                dst_.at<T>(i,j) = esrc.at<T>(i,j);
-            }
         }
     }
 }