123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997 |
- // This file is part of OpenCV project.
- // It is subject to the license terms in the LICENSE file found in the top-level directory
- // of this distribution and at http://opencv.org/license.html.
- //
- // Copyright (C) 2019 Intel Corporation
- #include "../test_precomp.hpp"
- #include <stdexcept>
- #include "compiler/gmodel.hpp"
- #include "compiler/gmodel_priv.hpp"
- #include "api/gcomputation_priv.hpp"
- #include "compiler/gcompiler.hpp"
- #include "compiler/gmodelbuilder.hpp"
- #include "compiler/passes/passes.hpp"
- #include "compiler/passes/pattern_matching.hpp"
- #include "../common/gapi_tests_common.hpp"
- #include "logger.hpp"
- namespace opencv_test
- {
- namespace matching_test {
- namespace {
- using V = std::vector<ade::NodeHandle>;
- using S = std::unordered_set< ade::NodeHandle
- , ade::HandleHasher<ade::Node>
- >;
- void initGModel(ade::Graph& gr,
- cv::GProtoInputArgs&& in,
- cv::GProtoOutputArgs&& out) {
- cv::gimpl::GModel::Graph gm(gr);
- cv::gimpl::GModel::init(gm);
- auto proto_slots = cv::gimpl::GModelBuilder(gr)
- .put(in.m_args, out.m_args);
- cv::gimpl::Protocol p;
- std::tie(p.inputs, p.outputs, p.in_nhs, p.out_nhs) = proto_slots;
- gm.metadata().set(p);
- }
- bool isConsumedBy(const cv::gimpl::GModel::ConstGraph &gm, ade::NodeHandle data_nh, ade::NodeHandle op_nh) {
- auto oi = cv::gimpl::GModel::orderedInputs(gm, op_nh);
- return std::find(oi.begin(), oi.end(), data_nh) != oi.end();
- }
- std::string opName(const cv::gimpl::GModel::ConstGraph &gm, ade::NodeHandle op_nh) {
- return gm.metadata(op_nh).get<cv::gimpl::Op>().k.name;
- }
- }
- } // matching_test
- TEST(PatternMatching, TestFuncDoesNotChangeTestGraph)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat out = cv::gapi::bitwise_not(in);
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in;
- GMat out = cv::gapi::bitwise_not(in);
- matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- matching_test::S nodes{ tgm.nodes().begin(), tgm.nodes().end() };
- const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
- const auto out_nh = cv::gimpl::GModel::dataNodeOf(tgm, out);
- auto input_data_nhs = tgm.metadata().get<cv::gimpl::Protocol>().in_nhs;
- auto output_data_nhs = tgm.metadata().get<cv::gimpl::Protocol>().out_nhs;
- EXPECT_EQ(1u, input_data_nhs.size());
- EXPECT_EQ(1u, output_data_nhs.size());
- EXPECT_EQ(in_nh, *input_data_nhs.begin());
- EXPECT_EQ(out_nh, *output_data_nhs.begin());
- EXPECT_EQ(0u, in_nh->inEdges().size());
- EXPECT_EQ(0u, out_nh->outEdges().size());
- EXPECT_EQ(1u, in_nh->outEdges().size());
- EXPECT_EQ(1u, out_nh->inEdges().size());
- const auto op_nh = cv::gimpl::GModel::producerOf(tgm, out_nh); //bitwise_not
- EXPECT_EQ(cv::gapi::core::GNot::id(), matching_test::opName(tgm, op_nh));
- EXPECT_EQ(1u, op_nh->inEdges().size());
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, in_nh, op_nh));
- EXPECT_EQ(1u, op_nh->outEdges().size());
- }
- TEST(PatternMatching, TestSimple1)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat out = cv::gapi::bitwise_not(in);
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in;
- GMat out = cv::gapi::bitwise_not(in);
- matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(3u, nodes.size());
- const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
- const auto out_nh = cv::gimpl::GModel::dataNodeOf(tgm, out);
- const auto op_nh = cv::gimpl::GModel::producerOf(tgm, out_nh);
- EXPECT_EQ(matching_test::S({in_nh, out_nh, op_nh}), nodes);
- EXPECT_EQ(cv::gapi::core::GNot::id(), matching_test::opName(tgm, op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, in_nh, op_nh));
- EXPECT_EQ(matching_test::S{op_nh}, match.startOps());
- EXPECT_EQ(matching_test::S{op_nh}, match.finishOps());
- EXPECT_EQ(matching_test::V{in_nh}, match.protoIns());
- EXPECT_EQ(matching_test::V{out_nh}, match.protoOuts());
- }
- TEST(PatternMatching, TestSimple2)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat out = cv::gapi::bitwise_not(in);
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in;
- GMat tmp = cv::gapi::bitwise_not(in);
- GMat out = cv::gapi::blur(tmp, cv::Size(3, 3));
- matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(3u, nodes.size());
- const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
- const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp);
- const auto op_nh = cv::gimpl::GModel::producerOf(tgm, tmp_nh);
- EXPECT_EQ(matching_test::S({in_nh, tmp_nh, op_nh}), nodes);
- EXPECT_EQ(cv::gapi::core::GNot::id(), matching_test::opName(tgm, op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, in_nh, op_nh));
- EXPECT_EQ(matching_test::S{op_nh}, match.startOps());
- EXPECT_EQ(matching_test::S{op_nh}, match.finishOps());
- EXPECT_EQ(matching_test::V{in_nh}, match.protoIns());
- EXPECT_EQ(matching_test::V{tmp_nh}, match.protoOuts());
- }
- TEST(PatternMatching, TestSimple3)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat out = cv::gapi::bitwise_not(in);
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in;
- GMat tmp = cv::gapi::blur(in, cv::Size(3, 3));
- GMat out = cv::gapi::bitwise_not(tmp);
- matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(3u, nodes.size());
- const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp);
- const auto out_nh = cv::gimpl::GModel::dataNodeOf(tgm, out);
- const auto op_nh = cv::gimpl::GModel::producerOf(tgm, out_nh);
- EXPECT_EQ(matching_test::S({tmp_nh, out_nh, op_nh}), nodes);
- EXPECT_EQ(cv::gapi::core::GNot::id(), matching_test::opName(tgm, op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, tmp_nh, op_nh));
- EXPECT_EQ(matching_test::S{op_nh}, match.startOps());
- EXPECT_EQ(matching_test::S{op_nh}, match.finishOps());
- EXPECT_EQ(matching_test::V{tmp_nh}, match.protoIns());
- EXPECT_EQ(matching_test::V{out_nh}, match.protoOuts());
- }
- TEST(PatternMatching, TestMultiplePatternOuts)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat dx, dy;
- std::tie(dx, dy) = cv::gapi::SobelXY(in, -1, 1);
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(dx, dy));
- }
- // Test
- ade::Graph tg;
- GMat in;
- GMat dx, dy;
- std::tie(dx, dy) = cv::gapi::SobelXY(in, -1, 1);
- matching_test::initGModel(tg, cv::GIn(in), cv::GOut(dx, dy));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(4u, nodes.size());
- const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
- const auto dx_nh = cv::gimpl::GModel::dataNodeOf(tgm, dx);
- const auto dy_nh = cv::gimpl::GModel::dataNodeOf(tgm, dy);
- const auto op_nh = cv::gimpl::GModel::producerOf(tgm, dx_nh);
- EXPECT_EQ(op_nh, cv::gimpl::GModel::producerOf(tgm, dy_nh));
- EXPECT_EQ(matching_test::S({in_nh, dx_nh, dy_nh, op_nh}), nodes);
- EXPECT_EQ(cv::gapi::imgproc::GSobelXY::id(), matching_test::opName(tgm, op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, in_nh, op_nh));
- EXPECT_EQ(matching_test::S{op_nh}, match.startOps());
- EXPECT_EQ(matching_test::S{op_nh}, match.finishOps());
- EXPECT_EQ(matching_test::V{in_nh}, match.protoIns());
- EXPECT_EQ(matching_test::V({dx_nh, dy_nh}), match.protoOuts());
- }
- TEST(PatternMatching, TestPrepResizeSplit3)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat tmp = cv::gapi::resize(in, cv::Size{224, 224});
- GMat b, g, r;
- std::tie(b, g, r) = cv::gapi::split3(tmp);
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(b, g, r));
- }
- // Test
- ade::Graph tg;
- GMat y, uv;
- GMat bgr = cv::gapi::NV12toBGR(y, uv);
- GMat tmp = cv::gapi::resize(bgr, cv::Size{224, 224});
- GMat b, g, r;
- std::tie(b, g, r) = cv::gapi::split3(tmp);
- matching_test::initGModel(tg, cv::GIn(y, uv), cv::GOut(b, g, r));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(7u, nodes.size());
- const auto bgr_nh = cv::gimpl::GModel::dataNodeOf(tgm, bgr);
- const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp);
- const auto b_nh = cv::gimpl::GModel::dataNodeOf(tgm, b);
- const auto g_nh = cv::gimpl::GModel::dataNodeOf(tgm, g);
- const auto r_nh = cv::gimpl::GModel::dataNodeOf(tgm, r);
- const auto op1_nh = cv::gimpl::GModel::producerOf(tgm, tmp_nh); // 1st resize
- const auto op2_nh = cv::gimpl::GModel::producerOf(tgm, b_nh); // 2nd split3
- EXPECT_EQ(op2_nh, cv::gimpl::GModel::producerOf(tgm, g_nh));
- EXPECT_EQ(op2_nh, cv::gimpl::GModel::producerOf(tgm, r_nh));
- EXPECT_EQ(matching_test::S({bgr_nh, tmp_nh, b_nh, g_nh,
- r_nh, op1_nh, op2_nh}),
- nodes);
- EXPECT_EQ(cv::gapi::imgproc::GResize::id(), matching_test::opName(tgm, op1_nh));
- EXPECT_EQ(cv::gapi::core::GSplit3::id(), matching_test::opName(tgm, op2_nh));
- EXPECT_EQ(1u, tmp_nh->outEdges().size());
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, bgr_nh, op1_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, tmp_nh, op2_nh));
- EXPECT_EQ(matching_test::S{ op1_nh }, match.startOps());
- EXPECT_EQ(matching_test::S{ op2_nh }, match.finishOps());
- EXPECT_EQ(matching_test::V{ bgr_nh }, match.protoIns());
- EXPECT_EQ(matching_test::V({ b_nh, g_nh, r_nh }), match.protoOuts());
- }
- G_TYPED_KERNEL(GToNCHW, <GMatP(GMat)>, "test.toNCHW") {
- static GMatDesc outMeta(GMatDesc in) {
- GAPI_Assert(in.depth == CV_8U);
- GAPI_Assert(in.chan == 3);
- GAPI_Assert(in.planar == false);
- return in.asPlanar();
- }
- };
- static GMatP toNCHW(const GMat& src)
- {
- return GToNCHW::on(src);
- }
- TEST(PatternMatching, TestPrepResizeToNCHW)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat tmp = cv::gapi::resize(in, cv::Size{224, 224});
- GMatP plr = toNCHW(tmp);
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(plr));
- }
- // Test
- ade::Graph tg;
- GMat y, uv;
- GMat bgr = cv::gapi::NV12toBGR(y, uv);
- GMat tmp = cv::gapi::resize(bgr, cv::Size{224, 224});
- GMatP plr = toNCHW(tmp);
- matching_test::initGModel(tg, cv::GIn(y, uv), cv::GOut(plr));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(5u, nodes.size());
- const auto bgr_nh = cv::gimpl::GModel::dataNodeOf(tgm, bgr);
- const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp);
- const auto plr_nh = cv::gimpl::GModel::dataNodeOf(tgm, plr);
- const auto op1_nh = cv::gimpl::GModel::producerOf(tgm, tmp_nh); // 1st resize
- const auto op2_nh = cv::gimpl::GModel::producerOf(tgm, plr_nh); // 2nd toNCHW
- EXPECT_EQ(matching_test::S({bgr_nh, tmp_nh, plr_nh, op1_nh, op2_nh}),
- nodes);
- EXPECT_EQ(cv::gapi::imgproc::GResize::id(), matching_test::opName(tgm, op1_nh));
- EXPECT_EQ(GToNCHW::id(), matching_test::opName(tgm, op2_nh));
- EXPECT_EQ(1u, tmp_nh->outEdges().size());
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, bgr_nh, op1_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, tmp_nh, op2_nh));
- EXPECT_EQ(matching_test::S{ op1_nh }, match.startOps());
- EXPECT_EQ(matching_test::S{ op2_nh }, match.finishOps());
- EXPECT_EQ(matching_test::V{ bgr_nh }, match.protoIns());
- EXPECT_EQ(matching_test::V{ plr_nh }, match.protoOuts());
- }
- TEST(PatternMatching, TestPrepNV12toBGRToNCHW)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat y, uv;
- GMat bgr = cv::gapi::NV12toBGR(y, uv);
- GMatP plr = toNCHW(bgr);
- matching_test::initGModel(pg, cv::GIn(y, uv), cv::GOut(plr));
- }
- // Test
- ade::Graph tg;
- GMat y, uv;
- GMat bgr = cv::gapi::NV12toBGR(y, uv);
- GMatP plr = toNCHW(bgr);
- GMat rsz = cv::gapi::resizeP(plr, cv::Size{224, 224});
- matching_test::initGModel(tg, cv::GIn(y, uv), cv::GOut(rsz));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(6u, nodes.size());
- const auto y_nh = cv::gimpl::GModel::dataNodeOf(tgm, y);
- const auto uv_nh = cv::gimpl::GModel::dataNodeOf(tgm, uv);
- const auto bgr_nh = cv::gimpl::GModel::dataNodeOf(tgm, bgr);
- const auto plr_nh = cv::gimpl::GModel::dataNodeOf(tgm, plr);
- const auto op1_nh = cv::gimpl::GModel::producerOf(tgm, bgr_nh); // 1st NV12toBGR
- const auto op2_nh = cv::gimpl::GModel::producerOf(tgm, plr_nh); // 2nd toNCHW
- EXPECT_EQ(matching_test::S({y_nh, uv_nh, bgr_nh, plr_nh, op1_nh, op2_nh}),
- nodes);
- EXPECT_EQ(cv::gapi::imgproc::GNV12toBGR::id(), matching_test::opName(tgm, op1_nh));
- EXPECT_EQ(GToNCHW::id(), matching_test::opName(tgm, op2_nh));
- EXPECT_EQ(1u, bgr_nh->outEdges().size());
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, y_nh, op1_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, uv_nh, op1_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, bgr_nh, op2_nh));
- EXPECT_EQ(matching_test::S{ op1_nh }, match.startOps());
- EXPECT_EQ(matching_test::S{ op2_nh }, match.finishOps());
- EXPECT_EQ(matching_test::V({ y_nh, uv_nh }), match.protoIns());
- EXPECT_EQ(matching_test::V{ plr_nh }, match.protoOuts());
- }
- //FIXME: To switch from filter2d kernel (which shall be matched by params too) to another one
- TEST(PatternMatching, MatchChainInTheMiddle)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat tmp = cv::gapi::filter2D(in, -1, {});
- GMat out = cv::gapi::filter2D(tmp, -1, {});
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in;
- GMat tmp1 = cv::gapi::erode3x3(in);
- GMat tmp2 = cv::gapi::filter2D(tmp1, -1, {});
- GMat tmp3 = cv::gapi::filter2D(tmp2, -1, {});
- GMat out = cv::gapi::dilate3x3(tmp3);
- matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(5u, nodes.size());
- const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp1);
- const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp2);
- const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp3);
- const auto op1_nh = cv::gimpl::GModel::producerOf(tgm, tmp2_nh); // 1st filter2D
- const auto op2_nh = cv::gimpl::GModel::producerOf(tgm, tmp3_nh); // 2nd filter2D
- EXPECT_EQ(matching_test::S({tmp1_nh, tmp2_nh, tmp3_nh, op1_nh, op2_nh}), nodes);
- EXPECT_EQ(cv::gapi::imgproc::GFilter2D::id(), matching_test::opName(tgm, op1_nh));
- EXPECT_EQ(cv::gapi::imgproc::GFilter2D::id(), matching_test::opName(tgm, op2_nh));
- EXPECT_EQ(1u, tmp2_nh->outEdges().size());
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, tmp1_nh, op1_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, tmp2_nh, op2_nh));
- EXPECT_EQ(matching_test::S({op1_nh}), match.startOps());
- EXPECT_EQ(matching_test::S({op2_nh}), match.finishOps());
- EXPECT_EQ(matching_test::V{ tmp1_nh }, match.protoIns());
- EXPECT_EQ(matching_test::V{ tmp3_nh }, match.protoOuts());
- }
- TEST(PatternMatching, TestMultipleStartOps1)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in1, in2;
- GMat er = cv::gapi::erode3x3(in1);
- GMat dil = cv::gapi::dilate3x3(in2);
- GMat out = cv::gapi::add(er, dil);
- matching_test::initGModel(pg, cv::GIn(in1, in2), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in1, in2, in3, in4, in5, in6;
- GMat er1 = cv::gapi::erode3x3(in1);
- GMat er2 = cv::gapi::erode3x3(in2);
- GMat er3 = cv::gapi::erode3x3(in3);
- GMat er4 = cv::gapi::erode3x3(in4);
- GMat dil1 = cv::gapi::dilate3x3(in5);
- GMat dil2 = cv::gapi::dilate3x3(in6);
- GMat out1 = cv::gapi::add(er1, er2);
- GMat out2 = cv::gapi::add(er3, dil2);
- matching_test::initGModel(tg, cv::GIn(in1, in2, in3, in4, in5, in6), cv::GOut(out1, out2, er4, dil1));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(8u, nodes.size());
- const auto in3_nh = cv::gimpl::GModel::dataNodeOf(tgm, in3);
- const auto in6_nh = cv::gimpl::GModel::dataNodeOf(tgm, in6);
- const auto er3_nh = cv::gimpl::GModel::dataNodeOf(tgm, er3);
- const auto dil2_nh = cv::gimpl::GModel::dataNodeOf(tgm, dil2);
- const auto out2_nh = cv::gimpl::GModel::dataNodeOf(tgm, out2);
- const auto er_op_nh = cv::gimpl::GModel::producerOf(tgm, er3_nh);
- const auto dil_op_nh = cv::gimpl::GModel::producerOf(tgm, dil2_nh);
- const auto add_op_nh = cv::gimpl::GModel::producerOf(tgm, out2_nh);
- EXPECT_EQ(matching_test::S({in3_nh, in6_nh, er3_nh, dil2_nh, out2_nh,
- er_op_nh, dil_op_nh, add_op_nh}),
- nodes);
- EXPECT_EQ(cv::gapi::imgproc::GErode::id(), matching_test::opName(tgm, er_op_nh));
- EXPECT_EQ(cv::gapi::imgproc::GDilate::id(), matching_test::opName(tgm, dil_op_nh));
- EXPECT_EQ(cv::gapi::core::GAdd::id(), matching_test::opName(tgm, add_op_nh));
- EXPECT_EQ(1u, er3_nh->outEdges().size());
- EXPECT_EQ(1u, dil2_nh->outEdges().size());
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, in3_nh, er_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, in6_nh, dil_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, er3_nh, add_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, dil2_nh, add_op_nh));
- EXPECT_EQ(matching_test::S({ er_op_nh, dil_op_nh }), match.startOps());
- EXPECT_EQ(matching_test::S{ add_op_nh }, match.finishOps());
- EXPECT_EQ(matching_test::V({ in3_nh, in6_nh }), match.protoIns());
- EXPECT_EQ(matching_test::V{ out2_nh }, match.protoOuts());
- }
- TEST(PatternMatching, TestMultipleStartOps2)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in1, in2;
- GMat er = cv::gapi::erode3x3(in1);
- GMat dil = cv::gapi::dilate3x3(in2);
- GMat out = cv::gapi::add(er, dil);
- matching_test::initGModel(pg, cv::GIn(in1, in2), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in1, in2;
- GMat er = cv::gapi::erode3x3(in1);
- GMat dil1 = cv::gapi::dilate3x3(in2);
- GMat dil2 = cv::gapi::dilate3x3(dil1);
- GMat out = cv::gapi::add(er, dil2);
- matching_test::initGModel(tg, cv::GIn(in1, in2), cv::GOut(out));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(8u, nodes.size());
- const auto in1_nh = cv::gimpl::GModel::dataNodeOf(tgm, in1);
- const auto dil1_nh = cv::gimpl::GModel::dataNodeOf(tgm, dil1);
- const auto er_nh = cv::gimpl::GModel::dataNodeOf(tgm, er);
- const auto dil2_nh = cv::gimpl::GModel::dataNodeOf(tgm, dil2);
- const auto out_nh = cv::gimpl::GModel::dataNodeOf(tgm, out);
- const auto er_op_nh = cv::gimpl::GModel::producerOf(tgm, er_nh);
- const auto dil_op_nh = cv::gimpl::GModel::producerOf(tgm, dil2_nh);
- const auto add_op_nh = cv::gimpl::GModel::producerOf(tgm, out_nh);
- EXPECT_EQ(matching_test::S({in1_nh, dil1_nh, er_nh, dil2_nh, out_nh,
- er_op_nh, dil_op_nh, add_op_nh}),
- nodes);
- EXPECT_EQ(cv::gapi::imgproc::GErode::id(), matching_test::opName(tgm, er_op_nh));
- EXPECT_EQ(cv::gapi::imgproc::GDilate::id(), matching_test::opName(tgm, dil_op_nh));
- EXPECT_EQ(cv::gapi::core::GAdd::id(), matching_test::opName(tgm, add_op_nh));
- EXPECT_EQ(1u, er_nh->outEdges().size());
- EXPECT_EQ(1u, dil2_nh->outEdges().size());
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, in1_nh, er_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, dil1_nh, dil_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, er_nh, add_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, dil2_nh, add_op_nh));
- EXPECT_EQ(matching_test::S({ er_op_nh, dil_op_nh }), match.startOps());
- EXPECT_EQ(matching_test::S{ add_op_nh }, match.finishOps());
- EXPECT_EQ(matching_test::V({ in1_nh, dil1_nh }), match.protoIns());
- EXPECT_EQ(matching_test::V{ out_nh }, match.protoOuts());
- }
- TEST(PatternMatching, TestInexactMatchOfInOutData)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat out = cv::gapi::dilate3x3(in);
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in;
- GMat out1 = cv::gapi::erode3x3(in);
- GMat out2 = cv::gapi::boxFilter(in, -1, cv::Size(3, 3));
- GMat tmp = cv::gapi::dilate3x3(in);
- GScalar out3 = cv::gapi::sum(tmp);
- GScalar out4 = cv::gapi::mean(tmp);
- matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out1, out2, out3, out4));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(3u, nodes.size());
- const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
- const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(tgm, tmp);
- const auto op_nh = cv::gimpl::GModel::producerOf(tgm, tmp_nh); // dilate3x3
- EXPECT_EQ(matching_test::S({in_nh, tmp_nh, op_nh}),
- nodes);
- EXPECT_EQ(cv::gapi::imgproc::GDilate::id(), matching_test::opName(tgm, op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, in_nh, op_nh));
- EXPECT_EQ(matching_test::S{ op_nh }, match.startOps());
- EXPECT_EQ(matching_test::S{ op_nh }, match.finishOps());
- EXPECT_EQ(matching_test::V{ in_nh }, match.protoIns());
- EXPECT_EQ(matching_test::V{ tmp_nh }, match.protoOuts());
- EXPECT_GT(in_nh->outEdges().size(), 1u);
- EXPECT_GT(tmp_nh->outEdges().size(), 1u);
- }
- //FIXME: The start ops matching shall be reworked to more smarter way.
- // Start ops matching shall get rid of non valid matchings sample,
- // where two identical start ops in the pattern refer to the only one in the test.
- TEST(PatternMatching, TestManySameStartOpsAndHinge)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in1, in2, in3;
- GMat er1 = cv::gapi::erode3x3(in1);
- GMat er2 = cv::gapi::erode3x3(in2);
- GMat er3 = cv::gapi::erode3x3(in3);
- GMat mrg = cv::gapi::merge3(er1, er2, er3);
- matching_test::initGModel(pg, cv::GIn(in1, in2, in3), cv::GOut(mrg));
- }
- // Test
- ade::Graph tg;
- GMat in1, in2, in3;
- GMat er1 = cv::gapi::erode3x3(in1);
- GMat er2 = cv::gapi::erode3x3(in2);
- GMat er3 = cv::gapi::erode3x3(in3);
- GMat mrg = cv::gapi::merge3(er1, er2, er3);
- matching_test::initGModel(tg, cv::GIn(in1, in2, in3), cv::GOut(mrg));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(11u, nodes.size());
- EXPECT_EQ(matching_test::S(tgm.nodes().begin(), tgm.nodes().end()),
- nodes);
- }
- //FIXME: The start ops matching shall be reworked to more smarter way.
- // Start ops matching shall get rid of non valid matchings sample,
- // where two identical start ops in the pattern refer to the only one in the test.
- TEST(PatternMatching, TestManySameStartOpsAndHinge2)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in1, in2, in3;
- GMat er1 = cv::gapi::erode3x3(in1);
- GMat er2 = cv::gapi::erode3x3(in2);
- GMat er3 = cv::gapi::erode3x3(in3);
- GMat dil1 = cv::gapi::dilate3x3(er1);
- GMat dil2 = cv::gapi::dilate3x3(er2);
- GMat dil3 = cv::gapi::dilate3x3(er3);
- GMat mrg = cv::gapi::merge3(dil1, dil2, dil3);
- matching_test::initGModel(pg, cv::GIn(in1, in2, in3), cv::GOut(mrg));
- }
- // Test
- ade::Graph tg;
- GMat in1, in2, in3;
- GMat er1 = cv::gapi::erode3x3(in1);
- GMat er2 = cv::gapi::erode3x3(in2);
- GMat er3 = cv::gapi::erode3x3(in3);
- GMat dil1 = cv::gapi::dilate3x3(er1);
- GMat dil2 = cv::gapi::dilate3x3(er2);
- GMat dil3 = cv::gapi::dilate3x3(er3);
- GMat mrg = cv::gapi::merge3(dil1, dil2, dil3);
- matching_test::initGModel(tg, cv::GIn(in1, in2, in3), cv::GOut(mrg));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(17u, nodes.size());
- EXPECT_EQ(matching_test::S(tgm.nodes().begin(), tgm.nodes().end()),
- nodes);
- }
- //FIXME: The start ops matching shall be reworked to more smarter way.
- // Start ops matching shall get rid of non valid matchings sample,
- // where two identical start ops in the pattern refer to the only one in the test.
- TEST(PatternMatching, TestTwoChainsOnTheHingeIsomorphism)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in1, in2;
- GMat er1 = cv::gapi::erode3x3(in1);
- GMat er2 = cv::gapi::erode3x3(in2);
- GMat mdb = cv::gapi::medianBlur(er1, 3);
- GMat gb = cv::gapi::gaussianBlur(er2, cv::Size(5, 5), 0.12);
- GMat conc = cv::gapi::concatVert(mdb, gb);
- matching_test::initGModel(pg, cv::GIn(in1, in2), cv::GOut(conc));
- }
- // Test
- ade::Graph tg;
- GMat in1, in2;
- GMat er1 = cv::gapi::erode3x3(in1);
- GMat er2 = cv::gapi::erode3x3(in2);
- GMat gb = cv::gapi::gaussianBlur(er1, cv::Size(5, 5), 0.12);
- GMat mdb = cv::gapi::medianBlur(er2, 3);
- GMat conc = cv::gapi::concatVert(mdb, gb);
- matching_test::initGModel(tg, cv::GIn(in1, in2), cv::GOut(conc));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(12u, nodes.size());
- EXPECT_EQ(matching_test::S(tgm.nodes().begin(), tgm.nodes().end()),
- nodes);
- const auto in1_nh = cv::gimpl::GModel::dataNodeOf(tgm, in1);
- const auto in2_nh = cv::gimpl::GModel::dataNodeOf(tgm, in2);
- EXPECT_EQ(matching_test::V({ in2_nh, in1_nh }), match.protoIns());
- }
- TEST(PatternMatching, TestPatternHasMoreInDataNodes)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in1, in2, in3;
- GMat out = cv::gapi::merge3(in1, in2, in3);
- matching_test::initGModel(pg, cv::GIn(in1, in2, in3), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in;
- GMat out = cv::gapi::merge3(in, in, in);
- matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(3u, nodes.size());
- EXPECT_EQ(matching_test::S(tgm.nodes().begin(), tgm.nodes().end()),
- nodes);
- const auto in_nh = cv::gimpl::GModel::dataNodeOf(tgm, in);
- EXPECT_EQ(matching_test::V({ in_nh, in_nh, in_nh }), match.protoIns());
- }
- TEST(PatternMatching, TestPatternHasFewerInDataNodes)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat out = cv::gapi::merge3(in, in, in);
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in1, in2, in3;
- GMat out = cv::gapi::merge3(in1, in2, in3);
- matching_test::initGModel(tg, cv::GIn(in1, in2, in3), cv::GOut(out));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_FALSE(match.ok());
- }
- TEST(PatternMatching, TestTwoMatchingsOneCorrect)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in1, in2;
- GMat n = cv::gapi::bitwise_not(in1);
- GMat e = cv::gapi::erode3x3(in1);
- GMat d = cv::gapi::dilate3x3(in2);
- GMat out = cv::gapi::merge3(n, e, d);
- matching_test::initGModel(pg, cv::GIn(in1, in2), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- GMat in1, in2;
- GMat n = cv::gapi::bitwise_not(in1);
- GMat e = cv::gapi::erode3x3(in2);
- GMat d = cv::gapi::dilate3x3(in2);
- GMat mrg = cv::gapi::merge3(n, e, d);
- GMat i, sqi;
- std::tie(i, sqi) = cv::gapi::integral(mrg);
- GMat n1 = cv::gapi::bitwise_not(i);
- GMat e1 = cv::gapi::erode3x3(i);
- GMat d1 = cv::gapi::dilate3x3(sqi);
- GMat out = cv::gapi::merge3(n1, e1, d1);
- matching_test::initGModel(tg, cv::GIn(in1, in2), cv::GOut(out));
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_TRUE(match.ok());
- auto nodes = match.nodes();
- EXPECT_EQ(10u, nodes.size());
- const auto i_nh = cv::gimpl::GModel::dataNodeOf(tgm, i);
- const auto sqi_nh = cv::gimpl::GModel::dataNodeOf(tgm, sqi);
- const auto n1_nh = cv::gimpl::GModel::dataNodeOf(tgm, n1);
- const auto e1_nh = cv::gimpl::GModel::dataNodeOf(tgm, e1);
- const auto d1_nh = cv::gimpl::GModel::dataNodeOf(tgm, d1);
- const auto out_nh = cv::gimpl::GModel::dataNodeOf(tgm, out);
- const auto n_op_nh = cv::gimpl::GModel::producerOf(tgm, n1_nh);
- const auto e_op_nh = cv::gimpl::GModel::producerOf(tgm, e1_nh);
- const auto d_op_nh = cv::gimpl::GModel::producerOf(tgm, d1_nh);
- const auto m_op_nh = cv::gimpl::GModel::producerOf(tgm, out_nh);
- EXPECT_EQ(matching_test::S({i_nh, sqi_nh, n1_nh, e1_nh, d1_nh, out_nh,
- n_op_nh, e_op_nh, d_op_nh, m_op_nh}), nodes);
- EXPECT_EQ(cv::gapi::core::GNot::id(), matching_test::opName(tgm, n_op_nh));
- EXPECT_EQ(cv::gapi::imgproc::GErode::id(), matching_test::opName(tgm, e_op_nh));
- EXPECT_EQ(cv::gapi::imgproc::GDilate::id(), matching_test::opName(tgm, d_op_nh));
- EXPECT_EQ(cv::gapi::core::GMerge3::id(), matching_test::opName(tgm, m_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, i_nh, n_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, i_nh, e_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, sqi_nh, d_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, n1_nh, m_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, e1_nh, m_op_nh));
- EXPECT_TRUE(matching_test::isConsumedBy(tgm, d1_nh, m_op_nh));
- EXPECT_EQ(1u, n1_nh->outEdges().size());
- EXPECT_EQ(1u, e1_nh->outEdges().size());
- EXPECT_EQ(1u, d1_nh->outEdges().size());
- EXPECT_EQ(matching_test::S({n_op_nh, e_op_nh, d_op_nh}), match.startOps());
- EXPECT_EQ(matching_test::S{m_op_nh}, match.finishOps());
- EXPECT_EQ(matching_test::V({i_nh, sqi_nh}), match.protoIns());
- EXPECT_EQ(matching_test::V{out_nh}, match.protoOuts());}
- TEST(PatternMatching, CheckNoMatch)
- {
- // Pattern
- ade::Graph pg;
- {
- GMat in;
- GMat tmp = cv::gapi::filter2D(in, -1, {});
- GMat out = cv::gapi::filter2D(tmp, -1, {});
- matching_test::initGModel(pg, cv::GIn(in), cv::GOut(out));
- }
- // Test
- ade::Graph tg;
- {
- GMat in;
- GMat tmp1 = cv::gapi::erode3x3(in);
- GMat out = cv::gapi::dilate3x3(tmp1);
- matching_test::initGModel(tg, cv::GIn(in), cv::GOut(out));
- }
- // Pattern Matching
- cv::gimpl::GModel::Graph pgm(pg);
- cv::gimpl::GModel::Graph tgm(tg);
- cv::gimpl::SubgraphMatch match = cv::gimpl::findMatches(pg, tg);
- // Inspecting results:
- EXPECT_FALSE(match.ok());
- }
- TEST(PatternMatching, adeSmokeTest)
- {
- ade::Graph g;
- ade::NodeHandle src = g.createNode();
- ade::NodeHandle dst = g.createNode();
- g.link(src, dst);
- g.link(src, dst);
- EXPECT_EQ(2u, dst->inNodes().size());
- }
- } // namespace opencv_test
|