Additional refactoring

This commit is contained in:
Erik Karlsson 2015-03-06 14:28:43 +01:00
parent c41efe4e30
commit 1e82a67cc4
3 changed files with 71 additions and 54 deletions

View File

@ -75,7 +75,7 @@ private:
int template_window_half_size_;
int search_window_half_size_;
int fixed_point_mult_;
typename pixelInfo<WT>::sampleType fixed_point_mult_;
int almost_template_window_size_sq_bin_shift_;
std::vector<WT> almost_dist2weight_;
@ -120,7 +120,7 @@ FastNlMeansDenoisingInvoker<T, IT, UIT, D, WT>::FastNlMeansDenoisingInvoker(
const IT max_estimate_sum_value =
(IT)search_window_size_ * (IT)search_window_size_ * (IT)pixelInfo<T>::sampleMax();
fixed_point_mult_ = (int)std::min<IT>(std::numeric_limits<IT>::max() / max_estimate_sum_value,
std::numeric_limits<int>::max());
pixelInfo<WT>::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<T, IT, UIT, D, WT>::operator() (const Range& ra
}
// calc weights
IT estimation[pixelInfo<T>::channels], weights_sum[pixelInfo<T>::channels];
IT estimation[pixelInfo<T>::channels], weights_sum[pixelInfo<WT>::channels];
for (size_t channel_num = 0; channel_num < pixelInfo<T>::channels; channel_num++)
estimation[channel_num] = weights_sum[channel_num] = 0;
estimation[channel_num] = 0;
for (size_t channel_num = 0; channel_num < pixelInfo<WT>::channels; channel_num++)
weights_sum[channel_num] = 0;
for (int y = 0; y < search_window_size_; y++)
{
@ -240,11 +242,8 @@ void FastNlMeansDenoisingInvoker<T, IT, UIT, D, WT>::operator() (const Range& ra
}
}
for (size_t channel_num = 0; channel_num < pixelInfo<T>::channels; channel_num++)
estimation[channel_num] =
(static_cast<UIT>(estimation[channel_num]) + weights_sum[channel_num]/2) /
weights_sum[channel_num];
divByWeightsSum<IT, UIT, pixelInfo<T>::channels, pixelInfo<WT>::channels>(estimation,
weights_sum);
dst_.at<T>(i,j) = saturateCastFromArray<T, IT>(estimation);
}
}

View File

@ -122,11 +122,11 @@ class DistAbs
}
};
static const double WEIGHT_THRESHOLD = 0.001;
template <typename T, typename WT> 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<T>::channels)));
if (weight < WEIGHT_THRESHOLD * fixed_point_mult)
@ -137,17 +137,11 @@ class DistAbs
template <typename T, typename ET, int n> struct calcWeight_<T, Vec<ET, n> >
{
static inline Vec<ET, n> f(double dist, const float *h, int fixed_point_mult)
static inline Vec<ET, n> f(double dist, const float *h, ET fixed_point_mult)
{
Vec<ET, n> res;
for (int i=0; i<n; i++)
{
ET weight = (ET)round(fixed_point_mult *
std::exp(-dist*dist / (h[i]*h[i] * pixelInfo<T>::channels)));
if (weight < WEIGHT_THRESHOLD * fixed_point_mult)
weight = 0;
res[i] = weight;
}
res[i] = calcWeight<T, ET>(dist, &h[i], fixed_point_mult);
return res;
}
};
@ -247,11 +241,11 @@ class DistSquared
}
};
static const double WEIGHT_THRESHOLD = 0.001;
template <typename T, typename WT> 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<T>::channels)));
if (weight < WEIGHT_THRESHOLD * fixed_point_mult)
@ -266,13 +260,7 @@ class DistSquared
{
Vec<ET, n> res;
for (int i=0; i<n; i++)
{
ET weight = (ET)round(fixed_point_mult *
std::exp(-dist / (h[i]*h[i] * pixelInfo<T>::channels)));
if (weight < WEIGHT_THRESHOLD * fixed_point_mult)
weight = 0;
res[i] = weight;
}
res[i] = calcWeight<T, ET>(dist, &h[i], fixed_point_mult);
return res;
}
};
@ -320,48 +308,42 @@ template <typename T, typename IT, typename WT> struct incWithWeight_
}
};
template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 2>, IT, int>
template <typename ET, typename IT, typename WT> struct incWithWeight_<Vec<ET, 2>, IT, WT>
{
static inline void f(IT* estimation, IT* weights_sum, int weight, Vec<ET, 2> p)
static inline void f(IT* estimation, IT* weights_sum, WT weight, Vec<ET, 2> p)
{
estimation[0] += (IT)weight * p[0];
estimation[1] += (IT)weight * p[1];
weights_sum[0] += (IT)weight;
weights_sum[1] += (IT)weight;
}
};
template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 3>, IT, int>
template <typename ET, typename IT, typename WT> struct incWithWeight_<Vec<ET, 3>, IT, WT>
{
static inline void f(IT* estimation, IT* weights_sum, int weight, Vec<ET, 3> p)
static inline void f(IT* estimation, IT* weights_sum, WT weight, Vec<ET, 3> 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 <typename ET, typename IT> struct incWithWeight_<Vec<ET, 4>, IT, int>
template <typename ET, typename IT, typename WT> struct incWithWeight_<Vec<ET, 4>, IT, WT>
{
static inline void f(IT* estimation, IT* weights_sum, int weight, Vec<ET, 4> p)
static inline void f(IT* estimation, IT* weights_sum, WT weight, Vec<ET, 4> 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 <typename ET, typename IT> struct incWithWeight_<Vec<ET, 2>, IT, Vec<int, 2> >
template <typename ET, typename IT, typename EW> struct incWithWeight_<Vec<ET, 2>, IT, Vec<EW, 2> >
{
static inline void f(IT* estimation, IT* weights_sum, Vec<int, 2> weight, Vec<ET, 2> p)
static inline void f(IT* estimation, IT* weights_sum, Vec<EW, 2> weight, Vec<ET, 2> p)
{
estimation[0] += (IT)weight[0] * p[0];
estimation[1] += (IT)weight[1] * p[1];
@ -370,9 +352,9 @@ template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 2>, IT, Vec<in
}
};
template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 3>, IT, Vec<int, 3> >
template <typename ET, typename IT, typename EW> struct incWithWeight_<Vec<ET, 3>, IT, Vec<EW, 3> >
{
static inline void f(IT* estimation, IT* weights_sum, Vec<int, 3> weight, Vec<ET, 3> p)
static inline void f(IT* estimation, IT* weights_sum, Vec<EW, 3> weight, Vec<ET, 3> p)
{
estimation[0] += (IT)weight[0] * p[0];
estimation[1] += (IT)weight[1] * p[1];
@ -383,9 +365,9 @@ template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 3>, IT, Vec<in
}
};
template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 4>, IT, Vec<int, 4> >
template <typename ET, typename IT, typename EW> struct incWithWeight_<Vec<ET, 4>, IT, Vec<EW, 4> >
{
static inline void f(IT* estimation, IT* weights_sum, Vec<int, 4> weight, Vec<ET, 4> p)
static inline void f(IT* estimation, IT* weights_sum, Vec<EW, 4> weight, Vec<ET, 4> 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_<T, IT, WT>::f(estimation, weights_sum, weight, p);
}
template <typename IT, typename UIT, int nc, int nw> struct divByWeightsSum_
{
static inline void f(IT* estimation, IT* weights_sum);
};
template <typename IT, typename UIT> struct divByWeightsSum_<IT, UIT, 1, 1>
{
static inline void f(IT* estimation, IT* weights_sum)
{
estimation[0] = (static_cast<UIT>(estimation[0]) + weights_sum[0]/2) / weights_sum[0];
}
};
template <typename IT, typename UIT, int n> struct divByWeightsSum_<IT, UIT, n, 1>
{
static inline void f(IT* estimation, IT* weights_sum)
{
for (size_t i = 0; i < n; i++)
estimation[i] = (static_cast<UIT>(estimation[i]) + weights_sum[0]/2) / weights_sum[0];
}
};
template <typename IT, typename UIT, int n> struct divByWeightsSum_<IT, UIT, n, n>
{
static inline void f(IT* estimation, IT* weights_sum)
{
for (size_t i = 0; i < n; i++)
estimation[i] = (static_cast<UIT>(estimation[i]) + weights_sum[i]/2) / weights_sum[i];
}
};
template <typename IT, typename UIT, int nc, int nw>
static inline void divByWeightsSum(IT* estimation, IT* weights_sum)
{
return divByWeightsSum_<IT, UIT, nc, nw>::f(estimation, weights_sum);
}
template <typename T, typename IT> struct saturateCastFromArray_
{
static inline T f(IT* estimation)

View File

@ -81,7 +81,7 @@ private:
int search_window_half_size_;
int temporal_window_half_size_;
int fixed_point_mult_;
typename pixelInfo<WT>::sampleType fixed_point_mult_;
int almost_template_window_size_sq_bin_shift;
std::vector<WT> almost_dist2weight;
@ -128,7 +128,7 @@ FastNlMeansMultiDenoisingInvoker<T, IT, UIT, D, WT>::FastNlMeansMultiDenoisingIn
const IT max_estimate_sum_value =
(IT)temporal_window_size_ * (IT)search_window_size_ * (IT)search_window_size_ * (IT)pixelInfo<T>::sampleMax();
fixed_point_mult_ = (int)std::min<IT>(std::numeric_limits<IT>::max() / max_estimate_sum_value,
std::numeric_limits<int>::max());
pixelInfo<WT>::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<T, IT, UIT, D, WT>::operator() (const Rang
}
// calc weights
IT estimation[pixelInfo<T>::channels], weights_sum[pixelInfo<T>::channels];
IT estimation[pixelInfo<T>::channels], weights_sum[pixelInfo<WT>::channels];
for (size_t channel_num = 0; channel_num < pixelInfo<T>::channels; channel_num++)
estimation[channel_num] = weights_sum[channel_num] = 0;
estimation[channel_num] = 0;
for (size_t channel_num = 0; channel_num < pixelInfo<WT>::channels; channel_num++)
weights_sum[channel_num] = 0;
for (int d = 0; d < temporal_window_size_; d++)
{
@ -267,11 +269,8 @@ void FastNlMeansMultiDenoisingInvoker<T, IT, UIT, D, WT>::operator() (const Rang
}
}
for (size_t channel_num = 0; channel_num < pixelInfo<T>::channels; channel_num++)
estimation[channel_num] =
(static_cast<UIT>(estimation[channel_num]) + weights_sum[channel_num] / 2) /
weights_sum[channel_num];
divByWeightsSum<IT, UIT, pixelInfo<T>::channels, pixelInfo<WT>::channels>(estimation,
weights_sum);
dst_.at<T>(i,j) = saturateCastFromArray<T, IT>(estimation);
}
}