vendor: OpenCV 5.0.0 snapshot at 40738fb16ceddb5fb3fea747585f7ce6abb0605b

This commit is contained in:
Gitea Mirror Bot
2026-08-22 00:10:33 +08:00
commit f7f077da11
6933 changed files with 2335208 additions and 0 deletions
+133
View File
@@ -0,0 +1,133 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
#include "../test_precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
#ifdef HAVE_OPENCL
namespace opencv_test {
namespace ocl {
PARAM_TEST_CASE(FastNlMeansDenoisingTestBase, Channels, int, bool, bool)
{
int cn, normType, templateWindowSize, searchWindowSize;
std::vector<float> h;
bool use_roi, use_image;
TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp()
{
cn = GET_PARAM(0);
normType = GET_PARAM(1);
use_roi = GET_PARAM(2);
use_image = GET_PARAM(3);
templateWindowSize = 7;
searchWindowSize = 21;
h.resize(cn);
for (int i=0; i<cn; i++)
h[i] = 3.0f + 0.5f*i;
}
void generateTestData()
{
const int type = CV_8UC(cn);
Mat image;
if (use_image) {
image = readImage("denoising/lena_noised_gaussian_sigma=10.png",
cn == 1 ? IMREAD_GRAYSCALE : IMREAD_COLOR);
ASSERT_FALSE(image.empty());
}
Size roiSize = use_image ? image.size() : randomSize(1, MAX_VALUE);
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src, src_roi, roiSize, srcBorder, type, 0, 255);
if (use_image) {
ASSERT_TRUE(cn > 0 && cn <= 4);
if (cn == 2) {
int from_to[] = { 0,0, 1,1 };
src_roi.create(roiSize, type);
mixChannels(&image, 1, &src_roi, 1, from_to, 2);
}
else if (cn == 4) {
int from_to[] = { 0,0, 1,1, 2,2, 1,3};
src_roi.create(roiSize, type);
mixChannels(&image, 1, &src_roi, 1, from_to, 4);
}
else image.copyTo(src_roi);
}
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, type, 0, 255);
UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
}
};
typedef FastNlMeansDenoisingTestBase FastNlMeansDenoising;
OCL_TEST_P(FastNlMeansDenoising, Mat)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
OCL_OFF(cv::fastNlMeansDenoising(src_roi, dst_roi, std::vector<float>(1, h[0]), templateWindowSize, searchWindowSize, normType));
OCL_ON(cv::fastNlMeansDenoising(usrc_roi, udst_roi, std::vector<float>(1, h[0]), templateWindowSize, searchWindowSize, normType));
OCL_EXPECT_MATS_NEAR(dst, 1);
}
}
typedef FastNlMeansDenoisingTestBase FastNlMeansDenoising_hsep;
OCL_TEST_P(FastNlMeansDenoising_hsep, Mat)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
OCL_OFF(cv::fastNlMeansDenoising(src_roi, dst_roi, h, templateWindowSize, searchWindowSize, normType));
OCL_ON(cv::fastNlMeansDenoising(usrc_roi, udst_roi, h, templateWindowSize, searchWindowSize, normType));
OCL_EXPECT_MATS_NEAR(dst, 1);
}
}
typedef FastNlMeansDenoisingTestBase FastNlMeansDenoisingColored;
OCL_TEST_P(FastNlMeansDenoisingColored, Mat)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
OCL_OFF(cv::fastNlMeansDenoisingColored(src_roi, dst_roi, h[0], h[0], templateWindowSize, searchWindowSize));
OCL_ON(cv::fastNlMeansDenoisingColored(usrc_roi, udst_roi, h[0], h[0], templateWindowSize, searchWindowSize));
OCL_EXPECT_MATS_NEAR(dst, 1);
}
}
OCL_INSTANTIATE_TEST_CASE_P(Photo, FastNlMeansDenoising,
Combine(Values(1, 2, 3, 4), Values((int)NORM_L2, (int)NORM_L1),
Bool(), Values(true)));
OCL_INSTANTIATE_TEST_CASE_P(Photo, FastNlMeansDenoising_hsep,
Combine(Values(1, 2, 3, 4), Values((int)NORM_L2, (int)NORM_L1),
Bool(), Values(true)));
OCL_INSTANTIATE_TEST_CASE_P(Photo, FastNlMeansDenoisingColored,
Combine(Values(3, 4), Values((int)NORM_L2), Bool(), Values(false)));
} } // namespace opencv_test::ocl
#endif // HAVE_OPENCL
+302
View File
@@ -0,0 +1,302 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
namespace opencv_test
{
namespace
{
Mat s = (Mat_<Vec3d>(24, 1) <<
Vec3d(214.11, 98.67, 37.97),
Vec3d(231.94, 153.1, 85.27),
Vec3d(204.08, 143.71, 78.46),
Vec3d(190.58, 122.99, 30.84),
Vec3d(230.93, 148.46, 100.84),
Vec3d(228.64, 206.97, 97.5),
Vec3d(229.09, 137.07, 55.29),
Vec3d(189.21, 111.22, 92.66),
Vec3d(223.5, 96.42, 75.45),
Vec3d(201.82, 69.71, 50.9),
Vec3d(240.52, 196.47, 59.3),
Vec3d(235.73, 172.13, 54.),
Vec3d(131.6, 75.04, 68.86),
Vec3d(189.04, 170.43, 42.05),
Vec3d(222.23, 74., 71.95),
Vec3d(241.01, 199.1, 61.15),
Vec3d(224.99, 101.4, 100.24),
Vec3d(174.58, 152.63, 91.52),
Vec3d(248.06, 227.69, 140.5),
Vec3d(241.15, 201.38, 115.58),
Vec3d(236.49, 175.87, 88.86),
Vec3d(212.19, 133.49, 54.79),
Vec3d(181.17, 102.94, 36.18),
Vec3d(115.1, 53.77, 15.23));
TEST(Photo_ColorCorrection, test_model)
{
cv::ccm::ColorCorrectionModel model(s / 255, cv::ccm::COLORCHECKER_MACBETH);
Mat colorCorrectionMat = model.compute();
Mat srcRgbl = (Mat_<Vec3d>(24, 1) <<
Vec3d(0.68078957, 0.12382801, 0.01514889),
Vec3d(0.81177942, 0.32550452, 0.089818),
Vec3d(0.61259378, 0.2831933, 0.07478902),
Vec3d(0.52696493, 0.20105976, 0.00958657),
Vec3d(0.80402284, 0.30419523, 0.12989841),
Vec3d(0.78658646, 0.63184111, 0.12062068),
Vec3d(0.78999637, 0.25520249, 0.03462853),
Vec3d(0.51866697, 0.16114393, 0.1078387),
Vec3d(0.74820768, 0.11770076, 0.06862177),
Vec3d(0.59776825, 0.05765816, 0.02886627),
Vec3d(0.8793145, 0.56346033, 0.0403954),
Vec3d(0.84124847, 0.42120746, 0.03287592),
Vec3d(0.23333214, 0.06780408, 0.05612276),
Vec3d(0.5176423, 0.41210976, 0.01896255),
Vec3d(0.73888613, 0.06575388, 0.06181293),
Vec3d(0.88326036, 0.58018751, 0.04321991),
Vec3d(0.75922531, 0.13149072, 0.1282041),
Vec3d(0.4345097, 0.32331019, 0.10494139),
Vec3d(0.94110142, 0.77941419, 0.26946323),
Vec3d(0.88438952, 0.5949049 , 0.17536928),
Vec3d(0.84722687, 0.44160449, 0.09834799),
Vec3d(0.66743106, 0.24076803, 0.03394333),
Vec3d(0.47141286, 0.13592419, 0.01362205),
Vec3d(0.17377101, 0.03256864, 0.00203026));
EXPECT_MAT_NEAR(srcRgbl, model.getSrcLinearRGB(), 1e-4);
Mat dstRgbl = (Mat_<Vec3d>(24, 1) <<
Vec3d(0.17303173, 0.08211037, 0.05672686),
Vec3d(0.56832031, 0.29269488, 0.21835529),
Vec3d(0.10365019, 0.19588357, 0.33140475),
Vec3d(0.10159676, 0.14892193, 0.05188294),
Vec3d(0.22159627, 0.21584476, 0.43461196),
Vec3d(0.10806379, 0.51437196, 0.41264213),
Vec3d(0.74736423, 0.20062878, 0.02807988),
Vec3d(0.05757947, 0.10516793, 0.40296109),
Vec3d(0.56676218, 0.08424805, 0.11969461),
Vec3d(0.11099515, 0.04230796, 0.14292554),
Vec3d(0.34546869, 0.50872001, 0.04944204),
Vec3d(0.79461323, 0.35942459, 0.02051968),
Vec3d(0.01710416, 0.05022043, 0.29220674),
Vec3d(0.05598012, 0.30021149, 0.06871162),
Vec3d(0.45585457, 0.03033727, 0.04085654),
Vec3d(0.85737614, 0.56757335, 0.0068503),
Vec3d(0.53348585, 0.08861148, 0.30750446),
Vec3d(-0.0374061, 0.24699498, 0.40041217),
Vec3d(0.91262695, 0.91493909, 0.89367049),
Vec3d(0.57981916, 0.59200418, 0.59328881),
Vec3d(0.35490581, 0.36544831, 0.36755375),
Vec3d(0.19007357, 0.19186587, 0.19308397),
Vec3d(0.08529188, 0.08887994, 0.09257601),
Vec3d(0.0303193, 0.03113818, 0.03274845));
EXPECT_MAT_NEAR(dstRgbl, model.getRefLinearRGB(), 1e-4);
Mat mask = Mat::ones(24, 1, CV_8U);
EXPECT_MAT_NEAR(model.getMask(), mask, 0.0);
Mat refColorMat = (Mat_<double>(3, 3) <<
0.37406520, 0.02066507, 0.05804047,
0.12719672, 0.77389268, -0.01569404,
-0.27627010, 0.00603427, 2.74272981);
EXPECT_MAT_NEAR(colorCorrectionMat, refColorMat, 1e-4);
}
TEST(Photo_ColorCorrection, test_model_with_color_patches_mask)
{
Mat dstData = (Mat_<Vec3d>(24, 1) <<
Vec3d(37.986, 13.555, 14.059),
Vec3d(65.711, 18.13, 17.81),
Vec3d(49.927, -4.88, -21.925),
Vec3d(43.139, -13.095, 21.905),
Vec3d(55.112, 8.843999999999999, -25.399),
Vec3d(70.71899999999999, -33.397, -0.199),
Vec3d(62.661, 36.067, 57.096),
Vec3d(40.02, 10.41, -45.964),
Vec3d(51.124, 48.239, 16.248),
Vec3d(30.325, 22.976, -21.587),
Vec3d(72.532, -23.709, 57.255),
Vec3d(71.941, 19.363, 67.857),
Vec3d(28.778, 14.179, -50.297),
Vec3d(55.261, -38.342, 31.37),
Vec3d(42.101, 53.378, 28.19),
Vec3d(81.733, 4.039, 79.819),
Vec3d(51.935, 49.986, -14.574),
Vec3d(51.038, -28.631, -28.638),
Vec3d(96.539, -0.425, 1.186),
Vec3d(81.25700000000001, -0.638, -0.335),
Vec3d(66.76600000000001, -0.734, -0.504),
Vec3d(50.867, -0.153, -0.27),
Vec3d(35.656, -0.421, -1.231),
Vec3d(20.461, -0.079, -0.973)
);
Mat coloredMask = (Mat_<uchar>(24, 1) <<
1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0);
cv::ccm::ColorCorrectionModel model(s/255, dstData, cv::ccm::COLOR_SPACE_LAB_D50_2, coloredMask);
Mat colorCorrectionMat = model.compute();
Mat refColorMat = (Mat_<double>(3, 3) <<
0.37406520, 0.02066507, 0.05804047,
0.12719672, 0.77389268, -0.01569404,
-0.27627010, 0.00603427, 2.74272981);
EXPECT_MAT_NEAR(colorCorrectionMat, refColorMat, 1e-4);
}
TEST(Photo_ColorCorrection, test_masks_weights_1)
{
Mat weightsList_ = (Mat_<double>(24, 1) <<
1.1, 0, 0, 1.2, 0, 0,
1.3, 0, 0, 1.4, 0, 0,
0.5, 0, 0, 0.6, 0, 0,
0.7, 0, 0, 0.8, 0, 0);
cv::ccm::ColorCorrectionModel model1(s / 255,cv::ccm::COLORCHECKER_MACBETH);
model1.setColorSpace(cv::ccm::COLOR_SPACE_SRGB);
model1.setCcmType(cv::ccm::CCM_LINEAR);
model1.setDistance(cv::ccm::DISTANCE_CIE2000);
model1.setLinearization(cv::ccm::LINEARIZATION_GAMMA);
model1.setLinearizationGamma(2.2);
model1.setLinearizationDegree(3);
model1.setSaturatedThreshold(0, 0.98);
model1.setWeightsList(weightsList_);
model1.setWeightCoeff(1.5);
Mat colorCorrectionMat = model1.compute();
Mat weights = (Mat_<double>(8, 1) <<
1.15789474, 1.26315789, 1.36842105, 1.47368421,
0.52631579, 0.63157895, 0.73684211, 0.84210526);
EXPECT_MAT_NEAR(model1.getWeights(), weights, 1e-4);
Mat mask = (Mat_<uchar>(24, 1) <<
true, false, false, true, false, false,
true, false, false, true, false, false,
true, false, false, true, false, false,
true, false, false, true, false, false);
EXPECT_MAT_NEAR(model1.getMask(), mask, 0.0);
}
TEST(Photo_ColorCorrection, test_masks_weights_2)
{
cv::ccm::ColorCorrectionModel model2(s / 255, cv::ccm::COLORCHECKER_MACBETH);
model2.setCcmType(cv::ccm::CCM_LINEAR);
model2.setDistance(cv::ccm::DISTANCE_CIE2000);
model2.setLinearization(cv::ccm::LINEARIZATION_GAMMA);
model2.setLinearizationGamma(2.2);
model2.setLinearizationDegree(3);
model2.setSaturatedThreshold(0.05, 0.93);
model2.setWeightsList(Mat());
model2.setWeightCoeff(1.5);
Mat colorCorrectionMat = model2.compute();
Mat weights = (Mat_<double>(20, 1) <<
0.65554256, 1.49454705, 1.00499244, 0.79735434, 1.16327759,
1.68623868, 1.37973155, 0.73213388, 1.0169629, 0.47430246,
1.70312161, 0.45414218, 1.15910007, 0.7540434, 1.05049802,
1.04551645, 1.54082353, 1.02453421, 0.6015915, 0.26154558);
EXPECT_MAT_NEAR(model2.getWeights(), weights, 1e-4);
Mat mask = (Mat_<uchar>(24, 1) <<
true, true, true, true, true, true,
true, true, true, true, false, true,
true, true, true, false, true, true,
false, false, true, true, true, true);
EXPECT_MAT_NEAR(model2.getMask(), mask, 0.0);
}
TEST(Photo_ColorCorrection, compute_color_correction_matrix)
{
// read gold chartsRGB
string path = cvtest::findDataFile("mcc/mcc_ccm_test.yml");
FileStorage fs(path, FileStorage::READ);
Mat chartsRGB;
FileNode node = fs["chartsRGB"];
node >> chartsRGB;
ASSERT_FALSE(chartsRGB.empty()) << "chartsRGB is empty after loading from: " << path;
// compute CCM
cv::ccm::ColorCorrectionModel model(chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255., cv::ccm::COLORCHECKER_MACBETH);
Mat colorCorrectionMat = model.compute();
// read gold CCM
node = fs["ccm"];
ASSERT_FALSE(node.empty());
Mat gold_ccm;
node >> gold_ccm;
fs.release();
// check CCM
EXPECT_MAT_NEAR(gold_ccm, colorCorrectionMat, 1e-8);
const double gold_loss = 4.6386569120323129;
// check loss
const double loss = model.getLoss();
EXPECT_NEAR(gold_loss, loss, 1e-8);
}
TEST(Photo_ColorCorrection, correct_image)
{
string path = cvtest::findDataFile("mcc/mcc_ccm_test.jpg");
Mat img = imread(path, IMREAD_COLOR);
// read gold calibrate img
path = cvtest::findDataFile("mcc/mcc_ccm_test_res.png");
Mat gold_img = imread(path);
// read gold chartsRGB
path = cvtest::findDataFile("mcc/mcc_ccm_test.yml");
FileStorage fs(path, FileStorage::READ);
Mat chartsRGB;
FileNode node = fs["chartsRGB"];
node >> chartsRGB;
fs.release();
ASSERT_FALSE(chartsRGB.empty()) << "chartsRGB is empty after loading from: " << path;
// compute CCM
cv::ccm::ColorCorrectionModel model(chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255., cv::ccm::COLORCHECKER_MACBETH);
Mat colorCorrectionMat = model.compute();
// compute calibrate image
Mat calibratedImage;
model.correctImage(img, calibratedImage);
// check calibrated image
EXPECT_MAT_NEAR(gold_img, calibratedImage, 0.1);
}
TEST(Photo_ColorCorrection, serialization)
{
auto path = cvtest::findDataFile("mcc/mcc_ccm_test.yml");
FileStorage fs(path, FileStorage::READ);
Mat chartsRGB;
FileNode node = fs["chartsRGB"];
node >> chartsRGB;
fs.release();
ASSERT_FALSE(chartsRGB.empty()) << "chartsRGB is empty after loading from: " << path;
// compute CCM
cv::ccm::ColorCorrectionModel model(chartsRGB.col(1).clone().reshape(3, chartsRGB.rows/3) / 255., cv::ccm::COLORCHECKER_MACBETH);
Mat colorCorrectionMat = model.compute();
//--- 1. write model to memory -------------------------------------------
FileStorage fs1("", FileStorage::WRITE | FileStorage::MEMORY);
model.write(fs1);
std::string yaml1 = fs1.releaseAndGetString();
//--- 2. read model back from memory -------------------------------------
cv::ccm::ColorCorrectionModel model1;
FileStorage fs2(yaml1, FileStorage::READ | FileStorage::MEMORY);
model1.read(fs2["ColorCorrectionModel"]);
fs2.release();
//--- 3. write the re-loaded model again to memory -----------------------
FileStorage fs3("", FileStorage::WRITE | FileStorage::MEMORY);
model1.write(fs3);
std::string yaml2 = fs3.releaseAndGetString();
//--- 4. compare the two YAML strings ------------------------------------
EXPECT_EQ(yaml1, yaml2);
}
} // namespace
} // namespace opencv_test
@@ -0,0 +1,144 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
namespace opencv_test { namespace {
const unsigned long EXPECTED_COEFFS_SIZE = 78;
class ChromaticAberrationTest : public testing::Test
{
protected:
std::string test_yaml_file;
cv::Mat test_image;
cv::Mat coeffMat;
cv::Mat corrected;
int degree = -1;
Size calib_size = {-1, -1};
void SetUp() override
{
string data_path = cvtest::TS::ptr()->get_data_path();
ASSERT_TRUE(!data_path.empty()) << "OPENCV_TEST_DATA_PATH not set";
test_yaml_file = std::string(data_path) + "cameracalibration/chromatic_aberration/ca_photo_calib.yaml";
test_image = cv::imread(std::string(data_path) + "cameracalibration/chromatic_aberration/ca_photo.png");
ASSERT_FALSE(test_image.empty()) << "Failed to load test image";
}
};
TEST_F(ChromaticAberrationTest, LoadCalibAndCorrectImage)
{
FileStorage fs(test_yaml_file, FileStorage::READ);
ASSERT_TRUE(fs.isOpened());
ASSERT_NO_THROW(cv::loadChromaticAberrationParams(fs.root(), coeffMat, calib_size, degree));
ASSERT_FALSE(coeffMat.empty());
ASSERT_EQ(coeffMat.type(), CV_32F);
ASSERT_EQ(coeffMat.rows, 4);
ASSERT_GT(coeffMat.cols, 0);
ASSERT_EQ((degree + 1) * (degree + 2) / 2, coeffMat.cols);
ASSERT_GT(calib_size.width, 0);
ASSERT_GT(calib_size.height, 0);
ASSERT_EQ(test_image.cols, calib_size.width);
ASSERT_EQ(test_image.rows, calib_size.height);
ASSERT_NO_THROW(cv::correctChromaticAberration(test_image, coeffMat, corrected, calib_size, degree));
EXPECT_EQ(corrected.size(), test_image.size());
EXPECT_EQ(corrected.channels(), test_image.channels());
EXPECT_EQ(corrected.type(), test_image.type());
cv::Mat diff; cv::absdiff(test_image, corrected, diff);
cv::Scalar s = cv::sum(diff);
EXPECT_GT(s[0] + s[1] + s[2], 0.0);
}
TEST_F(ChromaticAberrationTest, YAMLContentsAsExpected)
{
cv::FileStorage fs(test_yaml_file, cv::FileStorage::READ);
ASSERT_TRUE(fs.isOpened());
cv::FileNode red_node = fs["red_channel"];
cv::FileNode blue_node = fs["blue_channel"];
EXPECT_TRUE(red_node.isMap());
EXPECT_TRUE(blue_node.isMap());
std::vector<double> coeffs_x;
red_node["coeffs_x"] >> coeffs_x;
EXPECT_EQ(coeffs_x.size(), EXPECTED_COEFFS_SIZE);
blue_node["coeffs_x"] >> coeffs_x;
EXPECT_EQ(coeffs_x.size(), EXPECTED_COEFFS_SIZE);
std::vector<double> coeffs_y;
red_node["coeffs_y"] >> coeffs_y;
EXPECT_EQ(coeffs_y.size(), EXPECTED_COEFFS_SIZE);
blue_node["coeffs_y"] >> coeffs_y;
EXPECT_EQ(coeffs_y.size(), EXPECTED_COEFFS_SIZE);
fs.release();
}
TEST_F(ChromaticAberrationTest, InvalidSingleChannel)
{
FileStorage fs(test_yaml_file, FileStorage::READ);
ASSERT_TRUE(fs.isOpened());
ASSERT_NO_THROW(cv::loadChromaticAberrationParams(fs.root(), coeffMat, calib_size, degree));
cv::Mat gray;
cv::cvtColor(test_image, gray, cv::COLOR_BGR2GRAY);
EXPECT_THROW(cv::correctChromaticAberration(gray, coeffMat, corrected, calib_size, degree),
cv::Exception);
}
TEST_F(ChromaticAberrationTest, EmptyCoeffMat)
{
FileStorage fs(test_yaml_file, FileStorage::READ);
ASSERT_TRUE(fs.isOpened());
ASSERT_NO_THROW(cv::loadChromaticAberrationParams(fs.root(), coeffMat, calib_size, degree));
cv::Mat emptyCoeff;
EXPECT_THROW(cv::correctChromaticAberration(test_image, emptyCoeff, corrected, calib_size, degree),
cv::Exception);
}
TEST_F(ChromaticAberrationTest, MismatchedImageSize)
{
FileStorage fs(test_yaml_file, FileStorage::READ);
ASSERT_TRUE(fs.isOpened());
ASSERT_NO_THROW(cv::loadChromaticAberrationParams(fs.root(), coeffMat, calib_size, degree));
cv::Mat resized;
cv::resize(test_image, resized, cv::Size(test_image.cols/2, test_image.rows/2));
EXPECT_THROW(cv::correctChromaticAberration(resized, coeffMat, corrected, calib_size, degree),
cv::Exception);
}
TEST_F(ChromaticAberrationTest, WrongCoeffType)
{
FileStorage fs(test_yaml_file, FileStorage::READ);
ASSERT_TRUE(fs.isOpened());
ASSERT_NO_THROW(cv::loadChromaticAberrationParams(fs.root(), coeffMat, calib_size, degree));
cv::Mat wrongType;
coeffMat.convertTo(wrongType, CV_64F);
EXPECT_THROW(cv::correctChromaticAberration(test_image, wrongType, corrected, calib_size, degree),
cv::Exception);
}
TEST_F(ChromaticAberrationTest, DegreeDoesNotMatchCoeffCols)
{
FileStorage fs(test_yaml_file, FileStorage::READ);
ASSERT_TRUE(fs.isOpened());
ASSERT_NO_THROW(cv::loadChromaticAberrationParams(fs.root(), coeffMat, calib_size, degree));
int wrongDegree = std::max(1, degree - 1);
ASSERT_NE((wrongDegree + 1) * (wrongDegree + 2) / 2, coeffMat.cols);
EXPECT_THROW(cv::correctChromaticAberration(test_image, coeffMat, corrected, calib_size, wrongDegree),
cv::Exception);
}
}}
+247
View File
@@ -0,0 +1,247 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
namespace opencv_test { namespace {
#define OUTPUT_SAVING 0
#if OUTPUT_SAVING
#define SAVE(x) std::vector<int> params;\
params.push_back(16);\
params.push_back(0);\
imwrite(folder + "output.png", x ,params);
#else
#define SAVE(x)
#endif
static const double numerical_precision = 0.05; // 95% of pixels should have exact values
TEST(Photo_SeamlessClone_normal, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "cloning/Normal_Cloning/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "destination1.png";
string original_path3 = folder + "mask.png";
string reference_path = folder + "reference.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat destination = imread(original_path2, IMREAD_COLOR);
Mat mask = imread(original_path3, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(destination.empty()) << "Could not load destination image " << original_path2;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path3;
Mat result;
Point p;
p.x = destination.size().width/2;
p.y = destination.size().height/2;
seamlessClone(source, destination, mask, p, result, NORMAL_CLONE);
Mat reference = imread(reference_path);
ASSERT_FALSE(reference.empty()) << "Could not load reference image " << reference_path;
SAVE(result);
double errorINF = cvtest::norm(reference, result, NORM_INF);
EXPECT_LE(errorINF, 1);
double errorL1 = cvtest::norm(reference, result, NORM_L1);
EXPECT_LE(errorL1, reference.total() * numerical_precision) << "size=" << reference.size();
mask = Scalar(0, 0, 0);
seamlessClone(source, destination, mask, p, result, NORMAL_CLONE);
reference = destination;
errorINF = cvtest::norm(reference, result, NORM_INF);
EXPECT_LE(errorINF, 1);
errorL1 = cvtest::norm(reference, result, NORM_L1);
EXPECT_LE(errorL1, reference.total() * numerical_precision) << "size=" << reference.size();
}
TEST(Photo_SeamlessClone_mixed, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "cloning/Mixed_Cloning/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "destination1.png";
string original_path3 = folder + "mask.png";
string reference_path = folder + "reference.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat destination = imread(original_path2, IMREAD_COLOR);
Mat mask = imread(original_path3, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(destination.empty()) << "Could not load destination image " << original_path2;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path3;
Mat result;
Point p;
p.x = destination.size().width/2;
p.y = destination.size().height/2;
seamlessClone(source, destination, mask, p, result, MIXED_CLONE);
SAVE(result);
Mat reference = imread(reference_path);
ASSERT_FALSE(reference.empty()) << "Could not load reference image " << reference_path;
double errorINF = cvtest::norm(reference, result, NORM_INF);
EXPECT_LE(errorINF, 1);
double errorL1 = cvtest::norm(reference, result, NORM_L1);
EXPECT_LE(errorL1, reference.total() * numerical_precision) << "size=" << reference.size();
}
TEST(Photo_SeamlessClone_featureExchange, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "cloning/Monochrome_Transfer/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "destination1.png";
string original_path3 = folder + "mask.png";
string reference_path = folder + "reference.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat destination = imread(original_path2, IMREAD_COLOR);
Mat mask = imread(original_path3, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(destination.empty()) << "Could not load destination image " << original_path2;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path3;
Mat result;
Point p;
p.x = destination.size().width/2;
p.y = destination.size().height/2;
seamlessClone(source, destination, mask, p, result, MONOCHROME_TRANSFER);
SAVE(result);
Mat reference = imread(reference_path);
ASSERT_FALSE(reference.empty()) << "Could not load reference image " << reference_path;
double errorINF = cvtest::norm(reference, result, NORM_INF);
EXPECT_LE(errorINF, 1);
double errorL1 = cvtest::norm(reference, result, NORM_L1);
EXPECT_LE(errorL1, reference.total() * numerical_precision) << "size=" << reference.size();
}
TEST(Photo_SeamlessClone_colorChange, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "cloning/color_change/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "mask.png";
string reference_path = folder + "reference.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat mask = imread(original_path2, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path2;
Mat result;
colorChange(source, mask, result, 1.5, .5, .5);
SAVE(result);
Mat reference = imread(reference_path);
ASSERT_FALSE(reference.empty()) << "Could not load reference image " << reference_path;
double errorINF = cvtest::norm(reference, result, NORM_INF);
EXPECT_LE(errorINF, 1);
double errorL1 = cvtest::norm(reference, result, NORM_L1);
EXPECT_LE(errorL1, reference.total() * numerical_precision) << "size=" << reference.size();
}
TEST(Photo_SeamlessClone_illuminationChange, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "cloning/Illumination_Change/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "mask.png";
string reference_path = folder + "reference.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat mask = imread(original_path2, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path2;
Mat result;
illuminationChange(source, mask, result, 0.2f, 0.4f);
SAVE(result);
Mat reference = imread(reference_path);
ASSERT_FALSE(reference.empty()) << "Could not load reference image " << reference_path;
double errorINF = cvtest::norm(reference, result, NORM_INF);
EXPECT_LE(errorINF, 1);
double errorL1 = cvtest::norm(reference, result, NORM_L1);
EXPECT_LE(errorL1, reference.total() * numerical_precision) << "size=" << reference.size();
}
TEST(Photo_SeamlessClone_textureFlattening, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "cloning/Texture_Flattening/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "mask.png";
string reference_path = folder + "reference.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat mask = imread(original_path2, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path2;
Mat result;
textureFlattening(source, mask, result, 30, 45, 3);
SAVE(result);
Mat reference = imread(reference_path);
ASSERT_FALSE(reference.empty()) << "Could not load reference image " << reference_path;
double errorINF = cvtest::norm(reference, result, NORM_INF);
EXPECT_LE(errorINF, 1);
double errorL1 = cvtest::norm(reference, result, NORM_L1);
EXPECT_LE(errorL1, reference.total() * numerical_precision) << "size=" << reference.size();
}
}} // namespace
+68
View File
@@ -0,0 +1,68 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
namespace opencv_test { namespace {
TEST(Photo_Decolor, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "decolor/";
string original_path = folder + "color_image_1.png";
Mat original = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(original.empty()) << "Could not load input image " << original_path;
ASSERT_EQ(3, original.channels()) << "Load color input image " << original_path;
Mat grayscale, color_boost;
decolor(original, grayscale, color_boost);
Mat reference_grayscale = imread(folder + "grayscale_reference.png", 0 /* == grayscale image*/);
double gray_psnr = cvtest::PSNR(reference_grayscale, grayscale);
EXPECT_GT(gray_psnr, 60.0);
Mat reference_boost = imread(folder + "boost_reference.png");
double boost_psnr = cvtest::PSNR(reference_boost, color_boost);
EXPECT_GT(boost_psnr, 60.0);
}
}} // namespace
+129
View File
@@ -0,0 +1,129 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the OpenCV Foundation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
namespace opencv_test { namespace {
void make_noisy(const cv::Mat& img, cv::Mat& noisy, double sigma, double pepper_salt_ratio,cv::RNG& rng)
{
noisy.create(img.size(), img.type());
cv::Mat noise(img.size(), img.type()), mask(img.size(), CV_8U);
rng.fill(noise,cv::RNG::NORMAL,128.0,sigma);
cv::addWeighted(img, 1, noise, 1, -128, noisy);
cv::randn(noise, cv::Scalar::all(0), cv::Scalar::all(2));
noise *= 255;
cv::randu(mask, 0, cvRound(1./pepper_salt_ratio));
cv::Mat half = mask.colRange(0, img.cols/2);
half = cv::Scalar::all(1);
noise.setTo(128, mask);
cv::addWeighted(noisy, 1, noise, 1, -128, noisy);
}
#if 0
void make_spotty(cv::Mat& img,cv::RNG& rng, int r=3,int n=1000)
{
for(int i=0;i<n;i++)
{
int x=rng(img.cols-r),y=rng(img.rows-r);
if(rng(2)==0)
img(cv::Range(y,y+r),cv::Range(x,x+r))=(uchar)0;
else
img(cv::Range(y,y+r),cv::Range(x,x+r))=(uchar)255;
}
}
#endif
bool validate_pixel(const cv::Mat& image,int x,int y,uchar val)
{
bool ok = std::abs(image.at<uchar>(x,y) - val) < 10;
printf("test: image(%d,%d)=%d vs %d - %s\n",x,y,(int)image.at<uchar>(x,y),val,ok?"ok":"bad");
return ok;
}
TEST(Optim_denoise_tvl1, regression_basic)
{
cv::RNG rng(42);
cv::Mat img = cv::imread(cvtest::TS::ptr()->get_data_path() + "shared/lena.png", 0), noisy, res;
ASSERT_FALSE(img.empty()) << "Error: can't open 'lena.png'";
const int obs_num=5;
std::vector<cv::Mat> images(obs_num, cv::Mat());
for(int i=0;i<(int)images.size();i++)
{
make_noisy(img,images[i], 20, 0.02,rng);
//make_spotty(images[i],rng);
}
//cv::imshow("test", images[0]);
cv::denoise_TVL1(images, res);
//cv::imshow("denoised", res);
//cv::waitKey();
#if 0
ASSERT_TRUE(validate_pixel(res,248,334,179));
ASSERT_TRUE(validate_pixel(res,489,333,172));
ASSERT_TRUE(validate_pixel(res,425,507,104));
ASSERT_TRUE(validate_pixel(res,489,486,105));
ASSERT_TRUE(validate_pixel(res,223,208,64));
ASSERT_TRUE(validate_pixel(res,418,3,78));
ASSERT_TRUE(validate_pixel(res,63,76,97));
ASSERT_TRUE(validate_pixel(res,29,134,126));
ASSERT_TRUE(validate_pixel(res,219,291,174));
ASSERT_TRUE(validate_pixel(res,384,124,76));
#endif
#if 1
ASSERT_TRUE(validate_pixel(res,248,334,194));
ASSERT_TRUE(validate_pixel(res,489,333,171));
ASSERT_TRUE(validate_pixel(res,425,507,103));
ASSERT_TRUE(validate_pixel(res,489,486,109));
ASSERT_TRUE(validate_pixel(res,223,208,72));
ASSERT_TRUE(validate_pixel(res,418,3,58));
ASSERT_TRUE(validate_pixel(res,63,76,93));
ASSERT_TRUE(validate_pixel(res,29,134,127));
ASSERT_TRUE(validate_pixel(res,219,291,180));
ASSERT_TRUE(validate_pixel(res,384,124,80));
#endif
}
}} // namespace
+197
View File
@@ -0,0 +1,197 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
namespace opencv_test { namespace {
//#define DUMP_RESULTS
#ifdef DUMP_RESULTS
# define DUMP(image, path) imwrite(path, image)
#else
# define DUMP(image, path)
#endif
TEST(Photo_DenoisingGrayscale, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "denoising/";
string original_path = folder + "lena_noised_gaussian_sigma=10.png";
string expected_path = folder + "lena_noised_denoised_grayscale_tw=7_sw=21_h=10.png";
Mat original = imread(original_path, IMREAD_GRAYSCALE);
Mat expected = imread(expected_path, IMREAD_GRAYSCALE);
ASSERT_FALSE(original.empty()) << "Could not load input image " << original_path;
ASSERT_FALSE(expected.empty()) << "Could not load reference image " << expected_path;
Mat result;
fastNlMeansDenoising(original, result, 10);
DUMP(result, expected_path + ".res.png");
ASSERT_EQ(0, cvtest::norm(result, expected, NORM_L2));
}
TEST(Photo_DenoisingColored, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "denoising/";
string original_path = folder + "lena_noised_gaussian_sigma=10.png";
string expected_path = folder + "lena_noised_denoised_lab12_tw=7_sw=21_h=10_h2=10.png";
Mat original = imread(original_path, IMREAD_COLOR);
Mat expected = imread(expected_path, IMREAD_COLOR);
ASSERT_FALSE(original.empty()) << "Could not load input image " << original_path;
ASSERT_FALSE(expected.empty()) << "Could not load reference image " << expected_path;
Mat result;
fastNlMeansDenoisingColored(original, result, 10, 10);
DUMP(result, expected_path + ".res.png");
ASSERT_EQ(0, cvtest::norm(result, expected, NORM_L2));
}
TEST(Photo_DenoisingGrayscaleMulti, regression)
{
const int imgs_count = 3;
string folder = string(cvtest::TS::ptr()->get_data_path()) + "denoising/";
string expected_path = folder + "lena_noised_denoised_multi_tw=7_sw=21_h=15.png";
Mat expected = imread(expected_path, IMREAD_GRAYSCALE);
ASSERT_FALSE(expected.empty()) << "Could not load reference image " << expected_path;
vector<Mat> original(imgs_count);
for (int i = 0; i < imgs_count; i++)
{
string original_path = format("%slena_noised_gaussian_sigma=20_multi_%d.png", folder.c_str(), i);
original[i] = imread(original_path, IMREAD_GRAYSCALE);
ASSERT_FALSE(original[i].empty()) << "Could not load input image " << original_path;
}
Mat result;
fastNlMeansDenoisingMulti(original, result, imgs_count / 2, imgs_count, 15);
DUMP(result, expected_path + ".res.png");
ASSERT_EQ(0, cvtest::norm(result, expected, NORM_L2));
}
TEST(Photo_DenoisingColoredMulti, regression)
{
const int imgs_count = 3;
string folder = string(cvtest::TS::ptr()->get_data_path()) + "denoising/";
string expected_path = folder + "lena_noised_denoised_multi_lab12_tw=7_sw=21_h=10_h2=15.png";
Mat expected = imread(expected_path, IMREAD_COLOR);
ASSERT_FALSE(expected.empty()) << "Could not load reference image " << expected_path;
vector<Mat> original(imgs_count);
for (int i = 0; i < imgs_count; i++)
{
string original_path = format("%slena_noised_gaussian_sigma=20_multi_%d.png", folder.c_str(), i);
original[i] = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(original[i].empty()) << "Could not load input image " << original_path;
}
Mat result;
fastNlMeansDenoisingColoredMulti(original, result, imgs_count / 2, imgs_count, 10, 15);
DUMP(result, expected_path + ".res.png");
ASSERT_EQ(0, cvtest::norm(result, expected, NORM_L2));
}
TEST(Photo_White, issue_2646)
{
cv::Mat img(50, 50, CV_8UC1, cv::Scalar::all(255));
cv::Mat filtered;
cv::fastNlMeansDenoising(img, filtered);
int nonWhitePixelsCount = (int)img.total() - cv::countNonZero(filtered == img);
ASSERT_EQ(0, nonWhitePixelsCount);
}
TEST(Photo_Denoising, speed)
{
string imgname = string(cvtest::TS::ptr()->get_data_path()) + "shared/5MP.png";
Mat src = imread(imgname, IMREAD_GRAYSCALE), dst;
double t = (double)getTickCount();
fastNlMeansDenoising(src, dst, 5, 7, 21);
t = (double)getTickCount() - t;
printf("execution time: %gms\n", t*1000./getTickFrequency());
}
// Related issue : https://github.com/opencv/opencv/issues/26582
TEST(Photo_DenoisingGrayscaleMulti16bitL1, regression)
{
const int imgs_count = 3;
string folder = string(cvtest::TS::ptr()->get_data_path()) + "denoising/";
vector<Mat> original_8u(imgs_count);
vector<Mat> original_16u(imgs_count);
for (int i = 0; i < imgs_count; i++)
{
string original_path = format("%slena_noised_gaussian_sigma=20_multi_%d.png", folder.c_str(), i);
original_8u[i] = imread(original_path, IMREAD_GRAYSCALE);
ASSERT_FALSE(original_8u[i].empty()) << "Could not load input image " << original_path;
original_8u[i].convertTo(original_16u[i], CV_16U);
}
Mat result_8u, result_16u;
std::vector<float> h = {15};
fastNlMeansDenoisingMulti(original_8u, result_8u, /*imgToDenoiseIndex*/ imgs_count / 2, /*temporalWindowSize*/ imgs_count, h, 7, 21, NORM_L1);
fastNlMeansDenoisingMulti(original_16u, result_16u, /*imgToDenoiseIndex*/ imgs_count / 2, /*temporalWindowSize*/ imgs_count, h, 7, 21, NORM_L1);
DUMP(result_8u, "8u.res.png");
DUMP(result_16u, "16u.res.png");
cv::Mat expected;
result_8u.convertTo(expected, CV_16U);
EXPECT_MAT_NEAR(result_16u, expected, 1);
}
}} // namespace
+120
View File
@@ -0,0 +1,120 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
#include "opencv2/photo/cuda.hpp"
#include "opencv2/ts/cuda_test.hpp"
#include "opencv2/opencv_modules.hpp"
#include "cvconfig.h"
#if defined (HAVE_CUDA) && defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAIMGPROC)
namespace opencv_test { namespace {
////////////////////////////////////////////////////////
// Brute Force Non local means
TEST(CUDA_BruteForceNonLocalMeans, Regression)
{
using cv::cuda::GpuMat;
cv::Mat bgr = readImage("../gpu/denoising/lena_noised_gaussian_sigma=20_multi_0.png", cv::IMREAD_COLOR);
ASSERT_FALSE(bgr.empty());
cv::resize(bgr, bgr, cv::Size(256, 256));
cv::Mat gray;
cv::cvtColor(bgr, gray, cv::COLOR_BGR2GRAY);
GpuMat dbgr, dgray;
cv::cuda::nonLocalMeans(GpuMat(bgr), dbgr, 20);
cv::cuda::nonLocalMeans(GpuMat(gray), dgray, 20);
#if 0
dumpImage("../gpu/denoising/nlm_denoised_lena_bgr.png", cv::Mat(dbgr));
dumpImage("../gpu/denoising/nlm_denoised_lena_gray.png", cv::Mat(dgray));
#endif
cv::Mat bgr_gold = readImage("../gpu/denoising/nlm_denoised_lena_bgr.png", cv::IMREAD_COLOR);
cv::Mat gray_gold = readImage("../gpu/denoising/nlm_denoised_lena_gray.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(bgr_gold.empty() || gray_gold.empty());
cv::resize(bgr_gold, bgr_gold, cv::Size(256, 256));
cv::resize(gray_gold, gray_gold, cv::Size(256, 256));
EXPECT_MAT_NEAR(bgr_gold, dbgr, 1);
EXPECT_MAT_NEAR(gray_gold, dgray, 1);
}
////////////////////////////////////////////////////////
// Fast Force Non local means
TEST(CUDA_FastNonLocalMeans, Regression)
{
using cv::cuda::GpuMat;
cv::Mat bgr = readImage("../gpu/denoising/lena_noised_gaussian_sigma=20_multi_0.png", cv::IMREAD_COLOR);
ASSERT_FALSE(bgr.empty());
cv::Mat gray;
cv::cvtColor(bgr, gray, cv::COLOR_BGR2GRAY);
GpuMat dbgr, dgray;
cv::cuda::fastNlMeansDenoising(GpuMat(gray), dgray, 20);
cv::cuda::fastNlMeansDenoisingColored(GpuMat(bgr), dbgr, 20, 10);
#if 0
dumpImage("../gpu/denoising/fnlm_denoised_lena_bgr.png", cv::Mat(dbgr));
dumpImage("../gpu/denoising/fnlm_denoised_lena_gray.png", cv::Mat(dgray));
#endif
cv::Mat bgr_gold = readImage("../gpu/denoising/fnlm_denoised_lena_bgr.png", cv::IMREAD_COLOR);
cv::Mat gray_gold = readImage("../gpu/denoising/fnlm_denoised_lena_gray.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(bgr_gold.empty() || gray_gold.empty());
EXPECT_MAT_NEAR(bgr_gold, dbgr, 1);
EXPECT_MAT_NEAR(gray_gold, dgray, 1);
}
}} // namespace
#endif // HAVE_CUDA
+372
View File
@@ -0,0 +1,372 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
namespace opencv_test { namespace {
void loadImage(string path, Mat &img)
{
img = imread(path, -1);
ASSERT_FALSE(img.empty()) << "Could not load input image " << path;
}
void checkEqual(Mat img0, Mat img1, double threshold, const string& name)
{
double max = 1.0;
minMaxLoc(abs(img0 - img1), NULL, &max);
ASSERT_FALSE(max > threshold) << "max=" << max << " threshold=" << threshold << " method=" << name;
}
static vector<float> DEFAULT_VECTOR;
void loadExposureSeq(String path, vector<Mat>& images, vector<float>& times = DEFAULT_VECTOR)
{
std::ifstream list_file((path + "list.txt").c_str());
ASSERT_TRUE(list_file.is_open());
string name;
float val;
while(list_file >> name >> val) {
Mat img = imread(path + name);
ASSERT_FALSE(img.empty()) << "Could not load input image " << path + name;
images.push_back(img);
times.push_back(1 / val);
}
list_file.close();
}
void loadResponseCSV(String path, Mat& response)
{
response = Mat(256, 1, CV_32FC3);
std::ifstream resp_file(path.c_str());
for(int i = 0; i < 256; i++) {
for(int c = 0; c < 3; c++) {
resp_file >> response.at<Vec3f>(i)[c];
resp_file.ignore(1);
}
}
resp_file.close();
}
TEST(Photo_Tonemap, regression)
{
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/tonemap/";
Mat img, expected, result;
loadImage(test_path + "image.hdr", img);
float gamma = 2.2f;
Ptr<Tonemap> linear = createTonemap(gamma);
linear->process(img, result);
loadImage(test_path + "linear.png", expected);
result.convertTo(result, CV_8UC3, 255);
checkEqual(result, expected, 3, "Simple");
Ptr<TonemapDrago> drago = createTonemapDrago(gamma);
drago->process(img, result);
loadImage(test_path + "drago.png", expected);
result.convertTo(result, CV_8UC3, 255);
checkEqual(result, expected, 3, "Drago");
Ptr<TonemapReinhard> reinhard = createTonemapReinhard(gamma);
reinhard->process(img, result);
loadImage(test_path + "reinhard.png", expected);
result.convertTo(result, CV_8UC3, 255);
checkEqual(result, expected, 3, "Reinhard");
Ptr<TonemapMantiuk> mantiuk = createTonemapMantiuk(gamma);
mantiuk->process(img, result);
loadImage(test_path + "mantiuk.png", expected);
result.convertTo(result, CV_8UC3, 255);
checkEqual(result, expected, 3, "Mantiuk");
}
TEST(Photo_AlignMTB, regression)
{
const int TESTS_COUNT = 100;
string folder = string(cvtest::TS::ptr()->get_data_path()) + "shared/";
string file_name = folder + "lena.png";
Mat img;
loadImage(file_name, img);
cvtColor(img, img, COLOR_RGB2GRAY);
int max_bits = 5;
int max_shift = 32;
srand(static_cast<unsigned>(time(0)));
int errors = 0;
Ptr<AlignMTB> align = createAlignMTB(max_bits);
RNG rng = theRNG();
for(int i = 0; i < TESTS_COUNT; i++) {
Point shift(rng.uniform(0, max_shift), rng.uniform(0, max_shift));
Mat res;
align->shiftMat(img, res, shift);
Point calc = align->calculateShift(img, res);
errors += (calc != -shift);
}
ASSERT_TRUE(errors < 5) << errors << " errors";
}
TEST(Photo_MergeMertens, regression)
{
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/";
vector<Mat> images;
loadExposureSeq((test_path + "exposures/").c_str() , images);
Ptr<MergeMertens> merge = createMergeMertens();
Mat result, expected;
loadImage(test_path + "merge/mertens.png", expected);
merge->process(images, result);
result.convertTo(result, CV_8UC3, 255);
checkEqual(expected, result, 3, "Mertens");
Mat uniform(100, 100, CV_8UC3);
uniform = Scalar(0, 255, 0);
images.clear();
images.push_back(uniform);
merge->process(images, result);
result.convertTo(result, CV_8UC3, 255);
checkEqual(uniform, result, 1e-2f, "Mertens");
}
TEST(Photo_MergeDebevec, regression)
{
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/";
vector<Mat> images;
vector<float> times;
Mat response;
loadExposureSeq(test_path + "exposures/", images, times);
loadResponseCSV(test_path + "exposures/response.csv", response);
Ptr<MergeDebevec> merge = createMergeDebevec();
Mat result, expected;
loadImage(test_path + "merge/debevec.hdr", expected);
merge->process(images, result, times, response);
Ptr<Tonemap> map = createTonemap();
map->process(result, result);
map->process(expected, expected);
checkEqual(expected, result, 1e-2f, "Debevec");
}
TEST(Photo_MergeRobertson, regression)
{
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/";
vector<Mat> images;
vector<float> times;
loadExposureSeq(test_path + "exposures/", images, times);
Ptr<MergeRobertson> merge = createMergeRobertson();
Mat result, expected;
loadImage(test_path + "merge/robertson.hdr", expected);
merge->process(images, result, times);
const float eps = 6.f;
checkEqual(expected, result, eps, "MergeRobertson");
}
TEST(Photo_MergeDebevec, regression_depth_consistency)
{
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/";
vector<Mat> images8;
vector<float> times;
loadExposureSeq(test_path + "exposures/", images8, times);
vector<Mat> images16(images8.size()), images32(images8.size());
for (size_t i = 0; i < images8.size(); ++i)
{
images8[i].convertTo(images16[i], CV_16UC3, 257.0);
images8[i].convertTo(images32[i], CV_32FC3, 1.0 / 255.0);
}
Ptr<MergeDebevec> merge = createMergeDebevec();
Ptr<Tonemap> map = createTonemap();
Mat hdr8, hdr16, hdr32;
merge->process(images8, hdr8, times);
merge->process(images16, hdr16, times);
merge->process(images32, hdr32, times);
map->process(hdr8, hdr8);
map->process(hdr16, hdr16);
map->process(hdr32, hdr32);
checkEqual(hdr8, hdr16, 2e-2f, "Debevec realdata 16U vs 8U");
checkEqual(hdr8, hdr32, 2e-2f, "Debevec realdata 32F vs 8U");
}
TEST(Photo_MergeRobertson, regression_depth_consistency)
{
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/";
vector<Mat> images8;
vector<float> times;
loadExposureSeq(test_path + "exposures/", images8, times);
vector<Mat> images16(images8.size()), images32(images8.size());
for (size_t i = 0; i < images8.size(); ++i)
{
images8[i].convertTo(images16[i], CV_16UC3, 257.0);
images8[i].convertTo(images32[i], CV_32FC3, 1.0 / 255.0);
}
Ptr<MergeRobertson> merge = createMergeRobertson();
Ptr<Tonemap> map = createTonemap();
Mat hdr8, hdr16, hdr32;
merge->process(images8, hdr8, times);
merge->process(images16, hdr16, times);
merge->process(images32, hdr32, times);
map->process(hdr8, hdr8);
map->process(hdr16, hdr16);
map->process(hdr32, hdr32);
checkEqual(hdr8, hdr16, 3e-2f, "Robertson realdata 16U vs 8U");
checkEqual(hdr8, hdr32, 3e-2f, "Robertson realdata 32F vs 8U");
}
TEST(Photo_CalibrateDebevec, regression)
{
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/";
vector<Mat> images;
vector<float> times;
Mat response, expected;
loadExposureSeq(test_path + "exposures/", images, times);
loadResponseCSV(test_path + "calibrate/debevec.csv", expected);
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec();
calibrate->process(images, response, times);
Mat diff = abs(response - expected);
diff = diff.mul(1.0f / response);
double max;
minMaxLoc(diff, NULL, &max);
#if defined(__arm__) || defined(__aarch64__)
ASSERT_LT(max, 0.25);
#elif !defined(HAVE_IPP)
ASSERT_LT(max, 0.22);
#else
ASSERT_LT(max, 0.15);
#endif
}
TEST(Photo_CalibrateRobertson, regression)
{
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/";
vector<Mat> images;
vector<float> times;
Mat response, expected;
loadExposureSeq(test_path + "exposures/", images, times);
loadResponseCSV(test_path + "calibrate/robertson.csv", expected);
Ptr<CalibrateRobertson> calibrate = createCalibrateRobertson();
calibrate->process(images, response, times);
checkEqual(expected, response, 1e-1f, "CalibrateRobertson");
}
TEST(Photo_CalibrateRobertson, bug_18180)
{
vector<Mat> images;
vector<cv::String> fn;
string test_path = cvtest::TS::ptr()->get_data_path() + "hdr/exposures/bug_18180/";
for(int i = 1; i <= 4; ++i)
images.push_back(imread(test_path + std::to_string(i) + ".jpg"));
vector<float> times {15.0f, 2.5f, 0.25f, 0.33f};
Mat response, expected;
Ptr<CalibrateRobertson> calibrate = createCalibrateRobertson(2, 0.01f);
calibrate->process(images, response, times);
Mat response_no_nans = response.clone();
patchNaNs(response_no_nans);
// since there should be no NaNs, original response vs. response with NaNs patched should be identical
EXPECT_EQ(0.0, cv::norm(response, response_no_nans, NORM_L2));
}
TEST(Photo_CalibrateDebevec, bug_24966)
{
string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/";
vector<Mat> all_images;
vector<float> all_times;
loadExposureSeq(test_path + "exposures/", all_images, all_times);
// Use a balanced subset of exposures
vector<int> selected_indices = {1,2,3,4,5};
vector<Mat> images;
vector<float> times;
for (int idx : selected_indices) {
images.push_back(all_images[idx]);
times.push_back(all_times[idx]);
}
// Run CRF estimation for different sample points
vector<int> sample_points = {200,300,400};
vector<Mat> responses;
for (int samples : sample_points) {
Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec(samples);
Mat response;
calibrate->process(images, response, times);
Mat roi = response.rowRange(15, 240); //Checking CRF only in the middle of the image
responses.push_back(roi);
}
// Compare consecutive pairs of CRFs
for (size_t i = 0; i < responses.size()-1; ++i) {
Mat diff = abs(responses[i] - responses[i+1]);
double max_diff;
minMaxLoc(diff, nullptr, &max_diff);
cout << "max_diff = " << max_diff << endl;
#if defined(__aarch64__) && defined(__APPLE__)
ASSERT_LT(max_diff, 10) << "CRF instability detected between samples="
<< sample_points[i] << " and " << sample_points[i+1]
<< " (max diff = " << max_diff << ")";
#else
ASSERT_LT(max_diff, 5) << "CRF instability detected between samples="
<< sample_points[i] << " and " << sample_points[i+1]
<< " (max diff = " << max_diff << ")";
#endif
}
}
}} // namespace
+186
View File
@@ -0,0 +1,186 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
namespace opencv_test { namespace {
class CV_InpaintTest : public cvtest::BaseTest
{
public:
CV_InpaintTest();
~CV_InpaintTest();
protected:
void run(int);
};
CV_InpaintTest::CV_InpaintTest()
{
}
CV_InpaintTest::~CV_InpaintTest() {}
void CV_InpaintTest::run( int )
{
string folder = string(ts->get_data_path()) + "inpaint/";
Mat orig = imread(folder + "orig.png");
Mat exp1 = imread(folder + "exp1.png");
Mat exp2 = imread(folder + "exp2.png");
Mat mask = imread(folder + "mask.png");
if (orig.empty() || exp1.empty() || exp2.empty() || mask.empty())
{
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
}
Mat inv_mask;
mask.convertTo(inv_mask, CV_8UC3, -1.0, 255.0);
Mat mask1ch;
cv::cvtColor(mask, mask1ch, COLOR_BGR2GRAY);
Mat test = orig.clone();
test.setTo(Scalar::all(255), mask1ch);
Mat res1, res2;
inpaint( test, mask1ch, res1, 5, INPAINT_NS );
inpaint( test, mask1ch, res2, 5, INPAINT_TELEA );
Mat diff1, diff2;
absdiff( orig, res1, diff1 );
absdiff( orig, res2, diff2 );
double n1 = cvtest::norm(diff1.reshape(1), NORM_INF, inv_mask.reshape(1));
double n2 = cvtest::norm(diff2.reshape(1), NORM_INF, inv_mask.reshape(1));
if (n1 != 0 || n2 != 0)
{
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
return;
}
absdiff( exp1, res1, diff1 );
absdiff( exp2, res2, diff2 );
n1 = cvtest::norm(diff1.reshape(1), NORM_INF, mask.reshape(1));
n2 = cvtest::norm(diff2.reshape(1), NORM_INF, mask.reshape(1));
const int jpeg_thres = 3;
if (n1 > jpeg_thres || n2 > jpeg_thres)
{
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
return;
}
ts->set_failed_test_info(cvtest::TS::OK);
}
TEST(Photo_Inpaint, regression) { CV_InpaintTest test; test.safe_run(); }
typedef testing::TestWithParam<tuple<perf::MatType> > formats;
TEST_P(formats, basic)
{
const int type = get<0>(GetParam());
Mat src(100, 100, type);
src.setTo(Scalar::all(128));
Mat ref = src.clone();
Mat dst, mask = Mat::zeros(src.size(), CV_8U);
circle(src, Point(50, 50), 5, Scalar::all(200), 6);
circle(mask, Point(50, 50), 5, Scalar::all(200), 6);
inpaint(src, mask, dst, 10, INPAINT_NS);
Mat dst2;
inpaint(src, mask, dst2, 10, INPAINT_TELEA);
ASSERT_EQ(cv::norm(dst, ref, NORM_INF), 0.);
ASSERT_EQ(cv::norm(dst2, ref, NORM_INF), 0.);
}
INSTANTIATE_TEST_CASE_P(Photo_Inpaint, formats, testing::Values(CV_32FC1, CV_16UC1, CV_8UC1, CV_8UC3));
TEST(Photo_InpaintBorders, regression)
{
Mat img(64, 64, CV_8U);
img = 128;
img(Rect(0, 0, 16, 64)) = 0;
Mat mask(64, 64, CV_8U);
mask = 0;
mask(Rect(0, 0, 16, 64)) = 255;
Mat inpainted;
inpaint(img, mask, inpainted, 1, INPAINT_TELEA);
Mat diff;
cv::absdiff(inpainted, 128*Mat::ones(inpainted.size(), inpainted.type()), diff);
ASSERT_TRUE(countNonZero(diff) == 0);
}
typedef testing::TestWithParam<tuple<perf::MatType>> Photo_InpaintSmallBorders;
TEST_P(Photo_InpaintSmallBorders, regression)
{
int type = get<0>(GetParam());
Mat img(5, 5, type, Scalar::all(128));
Mat expected = img.clone();
Mat mask = Mat::zeros(5, 5, CV_8U);
mask(Rect(1, 1, 3, 3)) = 255;
img.setTo(Scalar::all(0), mask);
Mat inpainted, diff;
inpaint(img, mask, inpainted, 1, INPAINT_TELEA);
cv::absdiff(inpainted, expected, diff);
ASSERT_EQ(countNonZero(diff.reshape(1)), 0);
inpaint(img, mask, inpainted, 1, INPAINT_NS);
cv::absdiff(inpainted, expected, diff);
ASSERT_EQ(countNonZero(diff.reshape(1)), 0);
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, Photo_InpaintSmallBorders, Values(CV_8UC1, CV_8UC3));
}} // namespace
@@ -0,0 +1,496 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
//#include "opencv2/imgproc/segmentation.hpp"
namespace opencv_test { namespace {
Mat getTestImageGray()
{
static Mat m;
if (m.empty())
{
m = imread(findDataFile("shared/lena.png"), IMREAD_GRAYSCALE);
}
return m.clone();
}
Mat getTestImageColor()
{
static Mat m;
if (m.empty())
{
m = imread(findDataFile("shared/lena.png"), IMREAD_COLOR);
}
return m.clone();
}
Mat getTestImage1()
{
static Mat m;
if (m.empty())
{
m.create(Size(200, 100), CV_8UC1);
m.setTo(Scalar::all(128));
Rect roi(50, 30, 100, 40);
m(roi).setTo(Scalar::all(0));
#if 0
imshow("image", m);
waitKey();
#endif
}
return m.clone();
}
Mat getTestImage2()
{
static Mat m;
if (m.empty())
{
m.create(Size(200, 100), CV_8UC1);
m.setTo(Scalar::all(128));
Rect roi(40, 30, 100, 40);
m(roi).setTo(Scalar::all(255));
#if 0
imshow("image", m);
waitKey();
#endif
}
return m.clone();
}
Mat getTestImage3()
{
static Mat m;
if (m.empty())
{
m.create(Size(200, 100), CV_8UC1);
m.setTo(Scalar::all(128));
Scalar color(0,0,0,0);
line(m, Point(30, 50), Point(50, 50), color, 1);
line(m, Point(50, 50), Point(80, 30), color, 1);
line(m, Point(150, 50), Point(80, 30), color, 1);
line(m, Point(150, 50), Point(180, 50), color, 1);
line(m, Point(80, 10), Point(80, 90), Scalar::all(200), 1);
line(m, Point(100, 10), Point(100, 90), Scalar::all(200), 1);
line(m, Point(120, 10), Point(120, 90), Scalar::all(200), 1);
#if 0
imshow("image", m);
waitKey();
#endif
}
return m.clone();
}
Mat getTestImage4()
{
static Mat m;
if (m.empty())
{
m.create(Size(200, 100), CV_8UC1);
for (int y = 0; y < m.rows; y++)
{
for (int x = 0; x < m.cols; x++)
{
float dx = (float)(x - 100);
float dy = (float)(y - 100);
float d = sqrtf(dx * dx + dy * dy);
m.at<uchar>(y, x) = saturate_cast<uchar>(100 + 100 * sin(d / 10 * CV_PI));
}
}
#if 0
imshow("image", m);
waitKey();
#endif
}
return m.clone();
}
Mat getTestImage5()
{
static Mat m;
if (m.empty())
{
m.create(Size(200, 100), CV_8UC1);
for (int y = 0; y < m.rows; y++)
{
for (int x = 0; x < m.cols; x++)
{
float dx = (float)(x - 100);
float dy = (float)(y - 100);
float d = sqrtf(dx * dx + dy * dy);
m.at<uchar>(y, x) = saturate_cast<uchar>(x / 2 + 100 * sin(d / 10 * CV_PI));
}
}
#if 0
imshow("image", m);
waitKey();
#endif
}
return m.clone();
}
void show(const Mat& img, const std::vector<Point> pts)
{
if (cvtest::debugLevel >= 10)
{
Mat dst = img.clone();
std::vector< std::vector<Point> > contours;
contours.push_back(pts);
polylines(dst, contours, false, Scalar::all(255));
imshow("dst", dst);
waitKey();
}
}
Size estimateContourSize(const std::vector<Point>& pts)
{
Size s(0,0);
for (size_t i = 0; i < pts.size(); i++)
{
if (s.width < pts[i].x)
s.width = pts[i].x;
if (s.height < pts[i].y)
s.height = pts[i].y;
}
return s;
}
int contoursAreaPixelsMismatch(const std::vector<Point>& pts, const std::vector<Point>& gt)
{
Size ptsSize = estimateContourSize(pts);
Size gtSize = estimateContourSize(gt);
Size imgSize(std::max(ptsSize.width, gtSize.width)+1, std::max(ptsSize.height, gtSize.height)+1);
Mat ptsArea = Mat::zeros(imgSize, CV_8UC1);
Mat gtArea = Mat::zeros(imgSize, CV_8UC1);
std::vector<std::vector<Point>> pts_wrapped = {pts};
std::vector<std::vector<Point>> gt_wrapped = {gt};
drawContours(ptsArea, pts_wrapped, -1, Scalar(255), FILLED);
drawContours(gtArea, gt_wrapped, -1, Scalar(255), FILLED);
Mat uni = ptsArea | gtArea;
Mat intersection = ptsArea & gtArea;
bitwise_not(intersection, intersection);
Mat delta = uni & intersection;
return countNonZero(delta);
}
void checkContour(std::vector<Point>& pts,
const bool backward = false,
int allowed_mismatch = 0)
{
const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
CV_Assert(test_info);
const std::string name = std::string(cvtest::TS::ptr()->get_data_path() + "imgproc/" + test_info->test_case_name() + "-" + test_info->name() + (backward ? "-backward" : "") + ".xml");
std::vector<Point> reference_pts;
#ifdef GENERATE_TEST_DATA
{
cv::FileStorage fs(name, cv::FileStorage::WRITE);
fs << "pts" << pts;
}
reference_pts = pts;
#else
FileStorage fs(name, FileStorage::READ);
read(fs["pts"], reference_pts, std::vector<Point>());
#endif
if (!allowed_mismatch)
EXPECT_EQ(pts, reference_pts);
else
EXPECT_LE(contoursAreaPixelsMismatch(pts, reference_pts), allowed_mismatch);
}
TEST(Imgproc_IntelligentScissorsMB, rect)
{
segmentation::IntelligentScissorsMB tool;
Mat image = getTestImage1();
tool.applyImage(image);
Point source_point(50, 30);
tool.buildMap(source_point);
Point target_point(100, 30);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts);
show(image, pts);
Mat image2 = getTestImage2();
tool.applyImage(image2);
tool.buildMap(source_point);
std::vector<Point> pts2;
tool.getContour(target_point, pts2, true/*backward*/);
checkContour(pts2, true/*backward*/);
show(image2, pts2);
}
TEST(Imgproc_IntelligentScissorsMB, lines)
{
segmentation::IntelligentScissorsMB tool;
Mat image = getTestImage3();
tool.applyImage(image);
Point source_point(30, 50);
tool.buildMap(source_point);
Point target_point(150, 50);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, circles)
{
segmentation::IntelligentScissorsMB tool;
tool.setGradientMagnitudeMaxLimit(10);
Mat image = getTestImage4();
tool.applyImage(image);
Point source_point(50, 50);
tool.buildMap(source_point);
Point target_point(150, 50);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, circles_gradient)
{
segmentation::IntelligentScissorsMB tool;
Mat image = getTestImage5();
tool.applyImage(image);
Point source_point(50, 50);
tool.buildMap(source_point);
Point target_point(150, 50);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, grayscale)
{
segmentation::IntelligentScissorsMB tool;
Mat image = getTestImageGray();
tool.applyImage(image);
Point source_point(275, 63);
tool.buildMap(source_point);
Point target_point(413, 155);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts, false, 2);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_1_0_0_zerro_crossing_with_limit)
{
segmentation::IntelligentScissorsMB tool;
tool.setEdgeFeatureZeroCrossingParameters(64);
tool.setWeights(1.0f, 0.0f, 0.0f);
Mat image = getTestImageGray();
tool.applyImage(image);
Point source_point(275, 63);
tool.buildMap(source_point);
Point target_point(413, 155);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts, false, 11);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_1_0_0_canny)
{
segmentation::IntelligentScissorsMB tool;
tool.setEdgeFeatureCannyParameters(50, 100);
tool.setWeights(1.0f, 0.0f, 0.0f);
Mat image = getTestImageGray();
tool.applyImage(image);
Point source_point(275, 63);
tool.buildMap(source_point);
Point target_point(413, 155);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts, false, 6);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_0_1_0)
{
segmentation::IntelligentScissorsMB tool;
tool.setWeights(0.0f, 1.0f, 0.0f);
Mat image = getTestImageGray();
tool.applyImage(image);
Point source_point(275, 63);
tool.buildMap(source_point);
Point target_point(413, 155);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts, false, 4);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_0_0_1)
{
segmentation::IntelligentScissorsMB tool;
tool.setWeights(0.0f, 0.0f, 1.0f);
Mat image = getTestImageGray();
tool.applyImage(image);
Point source_point(275, 63);
tool.buildMap(source_point);
Point target_point(413, 155);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts, false, 2);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, color)
{
segmentation::IntelligentScissorsMB tool;
Mat image = getTestImageColor();
tool.applyImage(image);
Point source_point(275, 63);
tool.buildMap(source_point);
Point target_point(413, 155);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts, false, 2);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, color_canny)
{
segmentation::IntelligentScissorsMB tool;
tool.setEdgeFeatureCannyParameters(32, 100);
Mat image = getTestImageColor();
tool.applyImage(image);
Point source_point(275, 63);
tool.buildMap(source_point);
Point target_point(413, 155);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts, false, 2);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, color_custom_features_invalid)
{
segmentation::IntelligentScissorsMB tool;
ASSERT_ANY_THROW(tool.applyImageFeatures(noArray(), noArray(), noArray()));
}
TEST(Imgproc_IntelligentScissorsMB, color_custom_features_edge)
{
segmentation::IntelligentScissorsMB tool;
Mat image = getTestImageColor();
Mat canny_edges;
Canny(image, canny_edges, 32, 100, 5);
Mat binary_edge_feature;
cv::threshold(canny_edges, binary_edge_feature, 254, 1, THRESH_BINARY_INV);
tool.applyImageFeatures(binary_edge_feature, noArray(), noArray(), image);
Point source_point(275, 63);
tool.buildMap(source_point);
Point target_point(413, 155);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts, false, 2);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, color_custom_features_all)
{
segmentation::IntelligentScissorsMB tool;
tool.setWeights(0.9f, 0.0f, 0.1f);
Mat image = getTestImageColor();
Mat canny_edges;
Canny(image, canny_edges, 50, 100, 5);
Mat binary_edge_feature; // 0, 1 values
cv::threshold(canny_edges, binary_edge_feature, 254, 1, THRESH_BINARY_INV);
Mat_<Point2f> gradient_direction(image.size(), Point2f(0, 0)); // normalized
Mat_<float> gradient_magnitude(image.size(), 0); // cost function
tool.applyImageFeatures(binary_edge_feature, gradient_direction, gradient_magnitude);
Point source_point(275, 63);
tool.buildMap(source_point);
Point target_point(413, 155);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts, false, 9);
show(image, pts);
}
TEST(Imgproc_IntelligentScissorsMB, color_custom_features_edge_magnitude)
{
segmentation::IntelligentScissorsMB tool;
tool.setWeights(0.9f, 0.0f, 0.1f);
Mat image = getTestImageColor();
Mat canny_edges;
Canny(image, canny_edges, 50, 100, 5);
Mat binary_edge_feature; // 0, 1 values
cv::threshold(canny_edges, binary_edge_feature, 254, 1, THRESH_BINARY_INV);
Mat_<float> gradient_magnitude(image.size(), 0); // cost function
tool.applyImageFeatures(binary_edge_feature, noArray(), gradient_magnitude);
Point source_point(275, 63);
tool.buildMap(source_point);
Point target_point(413, 155);
std::vector<Point> pts;
tool.getContour(target_point, pts);
checkContour(pts, false, 9);
show(image, pts);
}
}} // namespace
+10
View File
@@ -0,0 +1,10 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#if defined(HAVE_HPX)
#include <hpx/hpx_main.hpp>
#endif
CV_TEST_MAIN("cv")
+140
View File
@@ -0,0 +1,140 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
namespace opencv_test { namespace {
static const double numerical_precision = 100.;
TEST(Photo_NPR_EdgePreserveSmoothing_RecursiveFilter, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat result;
edgePreservingFilter(source,result,1);
Mat reference = imread(folder + "smoothened_RF_reference.png");
double psnr = cvtest::PSNR(reference, result);
EXPECT_GT(psnr, 60.0);
}
TEST(Photo_NPR_EdgePreserveSmoothing_NormConvFilter, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat result;
edgePreservingFilter(source,result,2);
Mat reference = imread(folder + "smoothened_NCF_reference.png");
double psnr = cvtest::PSNR(reference, result);
EXPECT_GT(psnr, 60.0);
}
TEST(Photo_NPR_DetailEnhance, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat result;
detailEnhance(source,result);
Mat reference = imread(folder + "detail_enhanced_reference.png");
double psnr = cvtest::PSNR(reference, result);
EXPECT_GT(psnr, 60.0);
}
TEST(Photo_NPR_PencilSketch, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat pencil_result, color_pencil_result;
pencilSketch(source,pencil_result, color_pencil_result, 10, 0.1f, 0.03f);
Mat pencil_reference = imread(folder + "pencil_sketch_reference.png", 0 /* == grayscale*/);
double pencil_error = cvtest::norm(pencil_reference, pencil_result, NORM_L1);
EXPECT_LE(pencil_error, numerical_precision);
Mat color_pencil_reference = imread(folder + "color_pencil_sketch_reference.png");
double color_pencil_error = cvtest::norm(color_pencil_reference, color_pencil_result, NORM_L1);
EXPECT_LE(color_pencil_error, numerical_precision);
}
TEST(Photo_NPR_Stylization, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat result;
stylization(source,result);
Mat stylized_reference = imread(folder + "stylized_reference.png");
double stylized_error = cvtest::norm(stylized_reference, result, NORM_L1);
EXPECT_LE(stylized_error, numerical_precision);
}
}} // namespace
+15
View File
@@ -0,0 +1,15 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_PHOTO_TEST_PRECOMP_HPP
#define OPENCV_PHOTO_TEST_PRECOMP_HPP
#include "opencv2/ts.hpp"
#include "opencv2/ts/ocl_test.hpp"
#include "opencv2/photo.hpp"
namespace opencv_test
{
}
#endif