perf_decode_encode.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html
  4. #include "perf_precomp.hpp"
  5. namespace opencv_test
  6. {
  7. using namespace perf;
  8. static Animation makeCirclesAnimation(Size size = Size(320, 240), int type = CV_8UC4, int nbits = 8, int frameCount = 40)
  9. {
  10. struct AnimatedCircle {
  11. cv::Point2f pos;
  12. cv::Point2f velocity;
  13. float radius;
  14. float radius_speed;
  15. cv::Scalar color;
  16. cv::Scalar border_color;
  17. };
  18. const int numCircles = 80;
  19. const int maxval = (1 << nbits) - 1;
  20. cv::RNG rng = theRNG();
  21. std::vector<AnimatedCircle> circles;
  22. Animation animation;
  23. // Initialize animated circles
  24. for (int i = 0; i < numCircles; ++i) {
  25. AnimatedCircle c;
  26. c.pos = cv::Point2f(rng.uniform(0.f, (float)size.width),
  27. rng.uniform(0.f, (float)size.height));
  28. c.velocity = cv::Point2f(rng.uniform(-2.f, 2.f),
  29. rng.uniform(-2.f, 2.f));
  30. c.radius = rng.uniform(10.f, 40.f);
  31. c.radius_speed = rng.uniform(-0.5f, 0.5f);
  32. c.color = cv::Scalar(rng.uniform(0, maxval),
  33. rng.uniform(0, maxval),
  34. rng.uniform(0, maxval),
  35. rng.uniform(230, maxval));
  36. c.border_color = c.color;
  37. circles.push_back(c);
  38. }
  39. // Generate frames
  40. for (int frame = 0; frame < frameCount; ++frame) {
  41. cv::Mat img(size, type, cv::Scalar(20, 0, 10, 128));
  42. for (size_t i = 0; i < circles.size(); ++i) {
  43. AnimatedCircle& c = circles[i];
  44. // Update position
  45. c.pos += c.velocity;
  46. // Bounce on edges
  47. if (c.pos.x < 0 || c.pos.x > size.width) c.velocity.x *= -1;
  48. if (c.pos.y < 0 || c.pos.y > size.height) c.velocity.y *= -1;
  49. // Update radius
  50. c.radius += c.radius_speed;
  51. if (c.radius < 10.f || c.radius > 80.f) {
  52. c.radius_speed *= -1;
  53. c.radius = std::max(10.f, std::min(c.radius, 80.f));
  54. }
  55. c.color = c.color - Scalar(c.velocity.x, 0, c.velocity.y, rng.uniform(1, 4));
  56. // Draw
  57. cv::circle(img, c.pos, (int)c.radius, c.color, cv::FILLED, cv::LINE_AA);
  58. cv::circle(img, c.pos, (int)c.radius, c.border_color, 1, cv::LINE_AA);
  59. }
  60. animation.frames.push_back(img);
  61. animation.durations.push_back(20); // milliseconds
  62. }
  63. for (int i = (int)animation.frames.size() - 1; i >= 0; --i) {
  64. animation.frames.push_back(animation.frames[i].clone());
  65. animation.durations.push_back(15);
  66. }
  67. return animation;
  68. }
  69. typedef perf::TestBaseWithParam<std::string> Decode;
  70. typedef perf::TestBaseWithParam<std::string> Encode;
  71. const string exts[] = {
  72. #ifdef HAVE_AVIF
  73. ".avif",
  74. #endif
  75. ".bmp",
  76. #ifdef HAVE_IMGCODEC_GIF
  77. ".gif",
  78. #endif
  79. #if (defined(HAVE_JASPER) && defined(OPENCV_IMGCODECS_ENABLE_JASPER_TESTS)) \
  80. || defined(HAVE_OPENJPEG)
  81. ".jp2",
  82. #endif
  83. #ifdef HAVE_JPEG
  84. ".jpg",
  85. #endif
  86. #ifdef HAVE_JPEGXL
  87. ".jxl",
  88. #endif
  89. #ifdef HAVE_PNG
  90. ".png",
  91. #endif
  92. #ifdef HAVE_IMGCODEC_PXM
  93. ".ppm",
  94. #endif
  95. #ifdef HAVE_IMGCODEC_SUNRASTER
  96. ".ras",
  97. #endif
  98. #ifdef HAVE_TIFF
  99. ".tiff",
  100. #endif
  101. #ifdef HAVE_WEBP
  102. ".webp",
  103. #endif
  104. };
  105. const string exts_multi[] = {
  106. #ifdef HAVE_AVIF
  107. ".avif",
  108. #endif
  109. #ifdef HAVE_IMGCODEC_GIF
  110. ".gif",
  111. #endif
  112. #ifdef HAVE_PNG
  113. ".png",
  114. #endif
  115. #ifdef HAVE_TIFF
  116. ".tiff",
  117. #endif
  118. #ifdef HAVE_WEBP
  119. ".webp",
  120. #endif
  121. };
  122. const string exts_anim[] = {
  123. #ifdef HAVE_AVIF
  124. ".avif",
  125. #endif
  126. #ifdef HAVE_IMGCODEC_GIF
  127. ".gif",
  128. #endif
  129. #ifdef HAVE_PNG
  130. ".png",
  131. #endif
  132. #ifdef HAVE_WEBP
  133. ".webp",
  134. #endif
  135. };
  136. #ifdef HAVE_PNG
  137. PERF_TEST_P(Decode, bgr, testing::ValuesIn(exts))
  138. {
  139. String filename = getDataPath("perf/1920x1080.png");
  140. Mat src = imread(filename);
  141. EXPECT_FALSE(src.empty()) << "Cannot open test image perf/1920x1080.png";
  142. vector<uchar> buf;
  143. EXPECT_TRUE(imencode(GetParam(), src, buf));
  144. TEST_CYCLE() imdecode(buf, IMREAD_UNCHANGED);
  145. SANITY_CHECK_NOTHING();
  146. }
  147. PERF_TEST_P(Decode, rgb, testing::ValuesIn(exts))
  148. {
  149. String filename = getDataPath("perf/1920x1080.png");
  150. Mat src = imread(filename);
  151. EXPECT_FALSE(src.empty()) << "Cannot open test image perf/1920x1080.png";
  152. vector<uchar> buf;
  153. EXPECT_TRUE(imencode(GetParam(), src, buf));
  154. TEST_CYCLE() imdecode(buf, IMREAD_COLOR_RGB);
  155. SANITY_CHECK_NOTHING();
  156. }
  157. PERF_TEST_P(Encode, bgr, testing::ValuesIn(exts))
  158. {
  159. String filename = getDataPath("perf/1920x1080.png");
  160. Mat src = imread(filename);
  161. EXPECT_FALSE(src.empty()) << "Cannot open test image perf/1920x1080.png";
  162. vector<uchar> buf;
  163. TEST_CYCLE() imencode(GetParam(), src, buf);
  164. std::cout << " Encoded buffer size: " << buf.size()
  165. << " bytes, Compression ratio: " << std::fixed << std::setprecision(2)
  166. << (static_cast<double>(buf.size()) / (src.total() * src.channels())) * 100.0 << "%" << std::endl;
  167. SANITY_CHECK_NOTHING();
  168. }
  169. PERF_TEST_P(Encode, multi, testing::ValuesIn(exts_multi))
  170. {
  171. String filename = getDataPath("perf/1920x1080.png");
  172. vector<Mat> vec;
  173. EXPECT_TRUE(imreadmulti(filename, vec));
  174. vec.push_back(vec.back().clone());
  175. circle(vec.back(), Point(100, 100), 45, Scalar(0, 0, 255, 0), 2, LINE_AA);
  176. vector<uchar> buf;
  177. EXPECT_TRUE(imwrite("test" + GetParam(), vec));
  178. TEST_CYCLE() imencode(GetParam(), vec, buf);
  179. std::cout << " Encoded buffer size: " << buf.size()
  180. << " bytes, Compression ratio: " << std::fixed << std::setprecision(2)
  181. << (static_cast<double>(buf.size()) / (vec[0].total() * vec[0].channels())) * 100.0 << "%" << std::endl;
  182. SANITY_CHECK_NOTHING();
  183. }
  184. #endif // HAVE_PNG
  185. PERF_TEST_P(Encode, animation, testing::ValuesIn(exts_anim))
  186. {
  187. Animation animation = makeCirclesAnimation();
  188. TEST_CYCLE()
  189. {
  190. vector<uchar> buf;
  191. EXPECT_TRUE(imencodeanimation(GetParam().c_str(), animation, buf));
  192. }
  193. SANITY_CHECK_NOTHING();
  194. }
  195. PERF_TEST_P(Encode, multi_page, testing::ValuesIn(exts_multi))
  196. {
  197. Animation animation = makeCirclesAnimation();
  198. TEST_CYCLE()
  199. {
  200. vector<uchar> buf;
  201. EXPECT_TRUE(imencodemulti(GetParam().c_str(), animation.frames, buf));
  202. }
  203. SANITY_CHECK_NOTHING();
  204. }
  205. PERF_TEST_P(Decode, animation, testing::ValuesIn(exts_anim))
  206. {
  207. Animation animation = makeCirclesAnimation();
  208. vector<uchar> buf;
  209. ASSERT_TRUE(imencodeanimation(GetParam().c_str(), animation, buf));
  210. TEST_CYCLE()
  211. {
  212. Animation tmp_animation;
  213. EXPECT_TRUE(imdecodeanimation(buf, tmp_animation));
  214. }
  215. SANITY_CHECK_NOTHING();
  216. }
  217. PERF_TEST_P(Decode, multi_page, testing::ValuesIn(exts_multi))
  218. {
  219. Animation animation = makeCirclesAnimation();
  220. vector<uchar> buf;
  221. ASSERT_TRUE(imencodemulti(GetParam().c_str(), animation.frames, buf));
  222. TEST_CYCLE()
  223. {
  224. vector<Mat> tmp_frames;
  225. EXPECT_TRUE(imdecodemulti(buf, IMREAD_UNCHANGED, tmp_frames));
  226. }
  227. SANITY_CHECK_NOTHING();
  228. }
  229. } // namespace