Added support for 4-component input for fastNlMeansDenoising[Multi][Abs]

pull/3814/head
Erik Karlsson 10 years ago
parent 87760d13fb
commit ae08884854
  1. 41
      modules/photo/src/denoising.cpp
  2. 2
      modules/photo/src/fast_nlmeans_denoising_invoker.hpp
  3. 48
      modules/photo/src/fast_nlmeans_denoising_invoker_commons.hpp
  4. 2
      modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp

@ -78,9 +78,14 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h,
FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistSquared>(
src, dst, templateWindowSize, searchWindowSize, h));
break;
case CV_8UC4:
parallel_for_(cv::Range(0, src.rows),
FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared>(
src, dst, templateWindowSize, searchWindowSize, h));
break;
default:
CV_Error(Error::StsBadArg,
"Unsupported image format! Only CV_8U, CV_8UC2, and CV_8UC3 are supported");
"Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3 and CV_8UC4 are supported");
}
}
@ -112,6 +117,11 @@ void cv::fastNlMeansDenoisingAbs( InputArray _src, OutputArray _dst, float h,
FastNlMeansDenoisingInvoker<cv::Vec3b, int, unsigned, DistAbs>(
src, dst, templateWindowSize, searchWindowSize, h));
break;
case CV_8UC4:
parallel_for_(cv::Range(0, src.rows),
FastNlMeansDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs>(
src, dst, templateWindowSize, searchWindowSize, h));
break;
case CV_16U:
parallel_for_(cv::Range(0, src.rows),
FastNlMeansDenoisingInvoker<ushort, int64, uint64, DistAbs>(
@ -127,9 +137,14 @@ void cv::fastNlMeansDenoisingAbs( InputArray _src, OutputArray _dst, float h,
FastNlMeansDenoisingInvoker<cv::Vec<ushort, 3>, int64, uint64, DistAbs>(
src, dst, templateWindowSize, searchWindowSize, h));
break;
case CV_16UC4:
parallel_for_(cv::Range(0, src.rows),
FastNlMeansDenoisingInvoker<cv::Vec<ushort, 4>, int64, uint64, DistAbs>(
src, dst, templateWindowSize, searchWindowSize, h));
break;
default:
CV_Error(Error::StsBadArg,
"Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3, CV_16U, CV_16UC2, and CV_16UC3 are supported");
"Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3, CV_8UC4, CV_16U, CV_16UC2, CV_16UC3 and CV_16UC4 are supported");
}
}
@ -240,9 +255,15 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds
srcImgs, imgToDenoiseIndex, temporalWindowSize,
dst, templateWindowSize, searchWindowSize, h));
break;
case CV_8UC4:
parallel_for_(cv::Range(0, srcImgs[0].rows),
FastNlMeansMultiDenoisingInvoker<cv::Vec4b, int, unsigned, DistSquared>(
srcImgs, imgToDenoiseIndex, temporalWindowSize,
dst, templateWindowSize, searchWindowSize, h));
break;
default:
CV_Error(Error::StsBadArg,
"Unsupported image format! Only CV_8U, CV_8UC2, and CV_8UC3 are supported");
"Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3 and CV_8UC4 are supported");
}
}
@ -280,6 +301,12 @@ void cv::fastNlMeansDenoisingMultiAbs( InputArrayOfArrays _srcImgs, OutputArray
srcImgs, imgToDenoiseIndex, temporalWindowSize,
dst, templateWindowSize, searchWindowSize, h));
break;
case CV_8UC4:
parallel_for_(cv::Range(0, srcImgs[0].rows),
FastNlMeansMultiDenoisingInvoker<cv::Vec4b, int, unsigned, DistAbs>(
srcImgs, imgToDenoiseIndex, temporalWindowSize,
dst, templateWindowSize, searchWindowSize, h));
break;
case CV_16U:
parallel_for_(cv::Range(0, srcImgs[0].rows),
FastNlMeansMultiDenoisingInvoker<ushort, int64, uint64, DistAbs>(
@ -298,9 +325,15 @@ void cv::fastNlMeansDenoisingMultiAbs( InputArrayOfArrays _srcImgs, OutputArray
srcImgs, imgToDenoiseIndex, temporalWindowSize,
dst, templateWindowSize, searchWindowSize, h));
break;
case CV_16UC4:
parallel_for_(cv::Range(0, srcImgs[0].rows),
FastNlMeansMultiDenoisingInvoker<cv::Vec<ushort, 4>, int64, uint64, DistAbs>(
srcImgs, imgToDenoiseIndex, temporalWindowSize,
dst, templateWindowSize, searchWindowSize, h));
break;
default:
CV_Error(Error::StsBadArg,
"Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3, CV_16U, CV_16UC2, and CV_16UC3 are supported");
"Unsupported image format! Only CV_8U, CV_8UC2, CV_8UC3, CV_8UC4, CV_16U, CV_16UC2, CV_16UC3 and CV_16UC4 are supported");
}
}

@ -227,7 +227,7 @@ void FastNlMeansDenoisingInvoker<T, IT, UIT, D>::operator() (const Range& range)
}
// calc weights
IT estimation[3], weights_sum = 0;
IT estimation[pixelInfo<T>::channels], weights_sum = 0;
for (size_t channel_num = 0; channel_num < pixelInfo<T>::channels; channel_num++)
estimation[channel_num] = 0;

@ -110,6 +110,18 @@ class DistAbs
}
};
template <typename ET, typename IT> struct calcDist_<Vec<ET, 4>, IT>
{
static inline IT f(const Vec<ET, 4> a, const Vec<ET, 4> b)
{
return
std::abs((IT)(a[0]-b[0])) +
std::abs((IT)(a[1]-b[1])) +
std::abs((IT)(a[2]-b[2])) +
std::abs((IT)(a[3]-b[3]));
}
};
public:
template <typename T, typename IT> static inline IT calcDist(const T a, const T b)
{
@ -172,6 +184,18 @@ class DistSquared
}
};
template <typename ET, typename IT> struct calcDist_<Vec<ET, 4>, IT>
{
static inline IT f(const Vec<ET, 4> a, const Vec<ET, 4> 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]) +
(IT)(a[3]-b[3])*(IT)(a[3]-b[3]);
}
};
template <typename T, typename IT> struct calcUpDownDist_
{
static inline IT f(T a_up, T a_down, T b_up, T b_down)
@ -254,6 +278,17 @@ template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 3>, IT>
}
};
template <typename ET, typename IT> struct incWithWeight_<Vec<ET, 4>, IT>
{
static inline void f(IT* estimation, IT weight, Vec<ET, 4> p)
{
estimation[0] += weight * p[0];
estimation[1] += weight * p[1];
estimation[2] += weight * p[2];
estimation[3] += weight * p[3];
}
};
template <typename T, typename IT>
static inline void incWithWeight(IT* estimation, IT weight, T p)
{
@ -291,6 +326,19 @@ template <typename ET, typename IT> struct saturateCastFromArray_<Vec<ET, 3>, IT
}
};
template <typename ET, typename IT> struct saturateCastFromArray_<Vec<ET, 4>, IT>
{
static inline Vec<ET, 4> f(IT* estimation)
{
Vec<ET, 4> res;
res[0] = saturate_cast<ET>(estimation[0]);
res[1] = saturate_cast<ET>(estimation[1]);
res[2] = saturate_cast<ET>(estimation[2]);
res[3] = saturate_cast<ET>(estimation[3]);
return res;
}
};
template <typename T, typename IT> static inline T saturateCastFromArray(IT* estimation)
{
return saturateCastFromArray_<T, IT>::f(estimation);

@ -249,7 +249,7 @@ void FastNlMeansMultiDenoisingInvoker<T, IT, UIT, D>::operator() (const Range& r
// calc weights
IT weights_sum = 0;
IT estimation[3];
IT estimation[pixelInfo<T>::channels];
for (size_t channel_num = 0; channel_num < pixelInfo<T>::channels; channel_num++)
estimation[channel_num] = 0;

Loading…
Cancel
Save