1 /*M/////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 // 5 // By downloading, copying, installing or using the software you agree to this license. 6 // If you do not agree to this license, do not download, install, 7 // copy or use the software. 8 // 9 // 10 // License Agreement 11 // For Open Source Computer Vision Library 12 // 13 // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 14 // Third party copyrights are property of their respective owners. 15 // 16 // Redistribution and use in source and binary forms, with or without modification, 17 // are permitted provided that the following conditions are met: 18 // 19 // * Redistribution's of source code must retain the above copyright notice, 20 // this list of conditions and the following disclaimer. 21 // 22 // * Redistribution's in binary form must reproduce the above copyright notice, 23 // this list of conditions and the following disclaimer in the documentation 24 // and/or other materials provided with the distribution. 25 // 26 // * The name of the copyright holders may not be used to endorse or promote products 27 // derived from this software without specific prior written permission. 28 // 29 // This software is provided by the copyright holders and contributors "as is" and 30 // any express or implied warranties, including, but not limited to, the implied 31 // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 // In no event shall the Intel Corporation or contributors be liable for any direct, 33 // indirect, incidental, special, exemplary, or consequential damages 34 // (including, but not limited to, procurement of substitute goods or services; 35 // loss of use, data, or profits; or business interruption) however caused 36 // and on any theory of liability, whether in contract, strict liability, 37 // or tort (including negligence or otherwise) arising in any way out of 38 // the use of this software, even if advised of the possibility of such damage. 39 // 40 //M*/ 41 42 #include "test_precomp.hpp" 43 44 using namespace cv; 45 using namespace std; 46 47 void loadImage(string path, Mat &img) 48 { 49 img = imread(path, -1); 50 ASSERT_FALSE(img.empty()) << "Could not load input image " << path; 51 } 52 53 void checkEqual(Mat img0, Mat img1, double threshold, const string& name) 54 { 55 double max = 1.0; 56 minMaxLoc(abs(img0 - img1), NULL, &max); 57 ASSERT_FALSE(max > threshold) << "max=" << max << " threshold=" << threshold << " method=" << name; 58 } 59 60 static vector<float> DEFAULT_VECTOR; 61 void loadExposureSeq(String path, vector<Mat>& images, vector<float>& times = DEFAULT_VECTOR) 62 { 63 ifstream list_file((path + "list.txt").c_str()); 64 ASSERT_TRUE(list_file.is_open()); 65 string name; 66 float val; 67 while(list_file >> name >> val) { 68 Mat img = imread(path + name); 69 ASSERT_FALSE(img.empty()) << "Could not load input image " << path + name; 70 images.push_back(img); 71 times.push_back(1 / val); 72 } 73 list_file.close(); 74 } 75 76 void loadResponseCSV(String path, Mat& response) 77 { 78 response = Mat(256, 1, CV_32FC3); 79 ifstream resp_file(path.c_str()); 80 for(int i = 0; i < 256; i++) { 81 for(int c = 0; c < 3; c++) { 82 resp_file >> response.at<Vec3f>(i)[c]; 83 resp_file.ignore(1); 84 } 85 } 86 resp_file.close(); 87 } 88 89 TEST(Photo_Tonemap, regression) 90 { 91 string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/tonemap/"; 92 93 Mat img, expected, result; 94 loadImage(test_path + "image.hdr", img); 95 float gamma = 2.2f; 96 97 Ptr<Tonemap> linear = createTonemap(gamma); 98 linear->process(img, result); 99 loadImage(test_path + "linear.png", expected); 100 result.convertTo(result, CV_8UC3, 255); 101 checkEqual(result, expected, 3, "Simple"); 102 103 Ptr<TonemapDrago> drago = createTonemapDrago(gamma); 104 drago->process(img, result); 105 loadImage(test_path + "drago.png", expected); 106 result.convertTo(result, CV_8UC3, 255); 107 checkEqual(result, expected, 3, "Drago"); 108 109 Ptr<TonemapDurand> durand = createTonemapDurand(gamma); 110 durand->process(img, result); 111 loadImage(test_path + "durand.png", expected); 112 result.convertTo(result, CV_8UC3, 255); 113 checkEqual(result, expected, 3, "Durand"); 114 115 Ptr<TonemapReinhard> reinhard = createTonemapReinhard(gamma); 116 reinhard->process(img, result); 117 loadImage(test_path + "reinhard.png", expected); 118 result.convertTo(result, CV_8UC3, 255); 119 checkEqual(result, expected, 3, "Reinhard"); 120 121 Ptr<TonemapMantiuk> mantiuk = createTonemapMantiuk(gamma); 122 mantiuk->process(img, result); 123 loadImage(test_path + "mantiuk.png", expected); 124 result.convertTo(result, CV_8UC3, 255); 125 checkEqual(result, expected, 3, "Mantiuk"); 126 } 127 128 TEST(Photo_AlignMTB, regression) 129 { 130 const int TESTS_COUNT = 100; 131 string folder = string(cvtest::TS::ptr()->get_data_path()) + "shared/"; 132 133 string file_name = folder + "lena.png"; 134 Mat img; 135 loadImage(file_name, img); 136 cvtColor(img, img, COLOR_RGB2GRAY); 137 138 int max_bits = 5; 139 int max_shift = 32; 140 srand(static_cast<unsigned>(time(0))); 141 int errors = 0; 142 143 Ptr<AlignMTB> align = createAlignMTB(max_bits); 144 145 for(int i = 0; i < TESTS_COUNT; i++) { 146 Point shift(rand() % max_shift, rand() % max_shift); 147 Mat res; 148 align->shiftMat(img, res, shift); 149 Point calc = align->calculateShift(img, res); 150 errors += (calc != -shift); 151 } 152 ASSERT_TRUE(errors < 5) << errors << " errors"; 153 } 154 155 TEST(Photo_MergeMertens, regression) 156 { 157 string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/"; 158 159 vector<Mat> images; 160 loadExposureSeq((test_path + "exposures/").c_str() , images); 161 162 Ptr<MergeMertens> merge = createMergeMertens(); 163 164 Mat result, expected; 165 loadImage(test_path + "merge/mertens.png", expected); 166 merge->process(images, result); 167 result.convertTo(result, CV_8UC3, 255); 168 checkEqual(expected, result, 3, "Mertens"); 169 170 Mat uniform(100, 100, CV_8UC3); 171 uniform = Scalar(0, 255, 0); 172 173 images.clear(); 174 images.push_back(uniform); 175 176 merge->process(images, result); 177 result.convertTo(result, CV_8UC3, 255); 178 checkEqual(uniform, result, 1e-2f, "Mertens"); 179 } 180 181 TEST(Photo_MergeDebevec, regression) 182 { 183 string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/"; 184 185 vector<Mat> images; 186 vector<float> times; 187 Mat response; 188 loadExposureSeq(test_path + "exposures/", images, times); 189 loadResponseCSV(test_path + "exposures/response.csv", response); 190 191 Ptr<MergeDebevec> merge = createMergeDebevec(); 192 193 Mat result, expected; 194 loadImage(test_path + "merge/debevec.hdr", expected); 195 merge->process(images, result, times, response); 196 197 Ptr<Tonemap> map = createTonemap(); 198 map->process(result, result); 199 map->process(expected, expected); 200 201 checkEqual(expected, result, 1e-2f, "Debevec"); 202 } 203 204 TEST(Photo_MergeRobertson, regression) 205 { 206 string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/"; 207 208 vector<Mat> images; 209 vector<float> times; 210 loadExposureSeq(test_path + "exposures/", images, times); 211 212 Ptr<MergeRobertson> merge = createMergeRobertson(); 213 214 Mat result, expected; 215 loadImage(test_path + "merge/robertson.hdr", expected); 216 merge->process(images, result, times); 217 Ptr<Tonemap> map = createTonemap(); 218 map->process(result, result); 219 map->process(expected, expected); 220 221 checkEqual(expected, result, 1e-2f, "MergeRobertson"); 222 } 223 224 TEST(Photo_CalibrateDebevec, regression) 225 { 226 string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/"; 227 228 vector<Mat> images; 229 vector<float> times; 230 Mat response, expected; 231 loadExposureSeq(test_path + "exposures/", images, times); 232 loadResponseCSV(test_path + "calibrate/debevec.csv", expected); 233 Ptr<CalibrateDebevec> calibrate = createCalibrateDebevec(); 234 235 calibrate->process(images, response, times); 236 Mat diff = abs(response - expected); 237 diff = diff.mul(1.0f / response); 238 double max; 239 minMaxLoc(diff, NULL, &max); 240 ASSERT_FALSE(max > 0.1); 241 } 242 243 TEST(Photo_CalibrateRobertson, regression) 244 { 245 string test_path = string(cvtest::TS::ptr()->get_data_path()) + "hdr/"; 246 247 vector<Mat> images; 248 vector<float> times; 249 Mat response, expected; 250 loadExposureSeq(test_path + "exposures/", images, times); 251 loadResponseCSV(test_path + "calibrate/robertson.csv", expected); 252 253 Ptr<CalibrateRobertson> calibrate = createCalibrateRobertson(); 254 calibrate->process(images, response, times); 255 checkEqual(expected, response, 1e-3f, "CalibrateRobertson"); 256 } 257