Merge branch 'master' of git://code.opencv.org/opencv

This commit is contained in:
Alexander Kapustin 2012-09-20 17:32:54 +04:00
commit 858f437162
4 changed files with 30 additions and 43 deletions

View File

@ -68,20 +68,20 @@ CV_EXPORTS_W void inpaint( InputArray src, InputArray inpaintMask,
OutputArray dst, double inpaintRadius, int flags ); 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); int templateWindowSize = 7, int searchWindowSize = 21);
CV_EXPORTS_W void fastNlMeansDenoisingColored( InputArray src, OutputArray dst, 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); int templateWindowSize = 7, int searchWindowSize = 21);
CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst, CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst,
int imgToDenoiseIndex, int temporalWindowSize, 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, CV_EXPORTS_W void fastNlMeansDenoisingColoredMulti( InputArrayOfArrays srcImgs, OutputArray dst,
int imgToDenoiseIndex, int temporalWindowSize, int imgToDenoiseIndex, int temporalWindowSize,
int h = 3, int hColor = 3, float h = 3, float hColor = 3,
int templateWindowSize = 7, int searchWindowSize = 21); int templateWindowSize = 7, int searchWindowSize = 21);
} }

View File

@ -45,7 +45,7 @@
#include "fast_nlmeans_denoising_invoker.hpp" #include "fast_nlmeans_denoising_invoker.hpp"
#include "fast_nlmeans_multi_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) int templateWindowSize, int searchWindowSize)
{ {
Mat src = _src.getMat(); Mat src = _src.getMat();
@ -75,7 +75,7 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, int h,
} }
void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst, void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst,
int h, int hForColorComponents, float h, float hForColorComponents,
int templateWindowSize, int searchWindowSize) int templateWindowSize, int searchWindowSize)
{ {
Mat src = _src.getMat(); Mat src = _src.getMat();
@ -140,7 +140,7 @@ static void fastNlMeansDenoisingMultiCheckPreconditions(
void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst, void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
int imgToDenoiseIndex, int temporalWindowSize, int imgToDenoiseIndex, int temporalWindowSize,
int h, int templateWindowSize, int searchWindowSize) float h, int templateWindowSize, int searchWindowSize)
{ {
vector<Mat> srcImgs; vector<Mat> srcImgs;
_srcImgs.getMatVector(srcImgs); _srcImgs.getMatVector(srcImgs);
@ -179,7 +179,7 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _ds
void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs, OutputArray _dst, void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
int imgToDenoiseIndex, int temporalWindowSize, int imgToDenoiseIndex, int temporalWindowSize,
int h, int hForColorComponents, float h, float hForColorComponents,
int templateWindowSize, int searchWindowSize) int templateWindowSize, int searchWindowSize)
{ {
vector<Mat> srcImgs; vector<Mat> srcImgs;

View File

@ -58,7 +58,7 @@ template <typename T>
struct FastNlMeansDenoisingInvoker { struct FastNlMeansDenoisingInvoker {
public: public:
FastNlMeansDenoisingInvoker(const Mat& src, Mat& dst, 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; void operator() (const BlockedRange& range) const;
@ -109,7 +109,7 @@ FastNlMeansDenoisingInvoker<T>::FastNlMeansDenoisingInvoker(
cv::Mat& dst, cv::Mat& dst,
int template_window_size, int template_window_size,
int search_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 CV_Assert(src.channels() == sizeof(T)); //T is Vec1b or Vec2b or Vec3b
@ -133,21 +133,21 @@ FastNlMeansDenoisingInvoker<T>::FastNlMeansDenoisingInvoker(
almost_template_window_size_sq_bin_shift_ = getNearestPowerOf2(template_window_size_sq); 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; 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); int almost_max_dist = (int) (max_dist / almost_dist2actual_dist_multiplier + 1);
almost_dist2weight_.resize(almost_max_dist); almost_dist2weight_.resize(almost_max_dist);
const double WEIGHT_THRESHOLD = 0.001; 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; 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; weight = 0;
}
almost_dist2weight_[almost_dist] = weight; almost_dist2weight_[almost_dist] = weight;
} }
CV_Assert(almost_dist2weight_[0] == fixed_point_mult_);
// additional optimization init end // additional optimization init end
if (dst_.empty()) { if (dst_.empty()) {
@ -237,7 +237,7 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const BlockedRange& range) cons
int weights_sum = 0; int weights_sum = 0;
int estimation[3]; 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; estimation[channel_num] = 0;
} }
@ -256,15 +256,10 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const BlockedRange& range) cons
} }
} }
if (weights_sum > 0) { for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++)
for (int channel_num = 0; channel_num < src_.channels(); channel_num++) estimation[channel_num] = (estimation[channel_num] + weights_sum/2) / weights_sum;
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
dst_.at<T>(i,j) = src_.at<T>(i,j);
}
} }
} }
} }

View File

@ -59,18 +59,15 @@ struct FastNlMeansMultiDenoisingInvoker {
public: public:
FastNlMeansMultiDenoisingInvoker( FastNlMeansMultiDenoisingInvoker(
const std::vector<Mat>& srcImgs, int imgToDenoiseIndex, int temporalWindowSize, 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 BlockedRange& range) const;
void operator= (const FastNlMeansMultiDenoisingInvoker&) {
CV_Error(CV_StsNotImplemented, "Assigment operator is not implemented");
}
private: private:
void operator= (const FastNlMeansMultiDenoisingInvoker&);
int rows_; int rows_;
int cols_; int cols_;
int channels_count_;
Mat& dst_; Mat& dst_;
@ -113,14 +110,13 @@ FastNlMeansMultiDenoisingInvoker<T>::FastNlMeansMultiDenoisingInvoker(
cv::Mat& dst, cv::Mat& dst,
int template_window_size, int template_window_size,
int search_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.size() > 0);
CV_Assert(srcImgs[0].channels() <= 3); CV_Assert(srcImgs[0].channels() == sizeof(T));
rows_ = srcImgs[0].rows; rows_ = srcImgs[0].rows;
cols_ = srcImgs[0].cols; cols_ = srcImgs[0].cols;
channels_count_ = srcImgs[0].channels();
template_window_half_size_ = template_window_size / 2; template_window_half_size_ = template_window_size / 2;
search_window_half_size_ = search_window_size / 2; search_window_half_size_ = search_window_size / 2;
@ -155,14 +151,14 @@ FastNlMeansMultiDenoisingInvoker<T>::FastNlMeansMultiDenoisingInvoker(
double almost_dist2actual_dist_multiplier = double almost_dist2actual_dist_multiplier =
((double) almost_template_window_size_sq) / template_window_size_sq; ((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); int almost_max_dist = (int) (max_dist / almost_dist2actual_dist_multiplier + 1);
almost_dist2weight.resize(almost_max_dist); almost_dist2weight.resize(almost_max_dist);
const double WEIGHT_THRESHOLD = 0.001; 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; 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_) { if (weight < WEIGHT_THRESHOLD * fixed_point_mult_) {
weight = 0; weight = 0;
@ -170,6 +166,7 @@ FastNlMeansMultiDenoisingInvoker<T>::FastNlMeansMultiDenoisingInvoker(
almost_dist2weight[almost_dist] = weight; almost_dist2weight[almost_dist] = weight;
} }
CV_Assert(almost_dist2weight[0] == fixed_point_mult_);
// additional optimization init end // additional optimization init end
if (dst_.empty()) { if (dst_.empty()) {
@ -266,7 +263,7 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
int weights_sum = 0; int weights_sum = 0;
int estimation[3]; 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; estimation[channel_num] = 0;
} }
for (int d = 0; d < temporal_window_size_; d++) { for (int d = 0; d < temporal_window_size_; d++) {
@ -289,16 +286,11 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
} }
} }
if (weights_sum > 0) { for (size_t channel_num = 0; channel_num < sizeof(T); channel_num++)
for (int channel_num = 0; channel_num < channels_count_; channel_num++) estimation[channel_num] = (estimation[channel_num] + weights_sum / 2) / weights_sum;
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);
}
} }
} }
} }