mirror of
https://gitcode.com/gh_mirrors/es/esp32-opencv.git
synced 2025-08-15 19:30:59 +08:00
998 lines
34 KiB
C++
998 lines
34 KiB
C++
// 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::core::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::core::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
|