Additional refactoring preparing for 16-bit implementation
This commit is contained in:
parent
e178294b49
commit
8368fb9ea8
@ -107,7 +107,7 @@ FastNlMeansDenoisingInvoker<T, IT, UIT>::FastNlMeansDenoisingInvoker(
|
||||
const float h) :
|
||||
src_(src), dst_(dst)
|
||||
{
|
||||
CV_Assert(src.channels() == sizeof(T)); //T is Vec1b or Vec2b or Vec3b
|
||||
CV_Assert(src.channels() == pixelInfo<T>::channels);
|
||||
|
||||
template_window_half_size_ = template_window_size / 2;
|
||||
search_window_half_size_ = search_window_size / 2;
|
||||
@ -117,17 +117,21 @@ FastNlMeansDenoisingInvoker<T, IT, UIT>::FastNlMeansDenoisingInvoker(
|
||||
border_size_ = search_window_half_size_ + template_window_half_size_;
|
||||
copyMakeBorder(src_, extended_src_, border_size_, border_size_, border_size_, border_size_, BORDER_DEFAULT);
|
||||
|
||||
const IT max_estimate_sum_value = (IT)search_window_size_ * (IT)search_window_size_ * 255;
|
||||
const IT max_estimate_sum_value =
|
||||
(IT)search_window_size_ * (IT)search_window_size_ * (IT)pixelInfo<T>::sampleMax();
|
||||
fixed_point_mult_ = std::numeric_limits<IT>::max() / max_estimate_sum_value;
|
||||
|
||||
// precalc weight for every possible l2 dist between blocks
|
||||
// additional optimization of precalced weights to replace division(averaging) by binary shift
|
||||
// squared distances are truncated to 16 bits to get a reasonable table size
|
||||
CV_Assert(template_window_size_ <= 46340); // sqrt(INT_MAX)
|
||||
int template_window_size_sq = template_window_size_ * template_window_size_;
|
||||
almost_template_window_size_sq_bin_shift_ = getNearestPowerOf2(template_window_size_sq);
|
||||
almost_template_window_size_sq_bin_shift_ =
|
||||
getNearestPowerOf2(template_window_size_sq) + 2*pixelInfo<T>::sampleBits() - 16;
|
||||
double almost_dist2actual_dist_multiplier = ((double)(1 << almost_template_window_size_sq_bin_shift_)) / template_window_size_sq;
|
||||
|
||||
IT max_dist = 255 * 255 * sizeof(T);
|
||||
IT max_dist =
|
||||
(IT)pixelInfo<T>::sampleMax() * (IT)pixelInfo<T>::sampleMax() * (IT)pixelInfo<T>::channels;
|
||||
int almost_max_dist = (int)(max_dist / almost_dist2actual_dist_multiplier + 1);
|
||||
almost_dist2weight_.resize(almost_max_dist);
|
||||
|
||||
|
@ -44,30 +44,62 @@
|
||||
|
||||
using namespace cv;
|
||||
|
||||
template <typename T, typename IT> struct calcDist_
|
||||
template <typename T> struct pixelInfo_
|
||||
{
|
||||
static inline IT f(const T a, const T b);
|
||||
static const int channels = 1;
|
||||
typedef T sampleType;
|
||||
};
|
||||
|
||||
template <typename IT> struct calcDist_<uchar, IT>
|
||||
template <typename ET, int n> struct pixelInfo_<Vec<ET, n> >
|
||||
{
|
||||
static inline IT f(uchar a, uchar b)
|
||||
static const int channels = n;
|
||||
typedef ET sampleType;
|
||||
};
|
||||
|
||||
template <typename T> struct pixelInfo: public pixelInfo_<T>
|
||||
{
|
||||
using typename pixelInfo_<T>::sampleType;
|
||||
|
||||
static inline sampleType sampleMax()
|
||||
{
|
||||
return std::numeric_limits<sampleType>::max();
|
||||
}
|
||||
|
||||
static inline sampleType sampleMin()
|
||||
{
|
||||
return std::numeric_limits<sampleType>::min();
|
||||
}
|
||||
|
||||
static inline size_t sampleBytes()
|
||||
{
|
||||
return sizeof(sampleType);
|
||||
}
|
||||
|
||||
static inline size_t sampleBits()
|
||||
{
|
||||
return 8*sampleBytes();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename IT> struct calcDist_
|
||||
{
|
||||
static inline IT f(const T a, const T b)
|
||||
{
|
||||
return (IT)(a-b) * (IT)(a-b);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IT> struct calcDist_<Vec2b, IT>
|
||||
template <typename ET, typename IT> struct calcDist_<Vec<ET, 2>, IT>
|
||||
{
|
||||
static inline IT f(const Vec2b a, const Vec2b b)
|
||||
static inline IT f(const Vec<ET, 2> a, const Vec<ET, 2> b)
|
||||
{
|
||||
return (IT)(a[0]-b[0])*(IT)(a[0]-b[0]) + (IT)(a[1]-b[1])*(IT)(a[1]-b[1]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IT> struct calcDist_<Vec3b, IT>
|
||||
template <typename ET, typename IT> struct calcDist_<Vec<ET, 3>, IT>
|
||||
{
|
||||
static inline IT f(const Vec3b a, const Vec3b b)
|
||||
static inline IT f(const Vec<ET, 3> a, const Vec<ET, 3> b)
|
||||
{
|
||||
return
|
||||
(IT)(a[0]-b[0])*(IT)(a[0]-b[0]) +
|
||||
@ -92,14 +124,6 @@ static inline IT calcDist(const Mat& m, int i1, int j1, int i2, int j2)
|
||||
template <typename T, typename IT> struct calcUpDownDist_
|
||||
{
|
||||
static inline IT f(T a_up, T a_down, T b_up, T b_down)
|
||||
{
|
||||
return calcDist<T, IT>(a_down, b_down) - calcDist<T, IT>(a_up, b_up);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IT> struct calcUpDownDist_<uchar, IT>
|
||||
{
|
||||
static inline IT f(uchar a_up, uchar a_down, uchar b_up, uchar b_down)
|
||||
{
|
||||
IT A = a_down - b_down;
|
||||
IT B = a_up - b_up;
|
||||
@ -107,6 +131,17 @@ template <typename IT> struct calcUpDownDist_<uchar, IT>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ET, int n, typename IT> struct calcUpDownDist_<Vec<ET, n>, IT>
|
||||
{
|
||||
private:
|
||||
typedef Vec<ET, n> T;
|
||||
public:
|
||||
static inline IT f(T a_up, T a_down, T b_up, T b_down)
|
||||
{
|
||||
return calcDist<T, IT>(a_down, b_down) - calcDist<T, IT>(a_up, b_up);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename IT>
|
||||
static inline IT calcUpDownDist(T a_up, T a_down, T b_up, T b_down)
|
||||
{
|
||||
@ -115,29 +150,24 @@ static inline IT calcUpDownDist(T a_up, T a_down, T b_up, T b_down)
|
||||
|
||||
template <typename T, typename IT> struct incWithWeight_
|
||||
{
|
||||
static inline void f(IT* estimation, IT weight, T p);
|
||||
};
|
||||
|
||||
template <typename IT> struct incWithWeight_<uchar, IT>
|
||||
{
|
||||
static inline void f(IT* estimation, IT weight, uchar p)
|
||||
static inline void f(IT* estimation, IT weight, T p)
|
||||
{
|
||||
estimation[0] += weight * p;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IT> struct incWithWeight_<Vec2b, IT>
|
||||
template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 2>, IT>
|
||||
{
|
||||
static inline void f(IT* estimation, IT weight, Vec2b p)
|
||||
static inline void f(IT* estimation, IT weight, Vec<ET, 2> p)
|
||||
{
|
||||
estimation[0] += weight * p[0];
|
||||
estimation[1] += weight * p[1];
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IT> struct incWithWeight_<Vec3b, IT>
|
||||
template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 3>, IT>
|
||||
{
|
||||
static inline void f(IT* estimation, IT weight, Vec3b p)
|
||||
static inline void f(IT* estimation, IT weight, Vec<ET, 3> p)
|
||||
{
|
||||
estimation[0] += weight * p[0];
|
||||
estimation[1] += weight * p[1];
|
||||
@ -153,36 +183,31 @@ static inline void incWithWeight(IT* estimation, IT weight, T p)
|
||||
|
||||
template <typename T, typename IT> struct saturateCastFromArray_
|
||||
{
|
||||
static inline T f(IT* estimation);
|
||||
};
|
||||
|
||||
template <typename IT> struct saturateCastFromArray_<uchar, IT>
|
||||
{
|
||||
static inline uchar f(IT* estimation)
|
||||
static inline T f(IT* estimation)
|
||||
{
|
||||
return saturate_cast<uchar>(estimation[0]);
|
||||
return saturate_cast<T>(estimation[0]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IT> struct saturateCastFromArray_<Vec2b, IT>
|
||||
template <typename ET, typename IT> struct saturateCastFromArray_<Vec<ET, 2>, IT>
|
||||
{
|
||||
static inline Vec2b f(IT* estimation)
|
||||
static inline Vec<ET, 2> f(IT* estimation)
|
||||
{
|
||||
Vec2b res;
|
||||
res[0] = saturate_cast<uchar>(estimation[0]);
|
||||
res[1] = saturate_cast<uchar>(estimation[1]);
|
||||
Vec<ET, 2> res;
|
||||
res[0] = saturate_cast<ET>(estimation[0]);
|
||||
res[1] = saturate_cast<ET>(estimation[1]);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IT> struct saturateCastFromArray_<Vec3b, IT>
|
||||
template <typename ET, typename IT> struct saturateCastFromArray_<Vec<ET, 3>, IT>
|
||||
{
|
||||
static inline Vec3b f(IT* estimation)
|
||||
static inline Vec<ET, 3> f(IT* estimation)
|
||||
{
|
||||
Vec3b res;
|
||||
res[0] = saturate_cast<uchar>(estimation[0]);
|
||||
res[1] = saturate_cast<uchar>(estimation[1]);
|
||||
res[2] = saturate_cast<uchar>(estimation[2]);
|
||||
Vec<ET, 3> res;
|
||||
res[0] = saturate_cast<ET>(estimation[0]);
|
||||
res[1] = saturate_cast<ET>(estimation[1]);
|
||||
res[2] = saturate_cast<ET>(estimation[2]);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
@ -106,7 +106,7 @@ FastNlMeansMultiDenoisingInvoker<T, IT, UIT>::FastNlMeansMultiDenoisingInvoker(
|
||||
dst_(dst), extended_srcs_(srcImgs.size())
|
||||
{
|
||||
CV_Assert(srcImgs.size() > 0);
|
||||
CV_Assert(srcImgs[0].channels() == sizeof(T));
|
||||
CV_Assert(srcImgs[0].channels() == pixelInfo<T>::channels);
|
||||
|
||||
rows_ = srcImgs[0].rows;
|
||||
cols_ = srcImgs[0].cols;
|
||||
@ -126,20 +126,23 @@ FastNlMeansMultiDenoisingInvoker<T, IT, UIT>::FastNlMeansMultiDenoisingInvoker(
|
||||
|
||||
main_extended_src_ = extended_srcs_[temporal_window_half_size_];
|
||||
const IT max_estimate_sum_value =
|
||||
(IT)temporal_window_size_ * (IT)search_window_size_ * (IT)search_window_size_ * 255;
|
||||
(IT)temporal_window_size_ * (IT)search_window_size_ * (IT)search_window_size_ * (IT)pixelInfo<T>::sampleMax();
|
||||
fixed_point_mult_ = std::numeric_limits<IT>::max() / max_estimate_sum_value;
|
||||
|
||||
// precalc weight for every possible l2 dist between blocks
|
||||
// additional optimization of precalced weights to replace division(averaging) by binary shift
|
||||
// squared distances are truncated to 16 bits to get a reasonable table size
|
||||
int template_window_size_sq = template_window_size_ * template_window_size_;
|
||||
almost_template_window_size_sq_bin_shift = 0;
|
||||
while (1 << almost_template_window_size_sq_bin_shift < template_window_size_sq)
|
||||
almost_template_window_size_sq_bin_shift++;
|
||||
almost_template_window_size_sq_bin_shift += 2*pixelInfo<T>::sampleBits() - 16;
|
||||
|
||||
int almost_template_window_size_sq = 1 << almost_template_window_size_sq_bin_shift;
|
||||
double almost_dist2actual_dist_multiplier = (double) almost_template_window_size_sq / template_window_size_sq;
|
||||
|
||||
IT max_dist = 255 * 255 * sizeof(T);
|
||||
IT max_dist =
|
||||
(IT)pixelInfo<T>::sampleMax() * (IT)pixelInfo<T>::sampleMax() * (IT)pixelInfo<T>::channels;
|
||||
int almost_max_dist = (int) (max_dist / almost_dist2actual_dist_multiplier + 1);
|
||||
almost_dist2weight.resize(almost_max_dist);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user