OutputArray dst, double inpaintRadius, int flags );
-CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, int h = 3,
+CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, float h = 3,
int templateWindowSize = 7, int searchWindowSize = 21);
CV_EXPORTS_W void fastNlMeansDenoisingColored( InputArray src, OutputArray dst,
- int h = 3, int hColor = 3,
+ float h = 3, float hColor = 3,
int templateWindowSize = 7, int searchWindowSize = 21);
CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst,
int imgToDenoiseIndex, int temporalWindowSize,
- int h = 3, int templateWindowSize = 7, int searchWindowSize = 21);
+ float h = 3, int templateWindowSize = 7, int searchWindowSize = 21);
CV_EXPORTS_W void fastNlMeansDenoisingColoredMulti( InputArrayOfArrays srcImgs, OutputArray dst,
int imgToDenoiseIndex, int temporalWindowSize,
- int h = 3, int hColor = 3,
+ float h = 3, float hColor = 3,
int templateWindowSize = 7, int searchWindowSize = 21);
}
#include "fast_nlmeans_denoising_invoker.hpp"
#include "fast_nlmeans_multi_denoising_invoker.hpp"
-void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, int h,
+void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, float h,
int templateWindowSize, int searchWindowSize)
{
Mat src = _src.getMat();
}
void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst,
- int h, int hForColorComponents,
+ float h, float hForColorComponents,
int templateWindowSize, int searchWindowSize)
{
Mat src = _src.getMat();
void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
int imgToDenoiseIndex, int temporalWindowSize,
- int h, int templateWindowSize, int searchWindowSize)
+ float h, int templateWindowSize, int searchWindowSize)
{
vector<Mat> srcImgs;
_srcImgs.getMatVector(srcImgs);
void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
int imgToDenoiseIndex, int temporalWindowSize,
- int h, int hForColorComponents,
+ float h, float hForColorComponents,
int templateWindowSize, int searchWindowSize)
{
vector<Mat> srcImgs;
struct FastNlMeansDenoisingInvoker {
public:
FastNlMeansDenoisingInvoker(const Mat& src, Mat& dst,
- int template_window_size, int search_window_size, const double h);
+ int template_window_size, int search_window_size, const float h);
void operator() (const BlockedRange& range) const;
cv::Mat& dst,
int template_window_size,
int search_window_size,
- const double 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
almost_template_window_size_sq_bin_shift_ = getNearestPowerOf2(template_window_size_sq);
double almost_dist2actual_dist_multiplier = ((double)(1 << almost_template_window_size_sq_bin_shift_)) / template_window_size_sq;
- int max_dist = 256 * 256 * src_.channels();
+ int max_dist = 255 * 255 * sizeof(T);
int almost_max_dist = (int) (max_dist / almost_dist2actual_dist_multiplier + 1);
almost_dist2weight_.resize(almost_max_dist);
const double WEIGHT_THRESHOLD = 0.001;
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 * src_.channels())));
+ int weight = cvRound(fixed_point_mult_ * std::exp(-dist / (h * h * sizeof(T))));
- if (weight < WEIGHT_THRESHOLD * fixed_point_mult_) {
+ if (weight < WEIGHT_THRESHOLD * fixed_point_mult_)
weight = 0;
- }
almost_dist2weight_[almost_dist] = weight;
}
+ CV_Assert(almost_dist2weight_[0] == fixed_point_mult_);
// additional optimization init end
if (dst_.empty()) {
int weights_sum = 0;
int estimation[3];
- for (int channel_num = 0; channel_num < src_.channels(); channel_num++) {
+ for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++) {
estimation[channel_num] = 0;
}
}
}
- if (weights_sum > 0) {
- for (int channel_num = 0; channel_num < src_.channels(); channel_num++)
- estimation[channel_num] = (estimation[channel_num] + weights_sum/2) / weights_sum;
-
- dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation);
+ for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++)
+ estimation[channel_num] = (estimation[channel_num] + weights_sum/2) / weights_sum;
- } else { // weights_sum == 0
- dst_.at<T>(i,j) = src_.at<T>(i,j);
- }
+ dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation);
}
}
}
public:
FastNlMeansMultiDenoisingInvoker(
const std::vector<Mat>& srcImgs, int imgToDenoiseIndex, int temporalWindowSize,
- Mat& dst, int template_window_size, int search_window_size, const double h);
+ Mat& dst, int template_window_size, int search_window_size, const float h);
void operator() (const BlockedRange& range) const;
- void operator= (const FastNlMeansMultiDenoisingInvoker&) {
- CV_Error(CV_StsNotImplemented, "Assigment operator is not implemented");
- }
-
private:
+ void operator= (const FastNlMeansMultiDenoisingInvoker&);
+
int rows_;
int cols_;
- int channels_count_;
Mat& dst_;
cv::Mat& dst,
int template_window_size,
int search_window_size,
- const double h) : dst_(dst), extended_srcs_(srcImgs.size())
+ const float h) : dst_(dst), extended_srcs_(srcImgs.size())
{
CV_Assert(srcImgs.size() > 0);
- CV_Assert(srcImgs[0].channels() <= 3);
+ CV_Assert(srcImgs[0].channels() == sizeof(T));
rows_ = srcImgs[0].rows;
cols_ = srcImgs[0].cols;
- channels_count_ = srcImgs[0].channels();
template_window_half_size_ = template_window_size / 2;
search_window_half_size_ = search_window_size / 2;
double almost_dist2actual_dist_multiplier =
((double) almost_template_window_size_sq) / template_window_size_sq;
- int max_dist = 256 * 256 * channels_count_;
+ int max_dist = 255 * 255 * sizeof(T);
int almost_max_dist = (int) (max_dist / almost_dist2actual_dist_multiplier + 1);
almost_dist2weight.resize(almost_max_dist);
const double WEIGHT_THRESHOLD = 0.001;
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 * channels_count_)));
+ int weight = cvRound(fixed_point_mult_ * std::exp(-dist / (h * h * sizeof(T))));
if (weight < WEIGHT_THRESHOLD * fixed_point_mult_) {
weight = 0;
almost_dist2weight[almost_dist] = weight;
}
+ CV_Assert(almost_dist2weight[0] == fixed_point_mult_);
// additional optimization init end
if (dst_.empty()) {
int weights_sum = 0;
int estimation[3];
- for (int channel_num = 0; channel_num < channels_count_; channel_num++) {
+ for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++) {
estimation[channel_num] = 0;
}
for (int d = 0; d < temporal_window_size_; d++) {
}
}
- if (weights_sum > 0) {
- for (int channel_num = 0; channel_num < channels_count_; channel_num++)
- estimation[channel_num] = (estimation[channel_num] + weights_sum / 2) / weights_sum;
+ for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++)
+ estimation[channel_num] = (estimation[channel_num] + weights_sum / 2) / weights_sum;
- dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation);
+ dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation);
- } else { // weights_sum == 0
- const Mat& esrc = extended_srcs_[temporal_window_half_size_];
- dst_.at<T>(i,j) = esrc.at<T>(i,j);
- }
}
}
}