gapi_frame_tests.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. //
  5. // Copyright (C) 2020 Intel Corporation
  6. #include "test_precomp.hpp"
  7. #include <opencv2/gapi/media.hpp>
  8. ////////////////////////////////////////////////////////////////////////////////
  9. // cv::GFrame tests
  10. namespace opencv_test {
  11. G_API_OP(GBlurFrame, <GMat(GFrame)>, "test.blur_frame") {
  12. static GMatDesc outMeta(GFrameDesc in) {
  13. return cv::GMatDesc(CV_8U,3,in.size);
  14. }
  15. };
  16. GAPI_OCV_KERNEL(OCVBlurFrame, GBlurFrame) {
  17. static void run(const cv::MediaFrame &in, cv::Mat& out) {
  18. GAPI_Assert(in.desc().fmt == cv::MediaFormat::BGR);
  19. cv::MediaFrame::View view = in.access(cv::MediaFrame::Access::R);
  20. cv::blur(cv::Mat(in.desc().size, CV_8UC3, view.ptr[0], view.stride[0]),
  21. out,
  22. cv::Size{3,3});
  23. }
  24. };
  25. G_API_OP(GBlurFrameGray, <GMat(GFrame)>, "test.blur_frame_gray") {
  26. static GMatDesc outMeta(GFrameDesc in) {
  27. return cv::GMatDesc(CV_8U, 1, in.size);
  28. }
  29. };
  30. GAPI_OCV_KERNEL(OCVBlurFrameGray, GBlurFrameGray) {
  31. static void run(const cv::MediaFrame & in, cv::Mat & out) {
  32. GAPI_Assert(in.desc().fmt == cv::MediaFormat::GRAY);
  33. cv::MediaFrame::View view = in.access(cv::MediaFrame::Access::R);
  34. cv::blur(cv::Mat(in.desc().size, CV_8UC1, view.ptr[0], view.stride[0]),
  35. out,
  36. cv::Size{ 3,3 });
  37. }
  38. };
  39. ////////////////////////////////////////////////////////////////////////////////
  40. // cv::MediaFrame tests
  41. namespace {
  42. class TestMediaBGR final: public cv::MediaFrame::IAdapter {
  43. cv::Mat m_mat;
  44. using Cb = cv::MediaFrame::View::Callback;
  45. Cb m_cb;
  46. public:
  47. explicit TestMediaBGR(cv::Mat m, Cb cb = [](){})
  48. : m_mat(m), m_cb(cb) {
  49. }
  50. cv::GFrameDesc meta() const override {
  51. return cv::GFrameDesc{cv::MediaFormat::BGR, cv::Size(m_mat.cols, m_mat.rows)};
  52. }
  53. cv::MediaFrame::View access(cv::MediaFrame::Access) override {
  54. cv::MediaFrame::View::Ptrs pp = { m_mat.ptr(), nullptr, nullptr, nullptr };
  55. cv::MediaFrame::View::Strides ss = { m_mat.step, 0u, 0u, 0u };
  56. return cv::MediaFrame::View(std::move(pp), std::move(ss), Cb{m_cb});
  57. }
  58. };
  59. class TestMediaNV12 final: public cv::MediaFrame::IAdapter {
  60. cv::Mat m_y;
  61. cv::Mat m_uv;
  62. public:
  63. TestMediaNV12(cv::Mat y, cv::Mat uv) : m_y(y), m_uv(uv) {
  64. }
  65. cv::GFrameDesc meta() const override {
  66. return cv::GFrameDesc{cv::MediaFormat::NV12, cv::Size(m_y.cols, m_y.rows)};
  67. }
  68. cv::MediaFrame::View access(cv::MediaFrame::Access) override {
  69. cv::MediaFrame::View::Ptrs pp = {
  70. m_y.ptr(), m_uv.ptr(), nullptr, nullptr
  71. };
  72. cv::MediaFrame::View::Strides ss = {
  73. m_y.step, m_uv.step, 0u, 0u
  74. };
  75. return cv::MediaFrame::View(std::move(pp), std::move(ss));
  76. }
  77. };
  78. class TestMediaGray final : public cv::MediaFrame::IAdapter {
  79. cv::Mat m_mat;
  80. using Cb = cv::MediaFrame::View::Callback;
  81. Cb m_cb;
  82. public:
  83. explicit TestMediaGray(cv::Mat m, Cb cb = []() {})
  84. : m_mat(m), m_cb(cb) {
  85. }
  86. cv::GFrameDesc meta() const override {
  87. return cv::GFrameDesc{ cv::MediaFormat::GRAY, cv::Size(m_mat.cols, m_mat.rows) };
  88. }
  89. cv::MediaFrame::View access(cv::MediaFrame::Access) override {
  90. cv::MediaFrame::View::Ptrs pp = { m_mat.ptr(), nullptr, nullptr, nullptr };
  91. cv::MediaFrame::View::Strides ss = { m_mat.step, 0u, 0u, 0u };
  92. return cv::MediaFrame::View(std::move(pp), std::move(ss), Cb{ m_cb });
  93. }
  94. };
  95. } // anonymous namespace
  96. struct MediaFrame_Test: public ::testing::Test {
  97. using M = cv::Mat;
  98. using MF = cv::MediaFrame;
  99. MF frame;
  100. };
  101. struct MediaFrame_BGR: public MediaFrame_Test {
  102. M bgr;
  103. MediaFrame_BGR()
  104. : bgr(M::eye(240, 320, CV_8UC3)) {
  105. cv::randn(bgr, cv::Scalar::all(127.0f), cv::Scalar::all(40.f));
  106. frame = MF::Create<TestMediaBGR>(bgr);
  107. }
  108. };
  109. TEST_F(MediaFrame_BGR, Meta) {
  110. auto meta = frame.desc();
  111. EXPECT_EQ(cv::MediaFormat::BGR, meta.fmt);
  112. EXPECT_EQ(cv::Size(320,240), meta.size);
  113. }
  114. TEST_F(MediaFrame_BGR, Access) {
  115. cv::MediaFrame::View view1 = frame.access(cv::MediaFrame::Access::R);
  116. EXPECT_EQ(bgr.ptr(), view1.ptr[0]);
  117. EXPECT_EQ(bgr.step, view1.stride[0]);
  118. cv::MediaFrame::View view2 = frame.access(cv::MediaFrame::Access::R);
  119. EXPECT_EQ(bgr.ptr(), view2.ptr[0]);
  120. EXPECT_EQ(bgr.step, view2.stride[0]);
  121. }
  122. TEST_F(MediaFrame_BGR, Input) {
  123. // Run the OpenCV code
  124. cv::Mat out_mat_ocv, out_mat_gapi;
  125. cv::blur(bgr, out_mat_ocv, cv::Size{3,3});
  126. // Run the G-API code
  127. cv::GFrame in;
  128. cv::GMat out = GBlurFrame::on(in);
  129. cv::GComputation(cv::GIn(in), cv::GOut(out))
  130. .apply(cv::gin(frame),
  131. cv::gout(out_mat_gapi),
  132. cv::compile_args(cv::gapi::kernels<OCVBlurFrame>()));
  133. // Compare
  134. EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
  135. }
  136. struct MediaFrame_Gray : public MediaFrame_Test {
  137. M gray;
  138. MediaFrame_Gray()
  139. : gray(M::eye(240, 320, CV_8UC1)) {
  140. cv::randn(gray, cv::Scalar::all(127.0f), cv::Scalar::all(40.f));
  141. frame = MF::Create<TestMediaGray>(gray);
  142. }
  143. };
  144. TEST_F(MediaFrame_Gray, Meta) {
  145. auto meta = frame.desc();
  146. EXPECT_EQ(cv::MediaFormat::GRAY, meta.fmt);
  147. EXPECT_EQ(cv::Size(320, 240), meta.size);
  148. }
  149. TEST_F(MediaFrame_Gray, Access) {
  150. cv::MediaFrame::View view1 = frame.access(cv::MediaFrame::Access::R);
  151. EXPECT_EQ(gray.ptr(), view1.ptr[0]);
  152. EXPECT_EQ(gray.step, view1.stride[0]);
  153. cv::MediaFrame::View view2 = frame.access(cv::MediaFrame::Access::R);
  154. EXPECT_EQ(gray.ptr(), view2.ptr[0]);
  155. EXPECT_EQ(gray.step, view2.stride[0]);
  156. }
  157. TEST_F(MediaFrame_Gray, Input) {
  158. // Run the OpenCV code
  159. cv::Mat out_mat_ocv, out_mat_gapi;
  160. cv::blur(gray, out_mat_ocv, cv::Size{ 3,3 });
  161. // Run the G-API code
  162. cv::GFrame in;
  163. cv::GMat out = GBlurFrameGray::on(in);
  164. cv::GComputation(cv::GIn(in), cv::GOut(out))
  165. .apply(cv::gin(frame),
  166. cv::gout(out_mat_gapi),
  167. cv::compile_args(cv::gapi::kernels<OCVBlurFrameGray>()));
  168. // Compare
  169. EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
  170. }
  171. struct MediaFrame_NV12: public MediaFrame_Test {
  172. cv::Size sz;
  173. cv::Mat buf, y, uv;
  174. MediaFrame_NV12()
  175. : sz {320, 240}
  176. , buf(M::eye(sz.height*3/2, sz.width, CV_8UC1))
  177. , y (buf.rowRange(0, sz.height))
  178. , uv (buf.rowRange(sz.height, sz.height*3/2)) {
  179. frame = MF::Create<TestMediaNV12>(y, uv);
  180. }
  181. };
  182. TEST_F(MediaFrame_NV12, Meta) {
  183. auto meta = frame.desc();
  184. EXPECT_EQ(cv::MediaFormat::NV12, meta.fmt);
  185. EXPECT_EQ(cv::Size(320,240), meta.size);
  186. }
  187. TEST_F(MediaFrame_NV12, Access) {
  188. cv::MediaFrame::View view1 = frame.access(cv::MediaFrame::Access::R);
  189. EXPECT_EQ(y. ptr(), view1.ptr [0]);
  190. EXPECT_EQ(y. step, view1.stride[0]);
  191. EXPECT_EQ(uv.ptr(), view1.ptr [1]);
  192. EXPECT_EQ(uv.step, view1.stride[1]);
  193. cv::MediaFrame::View view2 = frame.access(cv::MediaFrame::Access::R);
  194. EXPECT_EQ(y. ptr(), view2.ptr [0]);
  195. EXPECT_EQ(y. step, view2.stride[0]);
  196. EXPECT_EQ(uv.ptr(), view2.ptr [1]);
  197. EXPECT_EQ(uv.step, view2.stride[1]);
  198. }
  199. TEST(MediaFrame, Callback) {
  200. int counter = 0;
  201. cv::Mat bgr = cv::Mat::eye(240, 320, CV_8UC3);
  202. cv::MediaFrame frame = cv::MediaFrame::Create<TestMediaBGR>(bgr, [&counter](){counter++;});
  203. // Test that the callback (in this case, incrementing the counter)
  204. // is called only on View destruction.
  205. EXPECT_EQ(0, counter);
  206. {
  207. cv::MediaFrame::View v1 = frame.access(cv::MediaFrame::Access::R);
  208. EXPECT_EQ(0, counter);
  209. }
  210. EXPECT_EQ(1, counter);
  211. {
  212. cv::MediaFrame::View v1 = frame.access(cv::MediaFrame::Access::R);
  213. EXPECT_EQ(1, counter);
  214. cv::MediaFrame::View v2 = frame.access(cv::MediaFrame::Access::W);
  215. EXPECT_EQ(1, counter);
  216. }
  217. EXPECT_EQ(3, counter);
  218. }
  219. TEST(MediaFrame, blobParams) {
  220. cv::Mat bgr = cv::Mat::eye(240, 320, CV_8UC3);
  221. cv::MediaFrame frame = cv::MediaFrame::Create<TestMediaBGR>(bgr);
  222. EXPECT_NO_THROW(frame.blobParams());
  223. }
  224. } // namespace opencv_test