test_grfmt.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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) 2000-2008, Intel Corporation, all rights reserved.
  14. // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
  15. // Third party copyrights are property of their respective owners.
  16. //
  17. // Redistribution and use in source and binary forms, with or without modification,
  18. // are permitted provided that the following conditions are met:
  19. //
  20. // * Redistribution's of source code must retain the above copyright notice,
  21. // this list of conditions and the following disclaimer.
  22. //
  23. // * Redistribution's in binary form must reproduce the above copyright notice,
  24. // this list of conditions and the following disclaimer in the documentation
  25. // and/or other materials provided with the distribution.
  26. //
  27. // * The name of the copyright holders may not be used to endorse or promote products
  28. // derived from this software without specific prior written permission.
  29. //
  30. // This software is provided by the copyright holders and contributors "as is" and
  31. // any express or implied warranties, including, but not limited to, the implied
  32. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  33. // In no event shall the Intel Corporation or contributors be liable for any direct,
  34. // indirect, incidental, special, exemplary, or consequential damages
  35. // (including, but not limited to, procurement of substitute goods or services;
  36. // loss of use, data, or profits; or business interruption) however caused
  37. // and on any theory of liability, whether in contract, strict liability,
  38. // or tort (including negligence or otherwise) arising in any way out of
  39. // the use of this software, even if advised of the possibility of such damage.
  40. //
  41. //M*/
  42. #include "test_precomp.hpp"
  43. namespace opencv_test { namespace {
  44. typedef tuple<string, int> File_Mode;
  45. typedef testing::TestWithParam<File_Mode> Imgcodecs_FileMode;
  46. TEST_P(Imgcodecs_FileMode, regression)
  47. {
  48. const string root = cvtest::TS::ptr()->get_data_path();
  49. const string filename = root + get<0>(GetParam());
  50. const int mode = get<1>(GetParam());
  51. const Mat single = imread(filename, mode);
  52. ASSERT_FALSE(single.empty());
  53. vector<Mat> pages;
  54. ASSERT_TRUE(imreadmulti(filename, pages, mode));
  55. ASSERT_FALSE(pages.empty());
  56. const Mat page = pages[0];
  57. ASSERT_FALSE(page.empty());
  58. EXPECT_EQ(page.channels(), single.channels());
  59. EXPECT_EQ(page.depth(), single.depth());
  60. EXPECT_EQ(page.size().height, single.size().height);
  61. EXPECT_EQ(page.size().width, single.size().width);
  62. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), page, single);
  63. }
  64. const string all_images[] =
  65. {
  66. #if (defined(HAVE_JASPER) && defined(OPENCV_IMGCODECS_ENABLE_JASPER_TESTS)) \
  67. || defined(HAVE_OPENJPEG)
  68. "readwrite/Rome.jp2",
  69. "readwrite/Bretagne2.jp2",
  70. "readwrite/Bretagne2.jp2",
  71. "readwrite/Grey.jp2",
  72. "readwrite/Grey.jp2",
  73. "readwrite/balloon.j2c",
  74. #endif
  75. #ifdef HAVE_GDCM
  76. "readwrite/int16-mono1.dcm",
  77. "readwrite/uint8-mono2.dcm",
  78. "readwrite/uint16-mono2.dcm",
  79. "readwrite/uint8-rgb.dcm",
  80. #endif
  81. "readwrite/color_palette_alpha.png",
  82. "readwrite/multipage.tif",
  83. "readwrite/ordinary.bmp",
  84. "readwrite/rle8.bmp",
  85. "readwrite/test_1_c1.jpg",
  86. #ifdef HAVE_IMGCODEC_HDR
  87. "readwrite/rle.hdr"
  88. #endif
  89. };
  90. const int basic_modes[] =
  91. {
  92. IMREAD_UNCHANGED,
  93. IMREAD_GRAYSCALE,
  94. IMREAD_COLOR,
  95. IMREAD_ANYDEPTH,
  96. IMREAD_ANYCOLOR
  97. };
  98. INSTANTIATE_TEST_CASE_P(All, Imgcodecs_FileMode,
  99. testing::Combine(
  100. testing::ValuesIn(all_images),
  101. testing::ValuesIn(basic_modes)));
  102. // GDAL does not support "hdr", "dcm" and has problems with JPEG2000 files (jp2, j2c)
  103. struct notForGDAL {
  104. bool operator()(const string &name) const {
  105. const string &ext = name.substr(name.size() - 3, 3);
  106. return ext == "hdr" || ext == "dcm" || ext == "jp2" || ext == "j2c" ||
  107. name.find("rle8.bmp") != std::string::npos;
  108. }
  109. };
  110. inline vector<string> gdal_images()
  111. {
  112. vector<string> res;
  113. std::back_insert_iterator< vector<string> > it(res);
  114. std::remove_copy_if(all_images, all_images + sizeof(all_images)/sizeof(all_images[0]), it, notForGDAL());
  115. return res;
  116. }
  117. INSTANTIATE_TEST_CASE_P(GDAL, Imgcodecs_FileMode,
  118. testing::Combine(
  119. testing::ValuesIn(gdal_images()),
  120. testing::Values(IMREAD_LOAD_GDAL)));
  121. //==================================================================================================
  122. typedef tuple<string, Size> Ext_Size;
  123. typedef testing::TestWithParam<Ext_Size> Imgcodecs_ExtSize;
  124. TEST_P(Imgcodecs_ExtSize, write_imageseq)
  125. {
  126. const string ext = get<0>(GetParam());
  127. const Size size = get<1>(GetParam());
  128. const Point2i center = Point2i(size.width / 2, size.height / 2);
  129. const int radius = std::min(size.height, size.width / 4);
  130. for (int cn = 1; cn <= 4; cn++)
  131. {
  132. SCOPED_TRACE(format("channels %d", cn));
  133. std::vector<int> parameters;
  134. if (cn == 2)
  135. continue;
  136. if (cn == 4 && ext != ".tiff")
  137. continue;
  138. if (cn > 1 && (ext == ".pbm" || ext == ".pgm"))
  139. continue;
  140. if (cn != 3 && ext == ".ppm")
  141. continue;
  142. string filename = cv::tempfile(format("%d%s", cn, ext.c_str()).c_str());
  143. Mat img_gt(size, CV_MAKETYPE(CV_8U, cn), Scalar::all(0));
  144. circle(img_gt, center, radius, Scalar::all(255));
  145. #if 1
  146. if (ext == ".pbm" || ext == ".pgm" || ext == ".ppm")
  147. {
  148. parameters.push_back(IMWRITE_PXM_BINARY);
  149. parameters.push_back(0);
  150. }
  151. #endif
  152. ASSERT_TRUE(imwrite(filename, img_gt, parameters));
  153. Mat img = imread(filename, IMREAD_UNCHANGED);
  154. ASSERT_FALSE(img.empty());
  155. EXPECT_EQ(img.size(), img.size());
  156. EXPECT_EQ(img.type(), img.type());
  157. EXPECT_EQ(cn, img.channels());
  158. if (ext == ".jpg")
  159. {
  160. // JPEG format does not provide 100% accuracy
  161. // using fuzzy image comparison
  162. double n = cvtest::norm(img, img_gt, NORM_L1);
  163. double expected = 0.07 * img.size().area();
  164. EXPECT_LT(n, expected);
  165. EXPECT_PRED_FORMAT2(cvtest::MatComparator(10, 0), img, img_gt);
  166. }
  167. else if (ext == ".pfm")
  168. {
  169. img_gt.convertTo(img_gt, CV_MAKETYPE(CV_32F, img.channels()));
  170. double n = cvtest::norm(img, img_gt, NORM_L2);
  171. EXPECT_LT(n, 1.);
  172. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, img_gt);
  173. }
  174. else
  175. {
  176. double n = cvtest::norm(img, img_gt, NORM_L2);
  177. EXPECT_LT(n, 1.);
  178. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, img_gt);
  179. }
  180. #if 0
  181. imshow("loaded", img);
  182. waitKey(0);
  183. #else
  184. EXPECT_EQ(0, remove(filename.c_str()));
  185. #endif
  186. }
  187. }
  188. const string all_exts[] =
  189. {
  190. #ifdef HAVE_PNG
  191. ".png",
  192. #endif
  193. #ifdef HAVE_TIFF
  194. ".tiff",
  195. #endif
  196. #ifdef HAVE_JPEG
  197. ".jpg",
  198. #endif
  199. ".bmp",
  200. #ifdef HAVE_IMGCODEC_PXM
  201. ".pam",
  202. ".ppm",
  203. ".pgm",
  204. ".pbm",
  205. ".pnm",
  206. #endif
  207. #ifdef HAVE_IMGCODEC_PFM
  208. ".pfm",
  209. #endif
  210. };
  211. vector<Size> all_sizes()
  212. {
  213. vector<Size> res;
  214. for (int k = 1; k <= 5; ++k)
  215. res.push_back(Size(640 * k, 480 * k));
  216. return res;
  217. }
  218. INSTANTIATE_TEST_CASE_P(All, Imgcodecs_ExtSize,
  219. testing::Combine(
  220. testing::ValuesIn(all_exts),
  221. testing::ValuesIn(all_sizes())));
  222. #ifdef HAVE_IMGCODEC_PXM
  223. typedef testing::TestWithParam<bool> Imgcodecs_pbm;
  224. TEST_P(Imgcodecs_pbm, write_read)
  225. {
  226. bool binary = GetParam();
  227. const String ext = "pbm";
  228. const string full_name = cv::tempfile(ext.c_str());
  229. Size size(640, 480);
  230. const Point2i center = Point2i(size.width / 2, size.height / 2);
  231. const int radius = std::min(size.height, size.width / 4);
  232. Mat image(size, CV_8UC1, Scalar::all(0));
  233. circle(image, center, radius, Scalar::all(255));
  234. vector<int> pbm_params;
  235. pbm_params.push_back(IMWRITE_PXM_BINARY);
  236. pbm_params.push_back(binary);
  237. imwrite( full_name, image, pbm_params );
  238. Mat loaded = imread(full_name, IMREAD_UNCHANGED);
  239. ASSERT_FALSE(loaded.empty());
  240. EXPECT_EQ(0, cvtest::norm(loaded, image, NORM_INF));
  241. FILE *f = fopen(full_name.c_str(), "rb");
  242. ASSERT_TRUE(f != NULL);
  243. ASSERT_EQ('P', getc(f));
  244. ASSERT_EQ('1' + (binary ? 3 : 0), getc(f));
  245. fclose(f);
  246. EXPECT_EQ(0, remove(full_name.c_str()));
  247. }
  248. INSTANTIATE_TEST_CASE_P(All, Imgcodecs_pbm, testing::Bool());
  249. #endif
  250. //==================================================================================================
  251. TEST(Imgcodecs_Bmp, read_rle8)
  252. {
  253. const string root = cvtest::TS::ptr()->get_data_path();
  254. Mat rle = imread(root + "readwrite/rle8.bmp");
  255. ASSERT_FALSE(rle.empty());
  256. Mat ord = imread(root + "readwrite/ordinary.bmp");
  257. ASSERT_FALSE(ord.empty());
  258. EXPECT_LE(cvtest::norm(rle, ord, NORM_L2), 1.e-10);
  259. EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), rle, ord);
  260. }
  261. TEST(Imgcodecs_Bmp, read_32bit_rgb)
  262. {
  263. const string root = cvtest::TS::ptr()->get_data_path();
  264. const string filenameInput = root + "readwrite/test_32bit_rgb.bmp";
  265. const Mat img = cv::imread(filenameInput, IMREAD_UNCHANGED);
  266. ASSERT_FALSE(img.empty());
  267. ASSERT_EQ(CV_8UC3, img.type());
  268. }
  269. TEST(Imgcodecs_Bmp, rgba_bit_mask)
  270. {
  271. const string root = cvtest::TS::ptr()->get_data_path();
  272. const string filenameInput = root + "readwrite/test_rgba_mask.bmp";
  273. const Mat img = cv::imread(filenameInput, IMREAD_UNCHANGED);
  274. ASSERT_FALSE(img.empty());
  275. ASSERT_EQ(CV_8UC4, img.type());
  276. const uchar* data = img.ptr();
  277. ASSERT_EQ(data[3], 255);
  278. }
  279. TEST(Imgcodecs_Bmp, read_32bit_xrgb)
  280. {
  281. const string root = cvtest::TS::ptr()->get_data_path();
  282. const string filenameInput = root + "readwrite/test_32bit_xrgb.bmp";
  283. const Mat img = cv::imread(filenameInput, IMREAD_UNCHANGED);
  284. ASSERT_FALSE(img.empty());
  285. ASSERT_EQ(CV_8UC4, img.type());
  286. const uchar* data = img.ptr();
  287. ASSERT_EQ(data[3], 255);
  288. }
  289. #ifdef HAVE_IMGCODEC_HDR
  290. TEST(Imgcodecs_Hdr, regression)
  291. {
  292. string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/";
  293. string name_rle = folder + "rle.hdr";
  294. string name_no_rle = folder + "no_rle.hdr";
  295. Mat img_rle = imread(name_rle, -1);
  296. ASSERT_FALSE(img_rle.empty()) << "Could not open " << name_rle;
  297. Mat img_no_rle = imread(name_no_rle, -1);
  298. ASSERT_FALSE(img_no_rle.empty()) << "Could not open " << name_no_rle;
  299. double min = 0.0, max = 1.0;
  300. minMaxLoc(abs(img_rle - img_no_rle), &min, &max);
  301. ASSERT_FALSE(max > DBL_EPSILON);
  302. string tmp_file_name = tempfile(".hdr");
  303. vector<int>param(1);
  304. for(int i = 0; i < 2; i++) {
  305. param[0] = i;
  306. imwrite(tmp_file_name, img_rle, param);
  307. Mat written_img = imread(tmp_file_name, -1);
  308. ASSERT_FALSE(written_img.empty()) << "Could not open " << tmp_file_name;
  309. minMaxLoc(abs(img_rle - written_img), &min, &max);
  310. ASSERT_FALSE(max > DBL_EPSILON);
  311. }
  312. remove(tmp_file_name.c_str());
  313. }
  314. #endif
  315. #ifdef HAVE_IMGCODEC_PXM
  316. TEST(Imgcodecs_Pam, read_write)
  317. {
  318. string folder = string(cvtest::TS::ptr()->get_data_path()) + "readwrite/";
  319. string filepath = folder + "lena.pam";
  320. cv::Mat img = cv::imread(filepath);
  321. ASSERT_FALSE(img.empty());
  322. std::vector<int> params;
  323. params.push_back(IMWRITE_PAM_TUPLETYPE);
  324. params.push_back(IMWRITE_PAM_FORMAT_RGB);
  325. string writefile = cv::tempfile(".pam");
  326. EXPECT_NO_THROW(cv::imwrite(writefile, img, params));
  327. cv::Mat reread = cv::imread(writefile);
  328. string writefile_no_param = cv::tempfile(".pam");
  329. EXPECT_NO_THROW(cv::imwrite(writefile_no_param, img));
  330. cv::Mat reread_no_param = cv::imread(writefile_no_param);
  331. EXPECT_EQ(0, cvtest::norm(reread, reread_no_param, NORM_INF));
  332. EXPECT_EQ(0, cvtest::norm(img, reread, NORM_INF));
  333. remove(writefile.c_str());
  334. remove(writefile_no_param.c_str());
  335. }
  336. #endif
  337. #ifdef HAVE_IMGCODEC_PFM
  338. TEST(Imgcodecs_Pfm, read_write)
  339. {
  340. Mat img = imread(findDataFile("readwrite/lena.pam"));
  341. ASSERT_FALSE(img.empty());
  342. img.convertTo(img, CV_32F, 1/255.0f);
  343. std::vector<int> params;
  344. string writefile = cv::tempfile(".pfm");
  345. EXPECT_NO_THROW(cv::imwrite(writefile, img, params));
  346. cv::Mat reread = cv::imread(writefile, IMREAD_UNCHANGED);
  347. string writefile_no_param = cv::tempfile(".pfm");
  348. EXPECT_NO_THROW(cv::imwrite(writefile_no_param, img));
  349. cv::Mat reread_no_param = cv::imread(writefile_no_param, IMREAD_UNCHANGED);
  350. EXPECT_EQ(0, cvtest::norm(reread, reread_no_param, NORM_INF));
  351. EXPECT_EQ(0, cvtest::norm(img, reread, NORM_INF));
  352. EXPECT_EQ(0, remove(writefile.c_str()));
  353. EXPECT_EQ(0, remove(writefile_no_param.c_str()));
  354. }
  355. #endif
  356. TEST(Imgcodecs, write_parameter_type)
  357. {
  358. cv::Mat m(10, 10, CV_8UC1, cv::Scalar::all(0));
  359. cv::Mat1b m_type = cv::Mat1b::zeros(10, 10);
  360. string tmp_file = cv::tempfile(".bmp");
  361. EXPECT_NO_THROW(cv::imwrite(tmp_file, cv::Mat(m * 2))) << "* Failed with cv::Mat";
  362. EXPECT_NO_THROW(cv::imwrite(tmp_file, m * 2)) << "* Failed with cv::MatExpr";
  363. EXPECT_NO_THROW(cv::imwrite(tmp_file, m_type)) << "* Failed with cv::Mat_";
  364. EXPECT_NO_THROW(cv::imwrite(tmp_file, m_type * 2)) << "* Failed with cv::MatExpr(Mat_)";
  365. cv::Matx<uchar, 10, 10> matx;
  366. EXPECT_NO_THROW(cv::imwrite(tmp_file, matx)) << "* Failed with cv::Matx";
  367. EXPECT_EQ(0, remove(tmp_file.c_str()));
  368. }
  369. }} // namespace
  370. #if defined(HAVE_OPENEXR) && defined(OPENCV_IMGCODECS_ENABLE_OPENEXR_TESTS)
  371. #include "test_exr.impl.hpp"
  372. #endif