Commit e178294b authored by Erik Karlsson's avatar Erik Karlsson

Refactoring in preparation for 16-bit implementation of fastNlMeansDenoising

parent 5466e321
...@@ -65,17 +65,17 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h, ...@@ -65,17 +65,17 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h,
switch (src.type()) { switch (src.type()) {
case CV_8U: case CV_8U:
parallel_for_(cv::Range(0, src.rows), parallel_for_(cv::Range(0, src.rows),
FastNlMeansDenoisingInvoker<uchar>( FastNlMeansDenoisingInvoker<uchar, int, unsigned int>(
src, dst, templateWindowSize, searchWindowSize, h)); src, dst, templateWindowSize, searchWindowSize, h));
break; break;
case CV_8UC2: case CV_8UC2:
parallel_for_(cv::Range(0, src.rows), parallel_for_(cv::Range(0, src.rows),
FastNlMeansDenoisingInvoker<cv::Vec2b>( FastNlMeansDenoisingInvoker<cv::Vec2b, int, unsigned int>(
src, dst, templateWindowSize, searchWindowSize, h)); src, dst, templateWindowSize, searchWindowSize, h));
break; break;
case CV_8UC3: case CV_8UC3:
parallel_for_(cv::Range(0, src.rows), parallel_for_(cv::Range(0, src.rows),
FastNlMeansDenoisingInvoker<cv::Vec3b>( FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned int>(
src, dst, templateWindowSize, searchWindowSize, h)); src, dst, templateWindowSize, searchWindowSize, h));
break; break;
default: default:
...@@ -175,19 +175,19 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds ...@@ -175,19 +175,19 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds
{ {
case CV_8U: case CV_8U:
parallel_for_(cv::Range(0, srcImgs[0].rows), parallel_for_(cv::Range(0, srcImgs[0].rows),
FastNlMeansMultiDenoisingInvoker<uchar>( FastNlMeansMultiDenoisingInvoker<uchar, int, unsigned int>(
srcImgs, imgToDenoiseIndex, temporalWindowSize, srcImgs, imgToDenoiseIndex, temporalWindowSize,
dst, templateWindowSize, searchWindowSize, h)); dst, templateWindowSize, searchWindowSize, h));
break; break;
case CV_8UC2: case CV_8UC2:
parallel_for_(cv::Range(0, srcImgs[0].rows), parallel_for_(cv::Range(0, srcImgs[0].rows),
FastNlMeansMultiDenoisingInvoker<cv::Vec2b>( FastNlMeansMultiDenoisingInvoker<cv::Vec2b, int, unsigned int>(
srcImgs, imgToDenoiseIndex, temporalWindowSize, srcImgs, imgToDenoiseIndex, temporalWindowSize,
dst, templateWindowSize, searchWindowSize, h)); dst, templateWindowSize, searchWindowSize, h));
break; break;
case CV_8UC3: case CV_8UC3:
parallel_for_(cv::Range(0, srcImgs[0].rows), parallel_for_(cv::Range(0, srcImgs[0].rows),
FastNlMeansMultiDenoisingInvoker<cv::Vec3b>( FastNlMeansMultiDenoisingInvoker<cv::Vec3b, int, unsigned int>(
srcImgs, imgToDenoiseIndex, temporalWindowSize, srcImgs, imgToDenoiseIndex, temporalWindowSize,
dst, templateWindowSize, searchWindowSize, h)); dst, templateWindowSize, searchWindowSize, h));
break; break;
......
...@@ -44,118 +44,152 @@ ...@@ -44,118 +44,152 @@
using namespace cv; using namespace cv;
template <typename T> static inline int calcDist(const T a, const T b); template <typename T, typename IT> struct calcDist_
template <> inline int calcDist(const uchar a, const uchar b)
{ {
return (a-b) * (a-b); static inline IT f(const T a, const T b);
} };
template <> inline int calcDist(const Vec2b a, const Vec2b b) template <typename IT> struct calcDist_<uchar, IT>
{ {
return (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]); static inline IT f(uchar a, uchar b)
} {
return (IT)(a-b) * (IT)(a-b);
}
};
template <> inline int calcDist(const Vec3b a, const Vec3b b) template <typename IT> struct calcDist_<Vec2b, IT>
{ {
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]); static inline IT f(const Vec2b a, const Vec2b b)
} {
return (IT)(a[0]-b[0])*(IT)(a[0]-b[0]) + (IT)(a[1]-b[1])*(IT)(a[1]-b[1]);
}
};
template <typename T> static inline int calcDist(const Mat& m, int i1, int j1, int i2, int j2) template <typename IT> struct calcDist_<Vec3b, IT>
{ {
const T a = m.at<T>(i1, j1); static inline IT f(const Vec3b a, const Vec3b b)
const T b = m.at<T>(i2, j2); {
return calcDist<T>(a,b); return
} (IT)(a[0]-b[0])*(IT)(a[0]-b[0]) +
(IT)(a[1]-b[1])*(IT)(a[1]-b[1]) +
(IT)(a[2]-b[2])*(IT)(a[2]-b[2]);
}
};
template <typename T> static inline int calcUpDownDist(T a_up, T a_down, T b_up, T b_down) template <typename T, typename IT> static inline IT calcDist(const T a, const T b)
{ {
return calcDist(a_down, b_down) - calcDist(a_up, b_up); return calcDist_<T, IT>::f(a, b);
} }
template <> inline int calcUpDownDist(uchar a_up, uchar a_down, uchar b_up, uchar b_down) template <typename T, typename IT>
static inline IT calcDist(const Mat& m, int i1, int j1, int i2, int j2)
{ {
int A = a_down - b_down; const T a = m.at<T>(i1, j1);
int B = a_up - b_up; const T b = m.at<T>(i2, j2);
return (A-B)*(A+B); return calcDist<T, IT>(a,b);
} }
template <typename T> static inline void incWithWeight(int* estimation, int weight, T p); template <typename T, typename IT> struct calcUpDownDist_
template <> inline void incWithWeight(int* estimation, int weight, uchar p)
{ {
estimation[0] += weight * p; 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 <> inline void incWithWeight(int* estimation, int weight, Vec2b p) template <typename IT> struct calcUpDownDist_<uchar, IT>
{ {
estimation[0] += weight * p[0]; static inline IT f(uchar a_up, uchar a_down, uchar b_up, uchar b_down)
estimation[1] += weight * p[1]; {
} IT A = a_down - b_down;
IT B = a_up - b_up;
return (A-B)*(A+B);
}
};
template <> inline void incWithWeight(int* estimation, int weight, Vec3b p) template <typename T, typename IT>
static inline IT calcUpDownDist(T a_up, T a_down, T b_up, T b_down)
{ {
estimation[0] += weight * p[0]; return calcUpDownDist_<T, IT>::f(a_up, a_down, b_up, b_down);
estimation[1] += weight * p[1]; };
estimation[2] += weight * p[2];
}
template <> inline void incWithWeight(int* estimation, int weight, int p) template <typename T, typename IT> struct incWithWeight_
{ {
estimation[0] += weight * p; static inline void f(IT* estimation, IT weight, T p);
} };
template <> inline void incWithWeight(int* estimation, int weight, Vec2i p) template <typename IT> struct incWithWeight_<uchar, IT>
{ {
estimation[0] += weight * p[0]; static inline void f(IT* estimation, IT weight, uchar p)
estimation[1] += weight * p[1]; {
} estimation[0] += weight * p;
}
};
template <> inline void incWithWeight(int* estimation, int weight, Vec3i p) template <typename IT> struct incWithWeight_<Vec2b, IT>
{ {
estimation[0] += weight * p[0]; static inline void f(IT* estimation, IT weight, Vec2b p)
estimation[1] += weight * p[1]; {
estimation[2] += weight * p[2]; estimation[0] += weight * p[0];
} estimation[1] += weight * p[1];
}
};
template <typename T> static inline T saturateCastFromArray(int* estimation); template <typename IT> struct incWithWeight_<Vec3b, IT>
{
static inline void f(IT* estimation, IT weight, Vec3b p)
{
estimation[0] += weight * p[0];
estimation[1] += weight * p[1];
estimation[2] += weight * p[2];
}
};
template <> inline uchar saturateCastFromArray(int* estimation) template <typename T, typename IT>
static inline void incWithWeight(IT* estimation, IT weight, T p)
{ {
return saturate_cast<uchar>(estimation[0]); return incWithWeight_<T, IT>::f(estimation, weight, p);
} }
template <> inline Vec2b saturateCastFromArray(int* estimation) template <typename T, typename IT> struct saturateCastFromArray_
{ {
Vec2b res; static inline T f(IT* estimation);
res[0] = saturate_cast<uchar>(estimation[0]); };
res[1] = saturate_cast<uchar>(estimation[1]);
return res;
}
template <> inline Vec3b saturateCastFromArray(int* estimation) template <typename IT> struct saturateCastFromArray_<uchar, IT>
{ {
Vec3b res; static inline uchar f(IT* estimation)
res[0] = saturate_cast<uchar>(estimation[0]); {
res[1] = saturate_cast<uchar>(estimation[1]); return saturate_cast<uchar>(estimation[0]);
res[2] = saturate_cast<uchar>(estimation[2]); }
return res; };
}
template <> inline int saturateCastFromArray(int* estimation) template <typename IT> struct saturateCastFromArray_<Vec2b, IT>
{ {
return estimation[0]; static inline Vec2b f(IT* estimation)
} {
Vec2b res;
res[0] = saturate_cast<uchar>(estimation[0]);
res[1] = saturate_cast<uchar>(estimation[1]);
return res;
}
};
template <> inline Vec2i saturateCastFromArray(int* estimation) template <typename IT> struct saturateCastFromArray_<Vec3b, IT>
{ {
estimation[1] = 0; static inline Vec3b f(IT* estimation)
return Vec2i(estimation); {
} Vec3b res;
res[0] = saturate_cast<uchar>(estimation[0]);
res[1] = saturate_cast<uchar>(estimation[1]);
res[2] = saturate_cast<uchar>(estimation[2]);
return res;
}
};
template <> inline Vec3i saturateCastFromArray(int* estimation) template <typename T, typename IT> static inline T saturateCastFromArray(IT* estimation)
{ {
return Vec3i(estimation); return saturateCastFromArray_<T, IT>::f(estimation);
} }
#endif #endif
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