vendor: OpenCV 5.0.0 snapshot at 40738fb16ceddb5fb3fea747585f7ce6abb0605b
This commit is contained in:
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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")
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user