Merge remote-tracking branch 'origin/master'

pull/32/head
Vadim Pisarevsky 13 years ago
commit 54705a009a
  1. BIN
      3rdparty/ffmpeg/opencv_ffmpeg.dll
  2. BIN
      3rdparty/ffmpeg/opencv_ffmpeg_64.dll
  3. 22
      modules/photo/include/opencv2/photo/photo.hpp
  4. 32
      modules/photo/src/denoising.cpp
  5. 6
      modules/photo/src/fast_nlmeans_denoising_invoker.hpp
  6. 6
      modules/photo/src/fast_nlmeans_multi_denoising_invoker.hpp
  7. 195
      modules/photo/test/test_denoising.cpp

Binary file not shown.

Binary file not shown.

@ -68,26 +68,24 @@ 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, CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, int h = 3,
int templateWindowSize, int searchWindowSize, int h); 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 templateWindowSize, int searchWindowSize, int h = 3, int hColor = 3,
int h, int hForColorComponents); int templateWindowSize = 7, int searchWindowSize = 21);
CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst,
int imgToDenoiseIndex, int temporalWindowSize, int imgToDenoiseIndex, int temporalWindowSize,
OutputArray dst, int h = 3, int templateWindowSize = 7, int searchWindowSize = 21);
int templateWindowSize, int searchWindowSize, int h);
CV_EXPORTS_W void fastNlMeansDenoisingColoredMulti( InputArrayOfArrays srcImgs, CV_EXPORTS_W void fastNlMeansDenoisingColoredMulti( InputArrayOfArrays srcImgs, OutputArray dst,
int imgToDenoiseIndex, int temporalWindowSize, int imgToDenoiseIndex, int temporalWindowSize,
OutputArray dst, int h = 3, int hColor = 3,
int templateWindowSize, int searchWindowSize, int templateWindowSize = 7, int searchWindowSize = 21);
int h, int hForColorComponents);
} }
#endif #endif //__cplusplus
#endif #endif

@ -45,8 +45,8 @@
#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, void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst, int h,
int templateWindowSize, int searchWindowSize, int h) int templateWindowSize, int searchWindowSize)
{ {
Mat src = _src.getMat(); Mat src = _src.getMat();
_dst.create(src.size(), src.type()); _dst.create(src.size(), src.type());
@ -75,8 +75,8 @@ void cv::fastNlMeansDenoising( InputArray _src, OutputArray _dst,
} }
void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst, void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst,
int templateWindowSize, int searchWindowSize, int h, int hForColorComponents,
int h, int hForColorComponents) int templateWindowSize, int searchWindowSize)
{ {
Mat src = _src.getMat(); Mat src = _src.getMat();
_dst.create(src.size(), src.type()); _dst.create(src.size(), src.type());
@ -96,8 +96,8 @@ void cv::fastNlMeansDenoisingColored( InputArray _src, OutputArray _dst,
int from_to[] = { 0,0, 1,1, 2,2 }; int from_to[] = { 0,0, 1,1, 2,2 };
mixChannels(&src_lab, 1, l_ab, 2, from_to, 3); mixChannels(&src_lab, 1, l_ab, 2, from_to, 3);
fastNlMeansDenoising(l, l, templateWindowSize, searchWindowSize, h); fastNlMeansDenoising(l, l, h, templateWindowSize, searchWindowSize);
fastNlMeansDenoising(ab, ab, templateWindowSize, searchWindowSize, hForColorComponents); fastNlMeansDenoising(ab, ab, hForColorComponents, templateWindowSize, searchWindowSize);
Mat l_ab_denoised[] = { l, ab }; Mat l_ab_denoised[] = { l, ab };
Mat dst_lab(src.size(), src.type()); Mat dst_lab(src.size(), src.type());
@ -138,10 +138,9 @@ static void fastNlMeansDenoisingMultiCheckPreconditions(
} }
} }
void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
int imgToDenoiseIndex, int temporalWindowSize, int imgToDenoiseIndex, int temporalWindowSize,
OutputArray _dst, int h, int templateWindowSize, int searchWindowSize)
int templateWindowSize, int searchWindowSize, int h)
{ {
vector<Mat> srcImgs; vector<Mat> srcImgs;
_srcImgs.getMatVector(srcImgs); _srcImgs.getMatVector(srcImgs);
@ -178,11 +177,10 @@ void cv::fastNlMeansDenoisingMulti( InputArrayOfArrays _srcImgs,
} }
} }
void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs, void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs, OutputArray _dst,
int imgToDenoiseIndex, int temporalWindowSize, int imgToDenoiseIndex, int temporalWindowSize,
OutputArray _dst, int h, int hForColorComponents,
int templateWindowSize, int searchWindowSize, int templateWindowSize, int searchWindowSize)
int h, int hForColorComponents)
{ {
vector<Mat> srcImgs; vector<Mat> srcImgs;
_srcImgs.getMatVector(srcImgs); _srcImgs.getMatVector(srcImgs);
@ -222,12 +220,12 @@ void cv::fastNlMeansDenoisingColoredMulti( InputArrayOfArrays _srcImgs,
Mat dst_ab; Mat dst_ab;
fastNlMeansDenoisingMulti( fastNlMeansDenoisingMulti(
l, imgToDenoiseIndex, temporalWindowSize, l, dst_l, imgToDenoiseIndex, temporalWindowSize,
dst_l, templateWindowSize, searchWindowSize, h); h, templateWindowSize, searchWindowSize);
fastNlMeansDenoisingMulti( fastNlMeansDenoisingMulti(
ab, imgToDenoiseIndex, temporalWindowSize, ab, dst_ab, imgToDenoiseIndex, temporalWindowSize,
dst_ab, templateWindowSize, searchWindowSize, hForColorComponents); hForColorComponents, templateWindowSize, searchWindowSize);
Mat l_ab_denoised[] = { dst_l, dst_ab }; Mat l_ab_denoised[] = { dst_l, dst_ab };
Mat dst_lab(srcImgs[0].size(), srcImgs[0].type()); Mat dst_lab(srcImgs[0].size(), srcImgs[0].type());

@ -257,10 +257,8 @@ void FastNlMeansDenoisingInvoker<T>::operator() (const BlockedRange& range) cons
} }
if (weights_sum > 0) { if (weights_sum > 0) {
for (int channel_num = 0; channel_num < src_.channels(); channel_num++) { for (int channel_num = 0; channel_num < src_.channels(); channel_num++)
estimation[channel_num] = estimation[channel_num] = (estimation[channel_num] + weights_sum/2) / weights_sum;
cvRound(((double)estimation[channel_num]) / weights_sum);
}
dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation); dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation);

@ -290,10 +290,8 @@ void FastNlMeansMultiDenoisingInvoker<T>::operator() (const BlockedRange& range)
} }
if (weights_sum > 0) { if (weights_sum > 0) {
for (int channel_num = 0; channel_num < channels_count_; channel_num++) { for (int channel_num = 0; channel_num < channels_count_; channel_num++)
estimation[channel_num] = estimation[channel_num] = (estimation[channel_num] + weights_sum / 2) / weights_sum;
cvRound(((double)estimation[channel_num]) / weights_sum);
}
dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation); dst_.at<T>(i,j) = saturateCastFromArray<T>(estimation);

@ -47,167 +47,102 @@
using namespace cv; using namespace cv;
using namespace std; using namespace std;
class CV_DenoisingGrayscaleTest : public cvtest::BaseTest //#define DUMP_RESULTS
{
public: #ifdef DUMP_RESULTS
CV_DenoisingGrayscaleTest(); # define DUMP(image, path) imwrite(path, image)
~CV_DenoisingGrayscaleTest(); #else
protected: # define FUMP(image, path)
void run(int); #endif
};
CV_DenoisingGrayscaleTest::CV_DenoisingGrayscaleTest() {}
CV_DenoisingGrayscaleTest::~CV_DenoisingGrayscaleTest() {}
void CV_DenoisingGrayscaleTest::run( int ) TEST(Imgproc_DenoisingGrayscale, regression)
{ {
string folder = string(ts->get_data_path()) + "denoising/"; string folder = string(cvtest::TS::ptr()->get_data_path()) + "denoising/";
Mat orig = imread(folder + "lena_noised_gaussian_sigma=10.png", 0); string original_path = folder + "lena_noised_gaussian_sigma=10.png";
Mat exp = imread(folder + "lena_noised_denoised_grayscale_tw=7_sw=21_h=10.png", 0); string expected_path = folder + "lena_noised_denoised_grayscale_tw=7_sw=21_h=10.png";
if (orig.empty() || exp.empty()) Mat original = imread(original_path, CV_LOAD_IMAGE_GRAYSCALE);
{ Mat expected = imread(expected_path, CV_LOAD_IMAGE_GRAYSCALE);
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
}
Mat res; ASSERT_FALSE(original.empty()) << "Could not load input image " << original_path;
fastNlMeansDenoising(orig, res, 7, 21, 10); ASSERT_FALSE(expected.empty()) << "Could not load reference image " << expected_path;
if (norm(res - exp) > 0) { Mat result;
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); fastNlMeansDenoising(original, result, 10);
} else {
ts->set_failed_test_info(cvtest::TS::OK); DUMP(result, expected_path + ".res.png");
}
ASSERT_EQ(0, norm(result != expected));
} }
class CV_DenoisingColoredTest : public cvtest::BaseTest TEST(Imgproc_DenoisingColored, regression)
{ {
public: string folder = string(cvtest::TS::ptr()->get_data_path()) + "denoising/";
CV_DenoisingColoredTest(); string original_path = folder + "lena_noised_gaussian_sigma=10.png";
~CV_DenoisingColoredTest(); string expected_path = folder + "lena_noised_denoised_lab12_tw=7_sw=21_h=10_h2=10.png";
protected:
void run(int);
};
CV_DenoisingColoredTest::CV_DenoisingColoredTest() {} Mat original = imread(original_path, CV_LOAD_IMAGE_COLOR);
CV_DenoisingColoredTest::~CV_DenoisingColoredTest() {} Mat expected = imread(expected_path, CV_LOAD_IMAGE_COLOR);
void CV_DenoisingColoredTest::run( int ) ASSERT_FALSE(original.empty()) << "Could not load input image " << original_path;
{ ASSERT_FALSE(expected.empty()) << "Could not load reference image " << expected_path;
string folder = string(ts->get_data_path()) + "denoising/";
Mat orig = imread(folder + "lena_noised_gaussian_sigma=10.png", 1);
Mat exp = imread(folder + "lena_noised_denoised_lab12_tw=7_sw=21_h=10_h2=10.png", 1);
if (orig.empty() || exp.empty()) Mat result;
{ fastNlMeansDenoisingColored(original, result, 10, 10);
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
}
Mat res; DUMP(result, expected_path + ".res.png");
fastNlMeansDenoisingColored(orig, res, 7, 21, 10, 10);
if (norm(res - exp) > 0) { ASSERT_EQ(0, norm(result != expected));
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
} else {
ts->set_failed_test_info(cvtest::TS::OK);
}
} }
class CV_DenoisingGrayscaleMultiTest : public cvtest::BaseTest TEST(Imgproc_DenoisingGrayscaleMulti, regression)
{ {
public:
CV_DenoisingGrayscaleMultiTest();
~CV_DenoisingGrayscaleMultiTest();
protected:
void run(int);
};
CV_DenoisingGrayscaleMultiTest::CV_DenoisingGrayscaleMultiTest() {}
CV_DenoisingGrayscaleMultiTest::~CV_DenoisingGrayscaleMultiTest() {}
void CV_DenoisingGrayscaleMultiTest::run( int )
{
string folder = string(ts->get_data_path()) + "denoising/";
const int imgs_count = 3; const int imgs_count = 3;
vector<Mat> src_imgs(imgs_count); string folder = string(cvtest::TS::ptr()->get_data_path()) + "denoising/";
src_imgs[0] = imread(folder + "lena_noised_gaussian_sigma=20_multi_0.png", 0);
src_imgs[1] = imread(folder + "lena_noised_gaussian_sigma=20_multi_1.png", 0); string expected_path = folder + "lena_noised_denoised_multi_tw=7_sw=21_h=15.png";
src_imgs[2] = imread(folder + "lena_noised_gaussian_sigma=20_multi_2.png", 0); Mat expected = imread(expected_path, CV_LOAD_IMAGE_GRAYSCALE);
ASSERT_FALSE(expected.empty()) << "Could not load reference image " << expected_path;
Mat exp = imread(folder + "lena_noised_denoised_multi_tw=7_sw=21_h=15.png", 0);
bool have_empty_src = false;
for (int i = 0; i < imgs_count; i++) {
have_empty_src |= src_imgs[i].empty();
}
if (have_empty_src || exp.empty()) vector<Mat> original(imgs_count);
for (int i = 0; i < imgs_count; i++)
{ {
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); string original_path = format("%slena_noised_gaussian_sigma=20_multi_%d.png", folder.c_str(), i);
return; original[i] = imread(original_path, CV_LOAD_IMAGE_GRAYSCALE);
ASSERT_FALSE(original[i].empty()) << "Could not load input image " << original_path;
} }
Mat res; Mat result;
fastNlMeansDenoisingMulti(src_imgs, imgs_count / 2, imgs_count, res, 7, 21, 15); fastNlMeansDenoisingMulti(original, result, imgs_count / 2, imgs_count, 15);
if (norm(res - exp) > 0) { DUMP(result, expected_path + ".res.png");
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
} else { ASSERT_EQ(0, norm(result != expected));
ts->set_failed_test_info(cvtest::TS::OK);
}
} }
class CV_DenoisingColoredMultiTest : public cvtest::BaseTest TEST(Imgproc_DenoisingColoredMulti, regression)
{ {
public:
CV_DenoisingColoredMultiTest();
~CV_DenoisingColoredMultiTest();
protected:
void run(int);
};
CV_DenoisingColoredMultiTest::CV_DenoisingColoredMultiTest() {}
CV_DenoisingColoredMultiTest::~CV_DenoisingColoredMultiTest() {}
void CV_DenoisingColoredMultiTest::run( int )
{
string folder = string(ts->get_data_path()) + "denoising/";
const int imgs_count = 3; const int imgs_count = 3;
vector<Mat> src_imgs(imgs_count); string folder = string(cvtest::TS::ptr()->get_data_path()) + "denoising/";
src_imgs[0] = imread(folder + "lena_noised_gaussian_sigma=20_multi_0.png", 1);
src_imgs[1] = imread(folder + "lena_noised_gaussian_sigma=20_multi_1.png", 1); string expected_path = folder + "lena_noised_denoised_multi_lab12_tw=7_sw=21_h=10_h2=15.png";
src_imgs[2] = imread(folder + "lena_noised_gaussian_sigma=20_multi_2.png", 1); Mat expected = imread(expected_path, CV_LOAD_IMAGE_COLOR);
ASSERT_FALSE(expected.empty()) << "Could not load reference image " << expected_path;
Mat exp = imread(folder + "lena_noised_denoised_multi_lab12_tw=7_sw=21_h=10_h2=15.png", 1);
bool have_empty_src = false;
for (int i = 0; i < imgs_count; i++) {
have_empty_src |= src_imgs[i].empty();
}
if (have_empty_src || exp.empty()) vector<Mat> original(imgs_count);
for (int i = 0; i < imgs_count; i++)
{ {
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); string original_path = format("%slena_noised_gaussian_sigma=20_multi_%d.png", folder.c_str(), i);
return; original[i] = imread(original_path, CV_LOAD_IMAGE_COLOR);
ASSERT_FALSE(original[i].empty()) << "Could not load input image " << original_path;
} }
Mat res; Mat result;
fastNlMeansDenoisingColoredMulti(src_imgs, imgs_count / 2, imgs_count, res, 7, 21, 10, 15); fastNlMeansDenoisingColoredMulti(original, result, imgs_count / 2, imgs_count, 10, 15);
if (norm(res - exp) > 0) {
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
} else {
ts->set_failed_test_info(cvtest::TS::OK);
}
}
DUMP(result, expected_path + ".res.png");
TEST(Imgproc_DenoisingGrayscale, regression) { CV_DenoisingGrayscaleTest test; test.safe_run(); } ASSERT_EQ(0, norm(result != expected));
TEST(Imgproc_DenoisingColored, regression) { CV_DenoisingColoredTest test; test.safe_run(); } }
TEST(Imgproc_DenoisingGrayscaleMulti, regression) { CV_DenoisingGrayscaleMultiTest test; test.safe_run(); }
TEST(Imgproc_DenoisingColoredMulti, regression) { CV_DenoisingColoredMultiTest test; test.safe_run(); }

Loading…
Cancel
Save