Commit e16d89e8 authored by Ilya Lavrenov's avatar Ilya Lavrenov

some refactoring

parent edbff688
......@@ -51,14 +51,16 @@
using namespace cv;
template <typename T>
struct FastNlMeansDenoisingInvoker : ParallelLoopBody {
public:
struct FastNlMeansDenoisingInvoker :
public ParallelLoopBody
{
public:
FastNlMeansDenoisingInvoker(const Mat& src, Mat& dst,
int template_window_size, int search_window_size, const float h);
void operator() (const Range& range) const;
private:
private:
void operator= (const FastNlMeansDenoisingInvoker&);
const Mat& src_;
......@@ -78,15 +80,12 @@ struct FastNlMeansDenoisingInvoker : ParallelLoopBody {
std::vector<int> almost_dist2weight_;
void calcDistSumsForFirstElementInRow(
int i,
Array2d<int>& dist_sums,
int i, Array2d<int>& dist_sums,
Array3d<int>& col_dist_sums,
Array3d<int>& up_col_dist_sums) const;
void calcDistSumsForElementInFirstRow(
int i,
int j,
int first_col_num,
int i, int j, int first_col_num,
Array2d<int>& dist_sums,
Array3d<int>& col_dist_sums,
Array3d<int>& up_col_dist_sums) const;
......@@ -95,17 +94,18 @@ struct FastNlMeansDenoisingInvoker : ParallelLoopBody {
inline int getNearestPowerOf2(int value)
{
int p = 0;
while( 1 << p < value) ++p;
while( 1 << p < value)
++p;
return p;
}
template <class T>
FastNlMeansDenoisingInvoker<T>::FastNlMeansDenoisingInvoker(
const cv::Mat& src,
cv::Mat& dst,
const cv::Mat& src, cv::Mat& dst,
int template_window_size,
int search_window_size,
const float 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
......@@ -134,7 +134,8 @@ FastNlMeansDenoisingInvoker<T>::FastNlMeansDenoisingInvoker(
almost_dist2weight_.resize(almost_max_dist);
const double WEIGHT_THRESHOLD = 0.001;
for (int almost_dist = 0; almost_dist < almost_max_dist; almost_dist++) {
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 * sizeof(T))));
......@@ -144,15 +145,15 @@ FastNlMeansDenoisingInvoker<T>::FastNlMeansDenoisingInvoker(
almost_dist2weight_[almost_dist] = weight;
}
CV_Assert(almost_dist2weight_[0] == fixed_point_mult_);
// additional optimization init end
if (dst_.empty()) {
// additional optimization init end
if (dst_.empty())
dst_ = Mat::zeros(src_.size(), src_.type());
}
}
template <class T>
void FastNlMeansDenoisingInvoker<T>::operator() (const Range& range) const {
void FastNlMeansDenoisingInvoker<T>::operator() (const Range& range) const
{
int row_from = range.start;
int row_to = range.end - 1;
......@@ -164,30 +165,36 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const Range& range) const {
int first_col_num = -1;
Array3d<int> up_col_dist_sums(src_.cols, search_window_size_, search_window_size_);
for (int i = row_from; i <= row_to; i++) {
for (int j = 0; j < src_.cols; j++) {
for (int i = row_from; i <= row_to; i++)
{
for (int j = 0; j < src_.cols; j++)
{
int search_window_y = i - search_window_half_size_;
int search_window_x = j - search_window_half_size_;
// calc dist_sums
if (j == 0) {
if (j == 0)
{
calcDistSumsForFirstElementInRow(i, dist_sums, col_dist_sums, up_col_dist_sums);
first_col_num = 0;
} else { // calc cur dist_sums using previous dist_sums
if (i == row_from) {
}
else
{
// calc cur dist_sums using previous dist_sums
if (i == row_from)
{
calcDistSumsForElementInFirstRow(i, j, first_col_num,
dist_sums, col_dist_sums, up_col_dist_sums);
} else {
}
else
{
int ay = border_size_ + i;
int ax = border_size_ + j + template_window_half_size_;
int start_by =
border_size_ + i - search_window_half_size_;
int start_bx =
border_size_ + j - search_window_half_size_ + template_window_half_size_;
int start_by = border_size_ + i - search_window_half_size_;
int start_bx = border_size_ + j - search_window_half_size_ + template_window_half_size_;
T a_up = extended_src_.at<T>(ay - template_window_half_size_ - 1, ax);
T a_down = extended_src_.at<T>(ay + template_window_half_size_, ax);
......@@ -195,20 +202,18 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const Range& range) const {
// copy class member to local variable for optimization
int search_window_size = search_window_size_;
for (int y = 0; y < search_window_size; y++) {
for (int y = 0; y < search_window_size; y++)
{
int* dist_sums_row = dist_sums.row_ptr(y);
int* col_dist_sums_row = col_dist_sums.row_ptr(first_col_num,y);
int* up_col_dist_sums_row = up_col_dist_sums.row_ptr(j, y);
const T* b_up_ptr =
extended_src_.ptr<T>(start_by - template_window_half_size_ - 1 + y);
const T* b_up_ptr = extended_src_.ptr<T>(start_by - template_window_half_size_ - 1 + y);
const T* b_down_ptr = extended_src_.ptr<T>(start_by + template_window_half_size_ + y);
const T* b_down_ptr =
extended_src_.ptr<T>(start_by + template_window_half_size_ + y);
for (int x = 0; x < search_window_size; x++) {
for (int x = 0; x < search_window_size; x++)
{
dist_sums_row[x] -= col_dist_sums_row[x];
col_dist_sums_row[x] =
......@@ -233,14 +238,15 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const Range& range) const {
int weights_sum = 0;
int estimation[3];
for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++) {
for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++)
estimation[channel_num] = 0;
}
for (int y = 0; y < search_window_size_; y++) {
for (int y = 0; y < search_window_size_; y++)
{
const T* cur_row_ptr = extended_src_.ptr<T>(border_size_ + search_window_y + y);
int* dist_sums_row = dist_sums.row_ptr(y);
for (int x = 0; x < search_window_size_; x++) {
for (int x = 0; x < search_window_size_; x++)
{
int almostAvgDist =
dist_sums_row[x] >> almost_template_window_size_sq_bin_shift_;
......@@ -269,18 +275,19 @@ inline void FastNlMeansDenoisingInvoker<T>::calcDistSumsForFirstElementInRow(
{
int j = 0;
for (int y = 0; y < search_window_size_; y++) {
for (int x = 0; x < search_window_size_; x++) {
for (int y = 0; y < search_window_size_; y++)
for (int x = 0; x < search_window_size_; x++)
{
dist_sums[y][x] = 0;
for (int tx = 0; tx < template_window_size_; tx++) {
for (int tx = 0; tx < template_window_size_; tx++)
col_dist_sums[tx][y][x] = 0;
}
int start_y = i + y - search_window_half_size_;
int start_x = j + x - search_window_half_size_;
for (int ty = -template_window_half_size_; ty <= template_window_half_size_; ty++) {
for (int tx = -template_window_half_size_; tx <= template_window_half_size_; tx++) {
for (int ty = -template_window_half_size_; ty <= template_window_half_size_; ty++)
for (int tx = -template_window_half_size_; tx <= template_window_half_size_; tx++)
{
int dist = calcDist<T>(extended_src_,
border_size_ + i + ty, border_size_ + j + tx,
border_size_ + start_y + ty, border_size_ + start_x + tx);
......@@ -288,11 +295,9 @@ inline void FastNlMeansDenoisingInvoker<T>::calcDistSumsForFirstElementInRow(
dist_sums[y][x] += dist;
col_dist_sums[tx + template_window_half_size_][y][x] += dist;
}
}
up_col_dist_sums[j][y][x] = col_dist_sums[template_window_size_ - 1][y][x];
}
}
}
template <class T>
......@@ -312,23 +317,21 @@ inline void FastNlMeansDenoisingInvoker<T>::calcDistSumsForElementInFirstRow(
int new_last_col_num = first_col_num;
for (int y = 0; y < search_window_size_; y++) {
for (int x = 0; x < search_window_size_; x++) {
for (int y = 0; y < search_window_size_; y++)
for (int x = 0; x < search_window_size_; x++)
{
dist_sums[y][x] -= col_dist_sums[first_col_num][y][x];
col_dist_sums[new_last_col_num][y][x] = 0;
int by = start_by + y;
int bx = start_bx + x;
for (int ty = -template_window_half_size_; ty <= template_window_half_size_; ty++) {
for (int ty = -template_window_half_size_; ty <= template_window_half_size_; ty++)
col_dist_sums[new_last_col_num][y][x] +=
calcDist<T>(extended_src_, ay + ty, ax, by + ty, bx);
}
dist_sums[y][x] += col_dist_sums[new_last_col_num][y][x];
up_col_dist_sums[j][y][x] = col_dist_sums[new_last_col_num][y][x];
}
}
}
#endif
......@@ -46,29 +46,35 @@ using namespace cv;
template <typename T> static inline int calcDist(const T a, const T b);
template <> inline int calcDist(const uchar a, const uchar b) {
template <> inline int calcDist(const uchar a, const uchar b)
{
return (a-b) * (a-b);
}
template <> inline int calcDist(const Vec2b a, const Vec2b b) {
template <> inline int calcDist(const Vec2b a, const Vec2b b)
{
return (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]);
}
template <> inline int calcDist(const Vec3b a, const Vec3b b) {
template <> inline int calcDist(const Vec3b a, const Vec3b b)
{
return (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) + (a[2]-b[2])*(a[2]-b[2]);
}
template <typename T> static inline int calcDist(const Mat& m, int i1, int j1, int i2, int j2) {
template <typename T> static inline int calcDist(const Mat& m, int i1, int j1, int i2, int j2)
{
const T a = m.at<T>(i1, j1);
const T b = m.at<T>(i2, j2);
return calcDist<T>(a,b);
}
template <typename T> static inline int calcUpDownDist(T a_up, T a_down, T b_up, T b_down) {
template <typename T> static inline int calcUpDownDist(T a_up, T a_down, T b_up, T b_down)
{
return calcDist(a_down,b_down) - calcDist(a_up, b_up);
}
template <> inline int calcUpDownDist(uchar a_up, uchar a_down, uchar b_up, uchar b_down) {
template <> inline int calcUpDownDist(uchar a_up, uchar a_down, uchar b_up, uchar b_down)
{
int A = a_down - b_down;
int B = a_up - b_up;
return (A-B)*(A+B);
......@@ -76,16 +82,20 @@ template <> inline int calcUpDownDist(uchar a_up, uchar a_down, uchar b_up, uch
template <typename T> static inline void incWithWeight(int* estimation, int weight, T p);
template <> inline void incWithWeight(int* estimation, int weight, uchar p) {
template <> inline void incWithWeight(int* estimation, int weight, uchar p)
{
estimation[0] += weight * p;
}
template <> inline void incWithWeight(int* estimation, int weight, Vec2b p) {
template <> inline void incWithWeight(int* estimation, int weight, Vec2b p)
{
estimation[0] += weight * p[0];
estimation[1] += weight * p[1];
}
template <> inline void incWithWeight(int* estimation, int weight, Vec3b p) {
template <> inline void incWithWeight(int* estimation, int weight, Vec3b p)
{
estimation[0] += weight * p[0];
estimation[1] += weight * p[1];
estimation[2] += weight * p[2];
......@@ -93,18 +103,21 @@ template <> inline void incWithWeight(int* estimation, int weight, Vec3b p) {
template <typename T> static inline T saturateCastFromArray(int* estimation);
template <> inline uchar saturateCastFromArray(int* estimation) {
template <> inline uchar saturateCastFromArray(int* estimation)
{
return saturate_cast<uchar>(estimation[0]);
}
template <> inline Vec2b saturateCastFromArray(int* estimation) {
template <> inline Vec2b saturateCastFromArray(int* estimation)
{
Vec2b res;
res[0] = saturate_cast<uchar>(estimation[0]);
res[1] = saturate_cast<uchar>(estimation[1]);
return res;
}
template <> inline Vec3b saturateCastFromArray(int* estimation) {
template <> inline Vec3b saturateCastFromArray(int* estimation)
{
Vec3b res;
res[0] = saturate_cast<uchar>(estimation[0]);
res[1] = saturate_cast<uchar>(estimation[1]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment