gapi_opaque_tests.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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) 2019 Intel Corporation
  6. #include "test_precomp.hpp"
  7. #include <string>
  8. #include <utility>
  9. namespace opencv_test
  10. {
  11. namespace ThisTest
  12. {
  13. using GPointOpaque = cv::GOpaque<cv::Point>;
  14. G_TYPED_KERNEL(GeneratePoint, <GPointOpaque(GMat)>, "test.opaque.gen_point")
  15. {
  16. static GOpaqueDesc outMeta(const GMatDesc&) { return empty_gopaque_desc(); }
  17. };
  18. G_TYPED_KERNEL(FillMat, <GMat(cv::GOpaque<int>, int, int, cv::Size)>, "test.opaque.fill_mat")
  19. {
  20. static GMatDesc outMeta(const GOpaqueDesc&, int depth, int chan, cv::Size size)
  21. {
  22. return cv::GMatDesc{depth, chan, size};
  23. }
  24. };
  25. G_TYPED_KERNEL(PaintPoint, <GMat(GPointOpaque, int, int, cv::Size)>, "test.opaque.paint_point")
  26. {
  27. static GMatDesc outMeta(const GOpaqueDesc&, int depth, int chan, cv::Size size)
  28. {
  29. return cv::GMatDesc{depth, chan, size};
  30. }
  31. };
  32. struct MyCustomType{
  33. int num = -1;
  34. std::string s;
  35. };
  36. using GOpaq2 = std::tuple<GOpaque<MyCustomType>,GOpaque<MyCustomType>>;
  37. G_TYPED_KERNEL_M(GenerateOpaque, <GOpaq2(GMat, GMat, std::string)>, "test.opaque.gen_point_multy")
  38. {
  39. static std::tuple<GOpaqueDesc, GOpaqueDesc> outMeta(const GMatDesc&, const GMatDesc&, std::string)
  40. {
  41. return std::make_tuple(empty_gopaque_desc(), empty_gopaque_desc());
  42. }
  43. };
  44. } // namespace ThisTest
  45. namespace
  46. {
  47. GAPI_OCV_KERNEL(OCVGeneratePoint, ThisTest::GeneratePoint)
  48. {
  49. static void run(const cv::Mat&, cv::Point& out)
  50. {
  51. out = cv::Point(42, 42);
  52. }
  53. };
  54. GAPI_OCL_KERNEL(OCLGeneratePoint, ThisTest::GeneratePoint)
  55. {
  56. static void run(const cv::UMat&, cv::Point& out)
  57. {
  58. out = cv::Point(42, 42);
  59. }
  60. };
  61. GAPI_OCV_KERNEL(OCVFillMat, ThisTest::FillMat)
  62. {
  63. static void run(int a, int, int, cv::Size, cv::Mat& out)
  64. {
  65. out = cv::Scalar(a);
  66. }
  67. };
  68. GAPI_OCV_KERNEL(OCVPaintPoint, ThisTest::PaintPoint)
  69. {
  70. static void run(cv::Point a, int, int, cv::Size, cv::Mat& out)
  71. {
  72. out.at<uint8_t>(a) = 77;
  73. }
  74. };
  75. GAPI_OCL_KERNEL(OCLPaintPoint, ThisTest::PaintPoint)
  76. {
  77. static void run(cv::Point a, int depth, int chan, cv::Size size, cv::UMat& out)
  78. {
  79. GAPI_Assert(chan == 1);
  80. out.create(size, CV_MAKETYPE(depth, chan));
  81. cv::drawMarker(out, a, cv::Scalar(77));
  82. }
  83. };
  84. GAPI_OCV_KERNEL(OCVGenerateOpaque, ThisTest::GenerateOpaque)
  85. {
  86. static void run(const cv::Mat& a, const cv::Mat& b, const std::string& s,
  87. ThisTest::MyCustomType &out1, ThisTest::MyCustomType &out2)
  88. {
  89. out1.num = a.size().width * a.size().height;
  90. out1.s = s;
  91. out2.num = b.size().width * b.size().height;
  92. auto s2 = s;
  93. std::reverse(s2.begin(), s2.end());
  94. out2.s = s2;
  95. }
  96. };
  97. } // (anonymous namespace)
  98. TEST(GOpaque, TestOpaqueOut)
  99. {
  100. cv::Mat input = cv::Mat(52, 52, CV_8U);
  101. cv::Point point;
  102. cv::GMat in;
  103. auto out = ThisTest::GeneratePoint::on(in);
  104. cv::GComputation c(cv::GIn(in), cv::GOut(out));
  105. c.apply(cv::gin(input), cv::gout(point), cv::compile_args(cv::gapi::kernels<OCVGeneratePoint>()));
  106. EXPECT_TRUE(point == cv::Point(42, 42));
  107. }
  108. TEST(GOpaque, TestOpaqueIn)
  109. {
  110. cv::Size sz = {42, 42};
  111. int depth = CV_8U;
  112. int chan = 1;
  113. cv::Mat mat = cv::Mat(sz, CV_MAKETYPE(depth, chan));
  114. int fill = 0;
  115. cv::GOpaque<int> in;
  116. auto out = ThisTest::FillMat::on(in, depth, chan, sz);
  117. cv::GComputation c(cv::GIn(in), cv::GOut(out));
  118. c.apply(cv::gin(fill), cv::gout(mat), cv::compile_args(cv::gapi::kernels<OCVFillMat>()));
  119. auto diff = cv::Mat(sz, CV_MAKETYPE(depth, chan), cv::Scalar(fill)) - mat;
  120. EXPECT_EQ(0, cvtest::norm(diff, NORM_INF));
  121. }
  122. TEST(GOpaque, TestOpaqueBetween)
  123. {
  124. cv::Size sz = {50, 50};
  125. int depth = CV_8U;
  126. int chan = 1;
  127. cv::Mat mat_in = cv::Mat::zeros(sz, CV_MAKETYPE(depth, chan));
  128. cv::Mat mat_out = cv::Mat::zeros(sz, CV_MAKETYPE(depth, chan));
  129. cv::GMat in, out;
  130. auto betw = ThisTest::GeneratePoint::on(in);
  131. out = ThisTest::PaintPoint::on(betw, depth, chan, sz);
  132. cv::GComputation c(cv::GIn(in), cv::GOut(out));
  133. c.apply(cv::gin(mat_in), cv::gout(mat_out), cv::compile_args(cv::gapi::kernels<OCVGeneratePoint, OCVPaintPoint>()));
  134. int painted = mat_out.at<uint8_t>(42, 42);
  135. EXPECT_EQ(77, painted);
  136. }
  137. TEST(GOpaque, TestOpaqueBetweenIslands)
  138. {
  139. cv::Size sz = {50, 50};
  140. int depth = CV_8U;
  141. int chan = 1;
  142. cv::Mat mat_in = cv::Mat::zeros(sz, CV_MAKETYPE(depth, chan));
  143. cv::Mat mat_out = cv::Mat::zeros(sz, CV_MAKETYPE(depth, chan));
  144. cv::GMat in, out;
  145. auto betw = ThisTest::GeneratePoint::on(in);
  146. out = ThisTest::PaintPoint::on(betw, depth, chan, sz);
  147. cv::gapi::island("test", cv::GIn(in), cv::GOut(betw));
  148. cv::GComputation c(cv::GIn(in), cv::GOut(out));
  149. c.apply(cv::gin(mat_in), cv::gout(mat_out), cv::compile_args(cv::gapi::kernels<OCVGeneratePoint, OCVPaintPoint>()));
  150. int painted = mat_out.at<uint8_t>(42, 42);
  151. EXPECT_EQ(77, painted);
  152. }
  153. TEST(GOpaque, TestOpaqueCustomOut2)
  154. {
  155. cv::Mat input1 = cv::Mat(52, 52, CV_8U);
  156. cv::Mat input2 = cv::Mat(42, 42, CV_8U);
  157. std::string str = "opaque";
  158. std::string str2 = str;
  159. std::reverse(str2.begin(), str2.end());
  160. ThisTest::MyCustomType out1, out2;
  161. cv::GMat in1, in2;
  162. auto out = ThisTest::GenerateOpaque::on(in1, in2, str);
  163. cv::GComputation c(cv::GIn(in1, in2), cv::GOut(std::get<0>(out), std::get<1>(out)));
  164. c.apply(cv::gin(input1, input2), cv::gout(out1, out2), cv::compile_args(cv::gapi::kernels<OCVGenerateOpaque>()));
  165. EXPECT_EQ(input1.size().width * input1.size().height, out1.num);
  166. EXPECT_EQ(str, out1.s);
  167. EXPECT_EQ(input2.size().width * input2.size().height, out2.num);
  168. EXPECT_EQ(str2, out2.s);
  169. }
  170. TEST(GOpaque, TestOpaqueOCLBackendIn)
  171. {
  172. cv::Point p_in = {42, 42};
  173. cv::Mat mat_out;
  174. ThisTest::GPointOpaque in;
  175. cv::GMat out = ThisTest::PaintPoint::on(in, CV_8U, 1, {50, 50});
  176. cv::GComputation c(cv::GIn(in), cv::GOut(out));
  177. c.apply(cv::gin(p_in), cv::gout(mat_out),
  178. cv::compile_args(cv::gapi::kernels<OCLPaintPoint>()));
  179. int painted = mat_out.at<uint8_t>(42, 42);
  180. EXPECT_EQ(77, painted);
  181. }
  182. TEST(GOpaque, TestOpaqueOCLBackendBetween)
  183. {
  184. cv::Size sz = {50, 50};
  185. int depth = CV_8U;
  186. int chan = 1;
  187. cv::Mat mat_in = cv::Mat::zeros(sz, CV_MAKETYPE(depth, chan));
  188. cv::Mat mat_out;
  189. cv::GMat in;
  190. auto betw = ThisTest::GeneratePoint::on(in);
  191. cv::GMat out = ThisTest::PaintPoint::on(betw, depth, chan, sz);
  192. cv::GComputation c(cv::GIn(in), cv::GOut(out));
  193. c.apply(cv::gin(mat_in), cv::gout(mat_out),
  194. cv::compile_args(cv::gapi::kernels<OCLGeneratePoint, OCLPaintPoint>()));
  195. int painted = mat_out.at<uint8_t>(42, 42);
  196. EXPECT_EQ(77, painted);
  197. }
  198. TEST(GOpaque, TestOpaqueOCLBackendOut)
  199. {
  200. cv::Mat input = cv::Mat(52, 52, CV_8U);
  201. cv::Point p_out;
  202. cv::GMat in;
  203. ThisTest::GPointOpaque out = ThisTest::GeneratePoint::on(in);
  204. cv::GComputation c(cv::GIn(in), cv::GOut(out));
  205. c.apply(cv::gin(input), cv::gout(p_out),
  206. cv::compile_args(cv::gapi::kernels<OCLGeneratePoint>()));
  207. EXPECT_TRUE(p_out == cv::Point(42, 42));
  208. }
  209. TEST(GOpaque_OpaqueRef, TestMov)
  210. {
  211. // Warning: this test is testing some not-very-public APIs
  212. // Test how OpaqueRef's mov() (aka poor man's move()) is working.
  213. using I = std::string;
  214. std::string str = "this string must be long due to short string optimization";
  215. const I gold(str);
  216. I test = gold;
  217. const char* ptr = test.data();
  218. cv::detail::OpaqueRef ref(test);
  219. cv::detail::OpaqueRef mov;
  220. mov.reset<I>();
  221. EXPECT_EQ(gold, ref.rref<I>()); // ref = gold
  222. mov.mov(ref);
  223. EXPECT_EQ(gold, mov.rref<I>()); // mov obtained the data
  224. EXPECT_EQ(ptr, mov.rref<I>().data()); // pointer is unchanged (same data)
  225. EXPECT_EQ(test, ref.rref<I>()); // ref = test
  226. EXPECT_NE(test, mov.rref<I>()); // ref lost the data
  227. }
  228. // types from anonymous namespace doesn't work well with templates
  229. inline namespace gapi_opaque_tests {
  230. struct MyTestStruct {
  231. int i;
  232. float f;
  233. std::string name;
  234. };
  235. }
  236. TEST(GOpaque_OpaqueRef, Kind)
  237. {
  238. cv::detail::OpaqueRef v1(cv::Rect{});
  239. EXPECT_EQ(cv::detail::OpaqueKind::CV_RECT, v1.getKind());
  240. cv::detail::OpaqueRef v3(int{});
  241. EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, v3.getKind());
  242. cv::detail::OpaqueRef v4(double{});
  243. EXPECT_EQ(cv::detail::OpaqueKind::CV_DOUBLE, v4.getKind());
  244. cv::detail::OpaqueRef v6(cv::Point{});
  245. EXPECT_EQ(cv::detail::OpaqueKind::CV_POINT, v6.getKind());
  246. cv::detail::OpaqueRef v7(cv::Size{});
  247. EXPECT_EQ(cv::detail::OpaqueKind::CV_SIZE, v7.getKind());
  248. cv::detail::OpaqueRef v8(std::string{});
  249. EXPECT_EQ(cv::detail::OpaqueKind::CV_STRING, v8.getKind());
  250. cv::detail::OpaqueRef v9(MyTestStruct{});
  251. EXPECT_EQ(cv::detail::OpaqueKind::CV_UNKNOWN, v9.getKind());
  252. }
  253. TEST(GOpaque_OpaqueRef, TestReset)
  254. {
  255. // Warning: this test is testing some not-very-public APIs
  256. cv::detail::OpaqueRef opref(int{42});
  257. EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, opref.getKind());
  258. opref.reset<int>();
  259. EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, opref.getKind());
  260. }
  261. } // namespace opencv_test