gapi_int_pattern_matching_test.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  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 <stdexcept>
  8. #include "compiler/gmodel.hpp"
  9. #include "compiler/gmodel_priv.hpp"
  10. #include "api/gcomputation_priv.hpp"
  11. #include "compiler/gcompiler.hpp"
  12. #include "compiler/gmodelbuilder.hpp"
  13. #include "compiler/passes/passes.hpp"
  14. #include "compiler/passes/pattern_matching.hpp"
  15. #include "../common/gapi_tests_common.hpp"
  16. #include "logger.hpp"
  17. namespace opencv_test
  18. {
  19. namespace matching_test {
  20. namespace {
  21. using V = std::vector<ade::NodeHandle>;
  22. using S = std::unordered_set< ade::NodeHandle
  23. , ade::HandleHasher<ade::Node>
  24. >;
  25. void initGModel(ade::Graph& gr,
  26. cv::GProtoInputArgs&& in,
  27. cv::GProtoOutputArgs&& out) {
  28. cv::gimpl::GModel::Graph gm(gr);
  29. cv::gimpl::GModel::init(gm);
  30. auto proto_slots = cv::gimpl::GModelBuilder(gr)
  31. .put(in.m_args, out.m_args);
  32. cv::gimpl::Protocol p;
  33. std::tie(p.inputs, p.outputs, p.in_nhs, p.out_nhs) = proto_slots;
  34. gm.metadata().set(p);
  35. }
  36. bool isConsumedBy(const cv::gimpl::GModel::ConstGraph &gm, ade::NodeHandle data_nh, ade::NodeHandle op_nh) {
  37. auto oi = cv::gimpl::GModel::orderedInputs(gm, op_nh);
  38. return std::find(oi.begin(), oi.end(), data_nh) != oi.end();
  39. }
  40. std::string opName(const cv::gimpl::GModel::ConstGraph &gm, ade::NodeHandle op_nh) {
  41. return gm.metadata(op_nh).get<cv::gimpl::Op>().k.name;
  42. }
  43. }
  44. } // matching_test
  45. TEST(PatternMatching, TestFuncDoesNotChangeTestGraph)
  46. {
  47. // Pattern
  48. ade::Graph pg;
  49. {
  50. GMat in;
  51. GMat out = cv::gapi::bitwise_not(in);
  52. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
  53. }
  54. // Test
  55. ade::Graph tg;
  56. GMat in;
  57. GMat out = cv::gapi::bitwise_not(in);
  58. matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
  59. // Pattern Matching
  60. cv::gimpl::GModel::Graph pgm(pg);
  61. cv::gimpl::GModel::Graph tgm(tg);
  62. cv::gimpl::findMatches(pg, tg);
  63. // Inspecting results:
  64. matching_test::S nodes{ tgm.nodes().begin(), tgm.nodes().end() };
  65. const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
  66. const auto out_nh = cv::gimpl::GModel::dataNodeOf(tgm, out);
  67. auto input_data_nhs = tgm.metadata().get<cv::gimpl::Protocol>().in_nhs;
  68. auto output_data_nhs = tgm.metadata().get<cv::gimpl::Protocol>().out_nhs;
  69. EXPECT_EQ(1u, input_data_nhs.size());
  70. EXPECT_EQ(1u, output_data_nhs.size());
  71. EXPECT_EQ(in_nh, *input_data_nhs.begin());
  72. EXPECT_EQ(out_nh, *output_data_nhs.begin());
  73. EXPECT_EQ(0u, in_nh->inEdges().size());
  74. EXPECT_EQ(0u, out_nh->outEdges().size());
  75. EXPECT_EQ(1u, in_nh->outEdges().size());
  76. EXPECT_EQ(1u, out_nh->inEdges().size());
  77. const auto op_nh = cv::gimpl::GModel::producerOf(tgm, out_nh); //bitwise_not
  78. EXPECT_EQ(cv::gapi::core::GNot::id(), matching_test::opName(tgm, op_nh));
  79. EXPECT_EQ(1u, op_nh->inEdges().size());
  80. EXPECT_TRUE(matching_test::isConsumedBy(tgm, in_nh, op_nh));
  81. EXPECT_EQ(1u, op_nh->outEdges().size());
  82. }
  83. TEST(PatternMatching, TestSimple1)
  84. {
  85. // Pattern
  86. ade::Graph pg;
  87. {
  88. GMat in;
  89. GMat out = cv::gapi::bitwise_not(in);
  90. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
  91. }
  92. // Test
  93. ade::Graph tg;
  94. GMat in;
  95. GMat out = cv::gapi::bitwise_not(in);
  96. matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
  97. // Pattern Matching
  98. cv::gimpl::GModel::Graph pgm(pg);
  99. cv::gimpl::GModel::Graph tgm(tg);
  100. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  101. // Inspecting results:
  102. EXPECT_TRUE(match.ok());
  103. auto nodes = match.nodes();
  104. EXPECT_EQ(3u, nodes.size());
  105. const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
  106. const auto out_nh = cv::gimpl::GModel::dataNodeOf(tgm, out);
  107. const auto op_nh = cv::gimpl::GModel::producerOf(tgm, out_nh);
  108. EXPECT_EQ(matching_test::S({in_nh, out_nh, op_nh}), nodes);
  109. EXPECT_EQ(cv::gapi::core::GNot::id(), matching_test::opName(tgm, op_nh));
  110. EXPECT_TRUE(matching_test::isConsumedBy(tgm, in_nh, op_nh));
  111. EXPECT_EQ(matching_test::S{op_nh}, match.startOps());
  112. EXPECT_EQ(matching_test::S{op_nh}, match.finishOps());
  113. EXPECT_EQ(matching_test::V{in_nh}, match.protoIns());
  114. EXPECT_EQ(matching_test::V{out_nh}, match.protoOuts());
  115. }
  116. TEST(PatternMatching, TestSimple2)
  117. {
  118. // Pattern
  119. ade::Graph pg;
  120. {
  121. GMat in;
  122. GMat out = cv::gapi::bitwise_not(in);
  123. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
  124. }
  125. // Test
  126. ade::Graph tg;
  127. GMat in;
  128. GMat tmp = cv::gapi::bitwise_not(in);
  129. GMat out = cv::gapi::blur(tmp, cv::Size(3, 3));
  130. matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
  131. // Pattern Matching
  132. cv::gimpl::GModel::Graph pgm(pg);
  133. cv::gimpl::GModel::Graph tgm(tg);
  134. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  135. // Inspecting results:
  136. EXPECT_TRUE(match.ok());
  137. auto nodes = match.nodes();
  138. EXPECT_EQ(3u, nodes.size());
  139. const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
  140. const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp);
  141. const auto op_nh = cv::gimpl::GModel::producerOf(tgm, tmp_nh);
  142. EXPECT_EQ(matching_test::S({in_nh, tmp_nh, op_nh}), nodes);
  143. EXPECT_EQ(cv::gapi::core::GNot::id(), matching_test::opName(tgm, op_nh));
  144. EXPECT_TRUE(matching_test::isConsumedBy(tgm, in_nh, op_nh));
  145. EXPECT_EQ(matching_test::S{op_nh}, match.startOps());
  146. EXPECT_EQ(matching_test::S{op_nh}, match.finishOps());
  147. EXPECT_EQ(matching_test::V{in_nh}, match.protoIns());
  148. EXPECT_EQ(matching_test::V{tmp_nh}, match.protoOuts());
  149. }
  150. TEST(PatternMatching, TestSimple3)
  151. {
  152. // Pattern
  153. ade::Graph pg;
  154. {
  155. GMat in;
  156. GMat out = cv::gapi::bitwise_not(in);
  157. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
  158. }
  159. // Test
  160. ade::Graph tg;
  161. GMat in;
  162. GMat tmp = cv::gapi::blur(in, cv::Size(3, 3));
  163. GMat out = cv::gapi::bitwise_not(tmp);
  164. matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
  165. // Pattern Matching
  166. cv::gimpl::GModel::Graph pgm(pg);
  167. cv::gimpl::GModel::Graph tgm(tg);
  168. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  169. // Inspecting results:
  170. EXPECT_TRUE(match.ok());
  171. auto nodes = match.nodes();
  172. EXPECT_EQ(3u, nodes.size());
  173. const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp);
  174. const auto out_nh = cv::gimpl::GModel::dataNodeOf(tgm, out);
  175. const auto op_nh = cv::gimpl::GModel::producerOf(tgm, out_nh);
  176. EXPECT_EQ(matching_test::S({tmp_nh, out_nh, op_nh}), nodes);
  177. EXPECT_EQ(cv::gapi::core::GNot::id(), matching_test::opName(tgm, op_nh));
  178. EXPECT_TRUE(matching_test::isConsumedBy(tgm, tmp_nh, op_nh));
  179. EXPECT_EQ(matching_test::S{op_nh}, match.startOps());
  180. EXPECT_EQ(matching_test::S{op_nh}, match.finishOps());
  181. EXPECT_EQ(matching_test::V{tmp_nh}, match.protoIns());
  182. EXPECT_EQ(matching_test::V{out_nh}, match.protoOuts());
  183. }
  184. TEST(PatternMatching, TestMultiplePatternOuts)
  185. {
  186. // Pattern
  187. ade::Graph pg;
  188. {
  189. GMat in;
  190. GMat dx, dy;
  191. std::tie(dx, dy) = cv::gapi::SobelXY(in, -1, 1);
  192. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(dx, dy));
  193. }
  194. // Test
  195. ade::Graph tg;
  196. GMat in;
  197. GMat dx, dy;
  198. std::tie(dx, dy) = cv::gapi::SobelXY(in, -1, 1);
  199. matching_test::initGModel(tg, cv::GIn(in), cv::GOut(dx, dy));
  200. // Pattern Matching
  201. cv::gimpl::GModel::Graph pgm(pg);
  202. cv::gimpl::GModel::Graph tgm(tg);
  203. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  204. // Inspecting results:
  205. EXPECT_TRUE(match.ok());
  206. auto nodes = match.nodes();
  207. EXPECT_EQ(4u, nodes.size());
  208. const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
  209. const auto dx_nh = cv::gimpl::GModel::dataNodeOf(tgm, dx);
  210. const auto dy_nh = cv::gimpl::GModel::dataNodeOf(tgm, dy);
  211. const auto op_nh = cv::gimpl::GModel::producerOf(tgm, dx_nh);
  212. EXPECT_EQ(op_nh, cv::gimpl::GModel::producerOf(tgm, dy_nh));
  213. EXPECT_EQ(matching_test::S({in_nh, dx_nh, dy_nh, op_nh}), nodes);
  214. EXPECT_EQ(cv::gapi::imgproc::GSobelXY::id(), matching_test::opName(tgm, op_nh));
  215. EXPECT_TRUE(matching_test::isConsumedBy(tgm, in_nh, op_nh));
  216. EXPECT_EQ(matching_test::S{op_nh}, match.startOps());
  217. EXPECT_EQ(matching_test::S{op_nh}, match.finishOps());
  218. EXPECT_EQ(matching_test::V{in_nh}, match.protoIns());
  219. EXPECT_EQ(matching_test::V({dx_nh, dy_nh}), match.protoOuts());
  220. }
  221. TEST(PatternMatching, TestPrepResizeSplit3)
  222. {
  223. // Pattern
  224. ade::Graph pg;
  225. {
  226. GMat in;
  227. GMat tmp = cv::gapi::resize(in, cv::Size{224, 224});
  228. GMat b, g, r;
  229. std::tie(b, g, r) = cv::gapi::split3(tmp);
  230. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(b, g, r));
  231. }
  232. // Test
  233. ade::Graph tg;
  234. GMat y, uv;
  235. GMat bgr = cv::gapi::NV12toBGR(y, uv);
  236. GMat tmp = cv::gapi::resize(bgr, cv::Size{224, 224});
  237. GMat b, g, r;
  238. std::tie(b, g, r) = cv::gapi::split3(tmp);
  239. matching_test::initGModel(tg, cv::GIn(y, uv), cv::GOut(b, g, r));
  240. // Pattern Matching
  241. cv::gimpl::GModel::Graph pgm(pg);
  242. cv::gimpl::GModel::Graph tgm(tg);
  243. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  244. // Inspecting results:
  245. EXPECT_TRUE(match.ok());
  246. auto nodes = match.nodes();
  247. EXPECT_EQ(7u, nodes.size());
  248. const auto bgr_nh = cv::gimpl::GModel::dataNodeOf(tgm, bgr);
  249. const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp);
  250. const auto b_nh = cv::gimpl::GModel::dataNodeOf(tgm, b);
  251. const auto g_nh = cv::gimpl::GModel::dataNodeOf(tgm, g);
  252. const auto r_nh = cv::gimpl::GModel::dataNodeOf(tgm, r);
  253. const auto op1_nh = cv::gimpl::GModel::producerOf(tgm, tmp_nh); // 1st resize
  254. const auto op2_nh = cv::gimpl::GModel::producerOf(tgm, b_nh); // 2nd split3
  255. EXPECT_EQ(op2_nh, cv::gimpl::GModel::producerOf(tgm, g_nh));
  256. EXPECT_EQ(op2_nh, cv::gimpl::GModel::producerOf(tgm, r_nh));
  257. EXPECT_EQ(matching_test::S({bgr_nh, tmp_nh, b_nh, g_nh,
  258. r_nh, op1_nh, op2_nh}),
  259. nodes);
  260. EXPECT_EQ(cv::gapi::imgproc::GResize::id(), matching_test::opName(tgm, op1_nh));
  261. EXPECT_EQ(cv::gapi::core::GSplit3::id(), matching_test::opName(tgm, op2_nh));
  262. EXPECT_EQ(1u, tmp_nh->outEdges().size());
  263. EXPECT_TRUE(matching_test::isConsumedBy(tgm, bgr_nh, op1_nh));
  264. EXPECT_TRUE(matching_test::isConsumedBy(tgm, tmp_nh, op2_nh));
  265. EXPECT_EQ(matching_test::S{ op1_nh }, match.startOps());
  266. EXPECT_EQ(matching_test::S{ op2_nh }, match.finishOps());
  267. EXPECT_EQ(matching_test::V{ bgr_nh }, match.protoIns());
  268. EXPECT_EQ(matching_test::V({ b_nh, g_nh, r_nh }), match.protoOuts());
  269. }
  270. G_TYPED_KERNEL(GToNCHW, <GMatP(GMat)>, "test.toNCHW") {
  271. static GMatDesc outMeta(GMatDesc in) {
  272. GAPI_Assert(in.depth == CV_8U);
  273. GAPI_Assert(in.chan == 3);
  274. GAPI_Assert(in.planar == false);
  275. return in.asPlanar();
  276. }
  277. };
  278. static GMatP toNCHW(const GMat& src)
  279. {
  280. return GToNCHW::on(src);
  281. }
  282. TEST(PatternMatching, TestPrepResizeToNCHW)
  283. {
  284. // Pattern
  285. ade::Graph pg;
  286. {
  287. GMat in;
  288. GMat tmp = cv::gapi::resize(in, cv::Size{224, 224});
  289. GMatP plr = toNCHW(tmp);
  290. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(plr));
  291. }
  292. // Test
  293. ade::Graph tg;
  294. GMat y, uv;
  295. GMat bgr = cv::gapi::NV12toBGR(y, uv);
  296. GMat tmp = cv::gapi::resize(bgr, cv::Size{224, 224});
  297. GMatP plr = toNCHW(tmp);
  298. matching_test::initGModel(tg, cv::GIn(y, uv), cv::GOut(plr));
  299. // Pattern Matching
  300. cv::gimpl::GModel::Graph pgm(pg);
  301. cv::gimpl::GModel::Graph tgm(tg);
  302. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  303. // Inspecting results:
  304. EXPECT_TRUE(match.ok());
  305. auto nodes = match.nodes();
  306. EXPECT_EQ(5u, nodes.size());
  307. const auto bgr_nh = cv::gimpl::GModel::dataNodeOf(tgm, bgr);
  308. const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp);
  309. const auto plr_nh = cv::gimpl::GModel::dataNodeOf(tgm, plr);
  310. const auto op1_nh = cv::gimpl::GModel::producerOf(tgm, tmp_nh); // 1st resize
  311. const auto op2_nh = cv::gimpl::GModel::producerOf(tgm, plr_nh); // 2nd toNCHW
  312. EXPECT_EQ(matching_test::S({bgr_nh, tmp_nh, plr_nh, op1_nh, op2_nh}),
  313. nodes);
  314. EXPECT_EQ(cv::gapi::imgproc::GResize::id(), matching_test::opName(tgm, op1_nh));
  315. EXPECT_EQ(GToNCHW::id(), matching_test::opName(tgm, op2_nh));
  316. EXPECT_EQ(1u, tmp_nh->outEdges().size());
  317. EXPECT_TRUE(matching_test::isConsumedBy(tgm, bgr_nh, op1_nh));
  318. EXPECT_TRUE(matching_test::isConsumedBy(tgm, tmp_nh, op2_nh));
  319. EXPECT_EQ(matching_test::S{ op1_nh }, match.startOps());
  320. EXPECT_EQ(matching_test::S{ op2_nh }, match.finishOps());
  321. EXPECT_EQ(matching_test::V{ bgr_nh }, match.protoIns());
  322. EXPECT_EQ(matching_test::V{ plr_nh }, match.protoOuts());
  323. }
  324. TEST(PatternMatching, TestPrepNV12toBGRToNCHW)
  325. {
  326. // Pattern
  327. ade::Graph pg;
  328. {
  329. GMat y, uv;
  330. GMat bgr = cv::gapi::NV12toBGR(y, uv);
  331. GMatP plr = toNCHW(bgr);
  332. matching_test::initGModel(pg, cv::GIn(y, uv), cv::GOut(plr));
  333. }
  334. // Test
  335. ade::Graph tg;
  336. GMat y, uv;
  337. GMat bgr = cv::gapi::NV12toBGR(y, uv);
  338. GMatP plr = toNCHW(bgr);
  339. GMat rsz = cv::gapi::resizeP(plr, cv::Size{224, 224});
  340. matching_test::initGModel(tg, cv::GIn(y, uv), cv::GOut(rsz));
  341. // Pattern Matching
  342. cv::gimpl::GModel::Graph pgm(pg);
  343. cv::gimpl::GModel::Graph tgm(tg);
  344. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  345. // Inspecting results:
  346. EXPECT_TRUE(match.ok());
  347. auto nodes = match.nodes();
  348. EXPECT_EQ(6u, nodes.size());
  349. const auto y_nh = cv::gimpl::GModel::dataNodeOf(tgm, y);
  350. const auto uv_nh = cv::gimpl::GModel::dataNodeOf(tgm, uv);
  351. const auto bgr_nh = cv::gimpl::GModel::dataNodeOf(tgm, bgr);
  352. const auto plr_nh = cv::gimpl::GModel::dataNodeOf(tgm, plr);
  353. const auto op1_nh = cv::gimpl::GModel::producerOf(tgm, bgr_nh); // 1st NV12toBGR
  354. const auto op2_nh = cv::gimpl::GModel::producerOf(tgm, plr_nh); // 2nd toNCHW
  355. EXPECT_EQ(matching_test::S({y_nh, uv_nh, bgr_nh, plr_nh, op1_nh, op2_nh}),
  356. nodes);
  357. EXPECT_EQ(cv::gapi::imgproc::GNV12toBGR::id(), matching_test::opName(tgm, op1_nh));
  358. EXPECT_EQ(GToNCHW::id(), matching_test::opName(tgm, op2_nh));
  359. EXPECT_EQ(1u, bgr_nh->outEdges().size());
  360. EXPECT_TRUE(matching_test::isConsumedBy(tgm, y_nh, op1_nh));
  361. EXPECT_TRUE(matching_test::isConsumedBy(tgm, uv_nh, op1_nh));
  362. EXPECT_TRUE(matching_test::isConsumedBy(tgm, bgr_nh, op2_nh));
  363. EXPECT_EQ(matching_test::S{ op1_nh }, match.startOps());
  364. EXPECT_EQ(matching_test::S{ op2_nh }, match.finishOps());
  365. EXPECT_EQ(matching_test::V({ y_nh, uv_nh }), match.protoIns());
  366. EXPECT_EQ(matching_test::V{ plr_nh }, match.protoOuts());
  367. }
  368. //FIXME: To switch from filter2d kernel (which shall be matched by params too) to another one
  369. TEST(PatternMatching, MatchChainInTheMiddle)
  370. {
  371. // Pattern
  372. ade::Graph pg;
  373. {
  374. GMat in;
  375. GMat tmp = cv::gapi::filter2D(in, -1, {});
  376. GMat out = cv::gapi::filter2D(tmp, -1, {});
  377. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
  378. }
  379. // Test
  380. ade::Graph tg;
  381. GMat in;
  382. GMat tmp1 = cv::gapi::erode3x3(in);
  383. GMat tmp2 = cv::gapi::filter2D(tmp1, -1, {});
  384. GMat tmp3 = cv::gapi::filter2D(tmp2, -1, {});
  385. GMat out = cv::gapi::dilate3x3(tmp3);
  386. matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
  387. // Pattern Matching
  388. cv::gimpl::GModel::Graph pgm(pg);
  389. cv::gimpl::GModel::Graph tgm(tg);
  390. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  391. // Inspecting results:
  392. EXPECT_TRUE(match.ok());
  393. auto nodes = match.nodes();
  394. EXPECT_EQ(5u, nodes.size());
  395. const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp1);
  396. const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp2);
  397. const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp3);
  398. const auto op1_nh = cv::gimpl::GModel::producerOf(tgm, tmp2_nh); // 1st filter2D
  399. const auto op2_nh = cv::gimpl::GModel::producerOf(tgm, tmp3_nh); // 2nd filter2D
  400. EXPECT_EQ(matching_test::S({tmp1_nh, tmp2_nh, tmp3_nh, op1_nh, op2_nh}), nodes);
  401. EXPECT_EQ(cv::gapi::imgproc::GFilter2D::id(), matching_test::opName(tgm, op1_nh));
  402. EXPECT_EQ(cv::gapi::imgproc::GFilter2D::id(), matching_test::opName(tgm, op2_nh));
  403. EXPECT_EQ(1u, tmp2_nh->outEdges().size());
  404. EXPECT_TRUE(matching_test::isConsumedBy(tgm, tmp1_nh, op1_nh));
  405. EXPECT_TRUE(matching_test::isConsumedBy(tgm, tmp2_nh, op2_nh));
  406. EXPECT_EQ(matching_test::S({op1_nh}), match.startOps());
  407. EXPECT_EQ(matching_test::S({op2_nh}), match.finishOps());
  408. EXPECT_EQ(matching_test::V{ tmp1_nh }, match.protoIns());
  409. EXPECT_EQ(matching_test::V{ tmp3_nh }, match.protoOuts());
  410. }
  411. TEST(PatternMatching, TestMultipleStartOps1)
  412. {
  413. // Pattern
  414. ade::Graph pg;
  415. {
  416. GMat in1, in2;
  417. GMat er = cv::gapi::erode3x3(in1);
  418. GMat dil = cv::gapi::dilate3x3(in2);
  419. GMat out = cv::gapi::add(er, dil);
  420. matching_test::initGModel(pg, cv::GIn(in1, in2), cv::GOut(out));
  421. }
  422. // Test
  423. ade::Graph tg;
  424. GMat in1, in2, in3, in4, in5, in6;
  425. GMat er1 = cv::gapi::erode3x3(in1);
  426. GMat er2 = cv::gapi::erode3x3(in2);
  427. GMat er3 = cv::gapi::erode3x3(in3);
  428. GMat er4 = cv::gapi::erode3x3(in4);
  429. GMat dil1 = cv::gapi::dilate3x3(in5);
  430. GMat dil2 = cv::gapi::dilate3x3(in6);
  431. GMat out1 = cv::gapi::add(er1, er2);
  432. GMat out2 = cv::gapi::add(er3, dil2);
  433. matching_test::initGModel(tg, cv::GIn(in1, in2, in3, in4, in5, in6), cv::GOut(out1, out2, er4, dil1));
  434. // Pattern Matching
  435. cv::gimpl::GModel::Graph pgm(pg);
  436. cv::gimpl::GModel::Graph tgm(tg);
  437. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  438. // Inspecting results:
  439. EXPECT_TRUE(match.ok());
  440. auto nodes = match.nodes();
  441. EXPECT_EQ(8u, nodes.size());
  442. const auto in3_nh = cv::gimpl::GModel::dataNodeOf(tgm, in3);
  443. const auto in6_nh = cv::gimpl::GModel::dataNodeOf(tgm, in6);
  444. const auto er3_nh = cv::gimpl::GModel::dataNodeOf(tgm, er3);
  445. const auto dil2_nh = cv::gimpl::GModel::dataNodeOf(tgm, dil2);
  446. const auto out2_nh = cv::gimpl::GModel::dataNodeOf(tgm, out2);
  447. const auto er_op_nh = cv::gimpl::GModel::producerOf(tgm, er3_nh);
  448. const auto dil_op_nh = cv::gimpl::GModel::producerOf(tgm, dil2_nh);
  449. const auto add_op_nh = cv::gimpl::GModel::producerOf(tgm, out2_nh);
  450. EXPECT_EQ(matching_test::S({in3_nh, in6_nh, er3_nh, dil2_nh, out2_nh,
  451. er_op_nh, dil_op_nh, add_op_nh}),
  452. nodes);
  453. EXPECT_EQ(cv::gapi::imgproc::GErode::id(), matching_test::opName(tgm, er_op_nh));
  454. EXPECT_EQ(cv::gapi::imgproc::GDilate::id(), matching_test::opName(tgm, dil_op_nh));
  455. EXPECT_EQ(cv::gapi::core::GAdd::id(), matching_test::opName(tgm, add_op_nh));
  456. EXPECT_EQ(1u, er3_nh->outEdges().size());
  457. EXPECT_EQ(1u, dil2_nh->outEdges().size());
  458. EXPECT_TRUE(matching_test::isConsumedBy(tgm, in3_nh, er_op_nh));
  459. EXPECT_TRUE(matching_test::isConsumedBy(tgm, in6_nh, dil_op_nh));
  460. EXPECT_TRUE(matching_test::isConsumedBy(tgm, er3_nh, add_op_nh));
  461. EXPECT_TRUE(matching_test::isConsumedBy(tgm, dil2_nh, add_op_nh));
  462. EXPECT_EQ(matching_test::S({ er_op_nh, dil_op_nh }), match.startOps());
  463. EXPECT_EQ(matching_test::S{ add_op_nh }, match.finishOps());
  464. EXPECT_EQ(matching_test::V({ in3_nh, in6_nh }), match.protoIns());
  465. EXPECT_EQ(matching_test::V{ out2_nh }, match.protoOuts());
  466. }
  467. TEST(PatternMatching, TestMultipleStartOps2)
  468. {
  469. // Pattern
  470. ade::Graph pg;
  471. {
  472. GMat in1, in2;
  473. GMat er = cv::gapi::erode3x3(in1);
  474. GMat dil = cv::gapi::dilate3x3(in2);
  475. GMat out = cv::gapi::add(er, dil);
  476. matching_test::initGModel(pg, cv::GIn(in1, in2), cv::GOut(out));
  477. }
  478. // Test
  479. ade::Graph tg;
  480. GMat in1, in2;
  481. GMat er = cv::gapi::erode3x3(in1);
  482. GMat dil1 = cv::gapi::dilate3x3(in2);
  483. GMat dil2 = cv::gapi::dilate3x3(dil1);
  484. GMat out = cv::gapi::add(er, dil2);
  485. matching_test::initGModel(tg, cv::GIn(in1, in2), cv::GOut(out));
  486. // Pattern Matching
  487. cv::gimpl::GModel::Graph pgm(pg);
  488. cv::gimpl::GModel::Graph tgm(tg);
  489. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  490. // Inspecting results:
  491. EXPECT_TRUE(match.ok());
  492. auto nodes = match.nodes();
  493. EXPECT_EQ(8u, nodes.size());
  494. const auto in1_nh = cv::gimpl::GModel::dataNodeOf(tgm, in1);
  495. const auto dil1_nh = cv::gimpl::GModel::dataNodeOf(tgm, dil1);
  496. const auto er_nh = cv::gimpl::GModel::dataNodeOf(tgm, er);
  497. const auto dil2_nh = cv::gimpl::GModel::dataNodeOf(tgm, dil2);
  498. const auto out_nh = cv::gimpl::GModel::dataNodeOf(tgm, out);
  499. const auto er_op_nh = cv::gimpl::GModel::producerOf(tgm, er_nh);
  500. const auto dil_op_nh = cv::gimpl::GModel::producerOf(tgm, dil2_nh);
  501. const auto add_op_nh = cv::gimpl::GModel::producerOf(tgm, out_nh);
  502. EXPECT_EQ(matching_test::S({in1_nh, dil1_nh, er_nh, dil2_nh, out_nh,
  503. er_op_nh, dil_op_nh, add_op_nh}),
  504. nodes);
  505. EXPECT_EQ(cv::gapi::imgproc::GErode::id(), matching_test::opName(tgm, er_op_nh));
  506. EXPECT_EQ(cv::gapi::imgproc::GDilate::id(), matching_test::opName(tgm, dil_op_nh));
  507. EXPECT_EQ(cv::gapi::core::GAdd::id(), matching_test::opName(tgm, add_op_nh));
  508. EXPECT_EQ(1u, er_nh->outEdges().size());
  509. EXPECT_EQ(1u, dil2_nh->outEdges().size());
  510. EXPECT_TRUE(matching_test::isConsumedBy(tgm, in1_nh, er_op_nh));
  511. EXPECT_TRUE(matching_test::isConsumedBy(tgm, dil1_nh, dil_op_nh));
  512. EXPECT_TRUE(matching_test::isConsumedBy(tgm, er_nh, add_op_nh));
  513. EXPECT_TRUE(matching_test::isConsumedBy(tgm, dil2_nh, add_op_nh));
  514. EXPECT_EQ(matching_test::S({ er_op_nh, dil_op_nh }), match.startOps());
  515. EXPECT_EQ(matching_test::S{ add_op_nh }, match.finishOps());
  516. EXPECT_EQ(matching_test::V({ in1_nh, dil1_nh }), match.protoIns());
  517. EXPECT_EQ(matching_test::V{ out_nh }, match.protoOuts());
  518. }
  519. TEST(PatternMatching, TestInexactMatchOfInOutData)
  520. {
  521. // Pattern
  522. ade::Graph pg;
  523. {
  524. GMat in;
  525. GMat out = cv::gapi::dilate3x3(in);
  526. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
  527. }
  528. // Test
  529. ade::Graph tg;
  530. GMat in;
  531. GMat out1 = cv::gapi::erode3x3(in);
  532. GMat out2 = cv::gapi::boxFilter(in, -1, cv::Size(3, 3));
  533. GMat tmp = cv::gapi::dilate3x3(in);
  534. GScalar out3 = cv::gapi::sum(tmp);
  535. GScalar out4 = cv::gapi::mean(tmp);
  536. matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out1, out2, out3, out4));
  537. // Pattern Matching
  538. cv::gimpl::GModel::Graph pgm(pg);
  539. cv::gimpl::GModel::Graph tgm(tg);
  540. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  541. // Inspecting results:
  542. EXPECT_TRUE(match.ok());
  543. auto nodes = match.nodes();
  544. EXPECT_EQ(3u, nodes.size());
  545. const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
  546. const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp);
  547. const auto op_nh = cv::gimpl::GModel::producerOf(tgm, tmp_nh); // dilate3x3
  548. EXPECT_EQ(matching_test::S({in_nh, tmp_nh, op_nh}),
  549. nodes);
  550. EXPECT_EQ(cv::gapi::imgproc::GDilate::id(), matching_test::opName(tgm, op_nh));
  551. EXPECT_TRUE(matching_test::isConsumedBy(tgm, in_nh, op_nh));
  552. EXPECT_EQ(matching_test::S{ op_nh }, match.startOps());
  553. EXPECT_EQ(matching_test::S{ op_nh }, match.finishOps());
  554. EXPECT_EQ(matching_test::V{ in_nh }, match.protoIns());
  555. EXPECT_EQ(matching_test::V{ tmp_nh }, match.protoOuts());
  556. EXPECT_GT(in_nh->outEdges().size(), 1u);
  557. EXPECT_GT(tmp_nh->outEdges().size(), 1u);
  558. }
  559. //FIXME: The start ops matching shall be reworked to more smarter way.
  560. // Start ops matching shall get rid of non valid matchings sample,
  561. // where two identical start ops in the pattern refer to the only one in the test.
  562. TEST(PatternMatching, TestManySameStartOpsAndHinge)
  563. {
  564. // Pattern
  565. ade::Graph pg;
  566. {
  567. GMat in1, in2, in3;
  568. GMat er1 = cv::gapi::erode3x3(in1);
  569. GMat er2 = cv::gapi::erode3x3(in2);
  570. GMat er3 = cv::gapi::erode3x3(in3);
  571. GMat mrg = cv::gapi::merge3(er1, er2, er3);
  572. matching_test::initGModel(pg, cv::GIn(in1, in2, in3), cv::GOut(mrg));
  573. }
  574. // Test
  575. ade::Graph tg;
  576. GMat in1, in2, in3;
  577. GMat er1 = cv::gapi::erode3x3(in1);
  578. GMat er2 = cv::gapi::erode3x3(in2);
  579. GMat er3 = cv::gapi::erode3x3(in3);
  580. GMat mrg = cv::gapi::merge3(er1, er2, er3);
  581. matching_test::initGModel(tg, cv::GIn(in1, in2, in3), cv::GOut(mrg));
  582. // Pattern Matching
  583. cv::gimpl::GModel::Graph pgm(pg);
  584. cv::gimpl::GModel::Graph tgm(tg);
  585. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  586. // Inspecting results:
  587. EXPECT_TRUE(match.ok());
  588. auto nodes = match.nodes();
  589. EXPECT_EQ(11u, nodes.size());
  590. EXPECT_EQ(matching_test::S(tgm.nodes().begin(), tgm.nodes().end()),
  591. nodes);
  592. }
  593. //FIXME: The start ops matching shall be reworked to more smarter way.
  594. // Start ops matching shall get rid of non valid matchings sample,
  595. // where two identical start ops in the pattern refer to the only one in the test.
  596. TEST(PatternMatching, TestManySameStartOpsAndHinge2)
  597. {
  598. // Pattern
  599. ade::Graph pg;
  600. {
  601. GMat in1, in2, in3;
  602. GMat er1 = cv::gapi::erode3x3(in1);
  603. GMat er2 = cv::gapi::erode3x3(in2);
  604. GMat er3 = cv::gapi::erode3x3(in3);
  605. GMat dil1 = cv::gapi::dilate3x3(er1);
  606. GMat dil2 = cv::gapi::dilate3x3(er2);
  607. GMat dil3 = cv::gapi::dilate3x3(er3);
  608. GMat mrg = cv::gapi::merge3(dil1, dil2, dil3);
  609. matching_test::initGModel(pg, cv::GIn(in1, in2, in3), cv::GOut(mrg));
  610. }
  611. // Test
  612. ade::Graph tg;
  613. GMat in1, in2, in3;
  614. GMat er1 = cv::gapi::erode3x3(in1);
  615. GMat er2 = cv::gapi::erode3x3(in2);
  616. GMat er3 = cv::gapi::erode3x3(in3);
  617. GMat dil1 = cv::gapi::dilate3x3(er1);
  618. GMat dil2 = cv::gapi::dilate3x3(er2);
  619. GMat dil3 = cv::gapi::dilate3x3(er3);
  620. GMat mrg = cv::gapi::merge3(dil1, dil2, dil3);
  621. matching_test::initGModel(tg, cv::GIn(in1, in2, in3), cv::GOut(mrg));
  622. // Pattern Matching
  623. cv::gimpl::GModel::Graph pgm(pg);
  624. cv::gimpl::GModel::Graph tgm(tg);
  625. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  626. // Inspecting results:
  627. EXPECT_TRUE(match.ok());
  628. auto nodes = match.nodes();
  629. EXPECT_EQ(17u, nodes.size());
  630. EXPECT_EQ(matching_test::S(tgm.nodes().begin(), tgm.nodes().end()),
  631. nodes);
  632. }
  633. //FIXME: The start ops matching shall be reworked to more smarter way.
  634. // Start ops matching shall get rid of non valid matchings sample,
  635. // where two identical start ops in the pattern refer to the only one in the test.
  636. TEST(PatternMatching, TestTwoChainsOnTheHingeIsomorphism)
  637. {
  638. // Pattern
  639. ade::Graph pg;
  640. {
  641. GMat in1, in2;
  642. GMat er1 = cv::gapi::erode3x3(in1);
  643. GMat er2 = cv::gapi::erode3x3(in2);
  644. GMat mdb = cv::gapi::medianBlur(er1, 3);
  645. GMat gb = cv::gapi::gaussianBlur(er2, cv::Size(5, 5), 0.12);
  646. GMat conc = cv::gapi::concatVert(mdb, gb);
  647. matching_test::initGModel(pg, cv::GIn(in1, in2), cv::GOut(conc));
  648. }
  649. // Test
  650. ade::Graph tg;
  651. GMat in1, in2;
  652. GMat er1 = cv::gapi::erode3x3(in1);
  653. GMat er2 = cv::gapi::erode3x3(in2);
  654. GMat gb = cv::gapi::gaussianBlur(er1, cv::Size(5, 5), 0.12);
  655. GMat mdb = cv::gapi::medianBlur(er2, 3);
  656. GMat conc = cv::gapi::concatVert(mdb, gb);
  657. matching_test::initGModel(tg, cv::GIn(in1, in2), cv::GOut(conc));
  658. // Pattern Matching
  659. cv::gimpl::GModel::Graph pgm(pg);
  660. cv::gimpl::GModel::Graph tgm(tg);
  661. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  662. // Inspecting results:
  663. EXPECT_TRUE(match.ok());
  664. auto nodes = match.nodes();
  665. EXPECT_EQ(12u, nodes.size());
  666. EXPECT_EQ(matching_test::S(tgm.nodes().begin(), tgm.nodes().end()),
  667. nodes);
  668. const auto in1_nh = cv::gimpl::GModel::dataNodeOf(tgm, in1);
  669. const auto in2_nh = cv::gimpl::GModel::dataNodeOf(tgm, in2);
  670. EXPECT_EQ(matching_test::V({ in2_nh, in1_nh }), match.protoIns());
  671. }
  672. TEST(PatternMatching, TestPatternHasMoreInDataNodes)
  673. {
  674. // Pattern
  675. ade::Graph pg;
  676. {
  677. GMat in1, in2, in3;
  678. GMat out = cv::gapi::merge3(in1, in2, in3);
  679. matching_test::initGModel(pg, cv::GIn(in1, in2, in3), cv::GOut(out));
  680. }
  681. // Test
  682. ade::Graph tg;
  683. GMat in;
  684. GMat out = cv::gapi::merge3(in, in, in);
  685. matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
  686. // Pattern Matching
  687. cv::gimpl::GModel::Graph pgm(pg);
  688. cv::gimpl::GModel::Graph tgm(tg);
  689. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  690. // Inspecting results:
  691. EXPECT_TRUE(match.ok());
  692. auto nodes = match.nodes();
  693. EXPECT_EQ(3u, nodes.size());
  694. EXPECT_EQ(matching_test::S(tgm.nodes().begin(), tgm.nodes().end()),
  695. nodes);
  696. const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
  697. EXPECT_EQ(matching_test::V({ in_nh, in_nh, in_nh }), match.protoIns());
  698. }
  699. TEST(PatternMatching, TestPatternHasFewerInDataNodes)
  700. {
  701. // Pattern
  702. ade::Graph pg;
  703. {
  704. GMat in;
  705. GMat out = cv::gapi::merge3(in, in, in);
  706. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
  707. }
  708. // Test
  709. ade::Graph tg;
  710. GMat in1, in2, in3;
  711. GMat out = cv::gapi::merge3(in1, in2, in3);
  712. matching_test::initGModel(tg, cv::GIn(in1, in2, in3), cv::GOut(out));
  713. // Pattern Matching
  714. cv::gimpl::GModel::Graph pgm(pg);
  715. cv::gimpl::GModel::Graph tgm(tg);
  716. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  717. // Inspecting results:
  718. EXPECT_FALSE(match.ok());
  719. }
  720. TEST(PatternMatching, TestTwoMatchingsOneCorrect)
  721. {
  722. // Pattern
  723. ade::Graph pg;
  724. {
  725. GMat in1, in2;
  726. GMat n = cv::gapi::bitwise_not(in1);
  727. GMat e = cv::gapi::erode3x3(in1);
  728. GMat d = cv::gapi::dilate3x3(in2);
  729. GMat out = cv::gapi::merge3(n, e, d);
  730. matching_test::initGModel(pg, cv::GIn(in1, in2), cv::GOut(out));
  731. }
  732. // Test
  733. ade::Graph tg;
  734. GMat in1, in2;
  735. GMat n = cv::gapi::bitwise_not(in1);
  736. GMat e = cv::gapi::erode3x3(in2);
  737. GMat d = cv::gapi::dilate3x3(in2);
  738. GMat mrg = cv::gapi::merge3(n, e, d);
  739. GMat i, sqi;
  740. std::tie(i, sqi) = cv::gapi::integral(mrg);
  741. GMat n1 = cv::gapi::bitwise_not(i);
  742. GMat e1 = cv::gapi::erode3x3(i);
  743. GMat d1 = cv::gapi::dilate3x3(sqi);
  744. GMat out = cv::gapi::merge3(n1, e1, d1);
  745. matching_test::initGModel(tg, cv::GIn(in1, in2), cv::GOut(out));
  746. // Pattern Matching
  747. cv::gimpl::GModel::Graph pgm(pg);
  748. cv::gimpl::GModel::Graph tgm(tg);
  749. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  750. // Inspecting results:
  751. EXPECT_TRUE(match.ok());
  752. auto nodes = match.nodes();
  753. EXPECT_EQ(10u, nodes.size());
  754. const auto i_nh = cv::gimpl::GModel::dataNodeOf(tgm, i);
  755. const auto sqi_nh = cv::gimpl::GModel::dataNodeOf(tgm, sqi);
  756. const auto n1_nh = cv::gimpl::GModel::dataNodeOf(tgm, n1);
  757. const auto e1_nh = cv::gimpl::GModel::dataNodeOf(tgm, e1);
  758. const auto d1_nh = cv::gimpl::GModel::dataNodeOf(tgm, d1);
  759. const auto out_nh = cv::gimpl::GModel::dataNodeOf(tgm, out);
  760. const auto n_op_nh = cv::gimpl::GModel::producerOf(tgm, n1_nh);
  761. const auto e_op_nh = cv::gimpl::GModel::producerOf(tgm, e1_nh);
  762. const auto d_op_nh = cv::gimpl::GModel::producerOf(tgm, d1_nh);
  763. const auto m_op_nh = cv::gimpl::GModel::producerOf(tgm, out_nh);
  764. EXPECT_EQ(matching_test::S({i_nh, sqi_nh, n1_nh, e1_nh, d1_nh, out_nh,
  765. n_op_nh, e_op_nh, d_op_nh, m_op_nh}), nodes);
  766. EXPECT_EQ(cv::gapi::core::GNot::id(), matching_test::opName(tgm, n_op_nh));
  767. EXPECT_EQ(cv::gapi::imgproc::GErode::id(), matching_test::opName(tgm, e_op_nh));
  768. EXPECT_EQ(cv::gapi::imgproc::GDilate::id(), matching_test::opName(tgm, d_op_nh));
  769. EXPECT_EQ(cv::gapi::core::GMerge3::id(), matching_test::opName(tgm, m_op_nh));
  770. EXPECT_TRUE(matching_test::isConsumedBy(tgm, i_nh, n_op_nh));
  771. EXPECT_TRUE(matching_test::isConsumedBy(tgm, i_nh, e_op_nh));
  772. EXPECT_TRUE(matching_test::isConsumedBy(tgm, sqi_nh, d_op_nh));
  773. EXPECT_TRUE(matching_test::isConsumedBy(tgm, n1_nh, m_op_nh));
  774. EXPECT_TRUE(matching_test::isConsumedBy(tgm, e1_nh, m_op_nh));
  775. EXPECT_TRUE(matching_test::isConsumedBy(tgm, d1_nh, m_op_nh));
  776. EXPECT_EQ(1u, n1_nh->outEdges().size());
  777. EXPECT_EQ(1u, e1_nh->outEdges().size());
  778. EXPECT_EQ(1u, d1_nh->outEdges().size());
  779. EXPECT_EQ(matching_test::S({n_op_nh, e_op_nh, d_op_nh}), match.startOps());
  780. EXPECT_EQ(matching_test::S{m_op_nh}, match.finishOps());
  781. EXPECT_EQ(matching_test::V({i_nh, sqi_nh}), match.protoIns());
  782. EXPECT_EQ(matching_test::V{out_nh}, match.protoOuts());}
  783. TEST(PatternMatching, CheckNoMatch)
  784. {
  785. // Pattern
  786. ade::Graph pg;
  787. {
  788. GMat in;
  789. GMat tmp = cv::gapi::filter2D(in, -1, {});
  790. GMat out = cv::gapi::filter2D(tmp, -1, {});
  791. matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
  792. }
  793. // Test
  794. ade::Graph tg;
  795. {
  796. GMat in;
  797. GMat tmp1 = cv::gapi::erode3x3(in);
  798. GMat out = cv::gapi::dilate3x3(tmp1);
  799. matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
  800. }
  801. // Pattern Matching
  802. cv::gimpl::GModel::Graph pgm(pg);
  803. cv::gimpl::GModel::Graph tgm(tg);
  804. cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
  805. // Inspecting results:
  806. EXPECT_FALSE(match.ok());
  807. }
  808. TEST(PatternMatching, adeSmokeTest)
  809. {
  810. ade::Graph g;
  811. ade::NodeHandle src = g.createNode();
  812. ade::NodeHandle dst = g.createNode();
  813. g.link(src, dst);
  814. g.link(src, dst);
  815. EXPECT_EQ(2u, dst->inNodes().size());
  816. }
  817. } // namespace opencv_test