From 1e82a67cc4d082abe9437dd163314a543bd90232 Mon Sep 17 00:00:00 2001 From: Erik Karlsson Date: Fri, 6 Mar 2015 14:28:43 +0100 Subject: [PATCH] Additional refactoring --- .../photo/src/fast_nlmeans_denoising_invoker.hpp | 17 ++-- .../src/fast_nlmeans_denoising_invoker_commons.hpp | 91 +++++++++++++--------- .../src/fast_nlmeans_multi_denoising_invoker.hpp | 17 ++-- 3 files changed, 71 insertions(+), 54 deletions(-) diff --git a/modules/photo/src/fast_nlmeans_denoising_invoker.hpp b/modules/photo/src/fast_nlmeans_denoising_invoker.hpp index 9dea2a0..ff35550 100644 --- a/modules/photo/src/fast_nlmeans_denoising_invoker.hpp +++ b/modules/photo/src/fast_nlmeans_denoising_invoker.hpp @@ -75,7 +75,7 @@ private: int template_window_half_size_; int search_window_half_size_; - int fixed_point_mult_; + typename pixelInfo::sampleType fixed_point_mult_; int almost_template_window_size_sq_bin_shift_; std::vector almost_dist2weight_; @@ -120,7 +120,7 @@ FastNlMeansDenoisingInvoker::FastNlMeansDenoisingInvoker( const IT max_estimate_sum_value = (IT)search_window_size_ * (IT)search_window_size_ * (IT)pixelInfo::sampleMax(); fixed_point_mult_ = (int)std::min(std::numeric_limits::max() / max_estimate_sum_value, - std::numeric_limits::max()); + pixelInfo::sampleMax()); // precalc weight for every possible l2 dist between blocks // additional optimization of precalced weights to replace division(averaging) by binary shift @@ -223,9 +223,11 @@ void FastNlMeansDenoisingInvoker::operator() (const Range& ra } // calc weights - IT estimation[pixelInfo::channels], weights_sum[pixelInfo::channels]; + IT estimation[pixelInfo::channels], weights_sum[pixelInfo::channels]; for (size_t channel_num = 0; channel_num < pixelInfo::channels; channel_num++) - estimation[channel_num] = weights_sum[channel_num] = 0; + estimation[channel_num] = 0; + for (size_t channel_num = 0; channel_num < pixelInfo::channels; channel_num++) + weights_sum[channel_num] = 0; for (int y = 0; y < search_window_size_; y++) { @@ -240,11 +242,8 @@ void FastNlMeansDenoisingInvoker::operator() (const Range& ra } } - for (size_t channel_num = 0; channel_num < pixelInfo::channels; channel_num++) - estimation[channel_num] = - (static_cast(estimation[channel_num]) + weights_sum[channel_num]/2) / - weights_sum[channel_num]; - + divByWeightsSum::channels, pixelInfo::channels>(estimation, + weights_sum); dst_.at(i,j) = saturateCastFromArray(estimation); } } diff --git a/modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp b/modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp index 53a6f5e..df8e470 100644 --- a/modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp +++ b/modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp @@ -122,11 +122,11 @@ class DistAbs } }; - static const double WEIGHT_THRESHOLD = 0.001; template struct calcWeight_ { - static inline WT f(double dist, const float *h, int fixed_point_mult) + static inline WT f(double dist, const float *h, WT fixed_point_mult) { + static const double WEIGHT_THRESHOLD = 0.001; WT weight = (WT)round(fixed_point_mult * std::exp(-dist*dist / (h[0]*h[0] * pixelInfo::channels))); if (weight < WEIGHT_THRESHOLD * fixed_point_mult) @@ -137,17 +137,11 @@ class DistAbs template struct calcWeight_ > { - static inline Vec f(double dist, const float *h, int fixed_point_mult) + static inline Vec f(double dist, const float *h, ET fixed_point_mult) { Vec res; for (int i=0; i::channels))); - if (weight < WEIGHT_THRESHOLD * fixed_point_mult) - weight = 0; - res[i] = weight; - } + res[i] = calcWeight(dist, &h[i], fixed_point_mult); return res; } }; @@ -247,11 +241,11 @@ class DistSquared } }; - static const double WEIGHT_THRESHOLD = 0.001; template struct calcWeight_ { static inline WT f(double dist, const float *h, int fixed_point_mult) { + static const double WEIGHT_THRESHOLD = 0.001; WT weight = (WT)round(fixed_point_mult * std::exp(-dist / (h[0]*h[0] * pixelInfo::channels))); if (weight < WEIGHT_THRESHOLD * fixed_point_mult) @@ -266,13 +260,7 @@ class DistSquared { Vec res; for (int i=0; i::channels))); - if (weight < WEIGHT_THRESHOLD * fixed_point_mult) - weight = 0; - res[i] = weight; - } + res[i] = calcWeight(dist, &h[i], fixed_point_mult); return res; } }; @@ -320,48 +308,42 @@ template struct incWithWeight_ } }; -template struct incWithWeight_, IT, int> +template struct incWithWeight_, IT, WT> { - static inline void f(IT* estimation, IT* weights_sum, int weight, Vec p) + static inline void f(IT* estimation, IT* weights_sum, WT weight, Vec p) { estimation[0] += (IT)weight * p[0]; estimation[1] += (IT)weight * p[1]; weights_sum[0] += (IT)weight; - weights_sum[1] += (IT)weight; } }; -template struct incWithWeight_, IT, int> +template struct incWithWeight_, IT, WT> { - static inline void f(IT* estimation, IT* weights_sum, int weight, Vec p) + static inline void f(IT* estimation, IT* weights_sum, WT weight, Vec p) { estimation[0] += (IT)weight * p[0]; estimation[1] += (IT)weight * p[1]; estimation[2] += (IT)weight * p[2]; weights_sum[0] += (IT)weight; - weights_sum[1] += (IT)weight; - weights_sum[2] += (IT)weight; } }; -template struct incWithWeight_, IT, int> +template struct incWithWeight_, IT, WT> { - static inline void f(IT* estimation, IT* weights_sum, int weight, Vec p) + static inline void f(IT* estimation, IT* weights_sum, WT weight, Vec p) { estimation[0] += (IT)weight * p[0]; estimation[1] += (IT)weight * p[1]; estimation[2] += (IT)weight * p[2]; estimation[3] += (IT)weight * p[3]; weights_sum[0] += (IT)weight; - weights_sum[1] += (IT)weight; - weights_sum[2] += (IT)weight; - weights_sum[3] += (IT)weight; } }; -template struct incWithWeight_, IT, Vec > +template struct incWithWeight_, IT, Vec > { - static inline void f(IT* estimation, IT* weights_sum, Vec weight, Vec p) + static inline void f(IT* estimation, IT* weights_sum, Vec weight, Vec p) { estimation[0] += (IT)weight[0] * p[0]; estimation[1] += (IT)weight[1] * p[1]; @@ -370,9 +352,9 @@ template struct incWithWeight_, IT, Vec struct incWithWeight_, IT, Vec > +template struct incWithWeight_, IT, Vec > { - static inline void f(IT* estimation, IT* weights_sum, Vec weight, Vec p) + static inline void f(IT* estimation, IT* weights_sum, Vec weight, Vec p) { estimation[0] += (IT)weight[0] * p[0]; estimation[1] += (IT)weight[1] * p[1]; @@ -383,9 +365,9 @@ template struct incWithWeight_, IT, Vec struct incWithWeight_, IT, Vec > +template struct incWithWeight_, IT, Vec > { - static inline void f(IT* estimation, IT* weights_sum, Vec weight, Vec p) + static inline void f(IT* estimation, IT* weights_sum, Vec weight, Vec p) { estimation[0] += (IT)weight[0] * p[0]; estimation[1] += (IT)weight[1] * p[1]; @@ -404,6 +386,43 @@ static inline void incWithWeight(IT* estimation, IT* weights_sum, IT weight, T p return incWithWeight_::f(estimation, weights_sum, weight, p); } +template struct divByWeightsSum_ +{ + static inline void f(IT* estimation, IT* weights_sum); +}; + +template struct divByWeightsSum_ +{ + static inline void f(IT* estimation, IT* weights_sum) + { + estimation[0] = (static_cast(estimation[0]) + weights_sum[0]/2) / weights_sum[0]; + } +}; + +template struct divByWeightsSum_ +{ + static inline void f(IT* estimation, IT* weights_sum) + { + for (size_t i = 0; i < n; i++) + estimation[i] = (static_cast(estimation[i]) + weights_sum[0]/2) / weights_sum[0]; + } +}; + +template struct divByWeightsSum_ +{ + static inline void f(IT* estimation, IT* weights_sum) + { + for (size_t i = 0; i < n; i++) + estimation[i] = (static_cast(estimation[i]) + weights_sum[i]/2) / weights_sum[i]; + } +}; + +template +static inline void divByWeightsSum(IT* estimation, IT* weights_sum) +{ + return divByWeightsSum_::f(estimation, weights_sum); +} + template struct saturateCastFromArray_ { static inline T f(IT* estimation) diff --git a/modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp b/modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp index 489ee67..cd3833a 100644 --- a/modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp +++ b/modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp @@ -81,7 +81,7 @@ private: int search_window_half_size_; int temporal_window_half_size_; - int fixed_point_mult_; + typename pixelInfo::sampleType fixed_point_mult_; int almost_template_window_size_sq_bin_shift; std::vector almost_dist2weight; @@ -128,7 +128,7 @@ FastNlMeansMultiDenoisingInvoker::FastNlMeansMultiDenoisingIn const IT max_estimate_sum_value = (IT)temporal_window_size_ * (IT)search_window_size_ * (IT)search_window_size_ * (IT)pixelInfo::sampleMax(); fixed_point_mult_ = (int)std::min(std::numeric_limits::max() / max_estimate_sum_value, - std::numeric_limits::max()); + pixelInfo::sampleMax()); // precalc weight for every possible l2 dist between blocks // additional optimization of precalced weights to replace division(averaging) by binary shift @@ -243,9 +243,11 @@ void FastNlMeansMultiDenoisingInvoker::operator() (const Rang } // calc weights - IT estimation[pixelInfo::channels], weights_sum[pixelInfo::channels]; + IT estimation[pixelInfo::channels], weights_sum[pixelInfo::channels]; for (size_t channel_num = 0; channel_num < pixelInfo::channels; channel_num++) - estimation[channel_num] = weights_sum[channel_num] = 0; + estimation[channel_num] = 0; + for (size_t channel_num = 0; channel_num < pixelInfo::channels; channel_num++) + weights_sum[channel_num] = 0; for (int d = 0; d < temporal_window_size_; d++) { @@ -267,11 +269,8 @@ void FastNlMeansMultiDenoisingInvoker::operator() (const Rang } } - for (size_t channel_num = 0; channel_num < pixelInfo::channels; channel_num++) - estimation[channel_num] = - (static_cast(estimation[channel_num]) + weights_sum[channel_num] / 2) / - weights_sum[channel_num]; - + divByWeightsSum::channels, pixelInfo::channels>(estimation, + weights_sum); dst_.at(i,j) = saturateCastFromArray(estimation); } } -- 2.7.4