1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

Merge pull request #18762 from TolyaTalamanov:at/support-garray

[G-API] Wrap GArray

* Wrap GArray for output

* Collect in/out info in graph

* Add imgproc tests

* Add cv::Point2f

* Update test_gapi_imgproc.py

* Fix comments to review
This commit is contained in:
Anatoliy Talamanov
2020-11-27 20:39:46 +03:00
committed by GitHub
parent 2155296a13
commit 7521f207b1
20 changed files with 400 additions and 104 deletions
@@ -38,6 +38,10 @@ class GAPI_EXPORTS GCompiled::Priv
GMetaArgs m_outMetas; // inferred by compiler
std::unique_ptr<cv::gimpl::GExecutor> m_exec;
// NB: Used by python wrapper to clarify input/output types
GTypesInfo m_out_info;
GTypesInfo m_in_info;
void checkArgs(const cv::gimpl::GRuntimeArgs &args) const;
public:
@@ -55,6 +59,12 @@ public:
const GMetaArgs& outMetas() const;
const cv::gimpl::GModel::Graph& model() const;
void setOutInfo(const GTypesInfo& info) { m_out_info = std::move(info); }
const GTypesInfo& outInfo() const { return m_out_info; }
void setInInfo(const GTypesInfo& info) { m_in_info = std::move(info); }
const GTypesInfo& inInfo() const { return m_in_info; }
};
}
+32 -7
View File
@@ -417,6 +417,19 @@ void cv::gimpl::GCompiler::compileIslands(ade::Graph &g, const cv::GCompileArgs
GIslandModel::compileIslands(gim, g, args);
}
static cv::GTypesInfo collectInfo(const cv::gimpl::GModel::ConstGraph& g,
const std::vector<ade::NodeHandle>& nhs) {
cv::GTypesInfo info;
info.reserve(nhs.size());
ade::util::transform(nhs, std::back_inserter(info), [&g](const ade::NodeHandle& nh) {
const auto& data = g.metadata(nh).get<cv::gimpl::Data>();
return cv::GTypeInfo{data.shape, data.kind};
});
return info;
}
cv::GCompiled cv::gimpl::GCompiler::produceCompiled(GPtr &&pg)
{
// This is the final compilation step. Here:
@@ -435,6 +448,8 @@ cv::GCompiled cv::gimpl::GCompiler::produceCompiled(GPtr &&pg)
// an execution plan for it (backend-specific execution)
// ...before call to produceCompiled();
GModel::ConstGraph cgr(*pg);
const auto &outMetas = GModel::ConstGraph(*pg).metadata()
.get<OutputMeta>().outMeta;
std::unique_ptr<GExecutor> pE(new GExecutor(std::move(pg)));
@@ -443,6 +458,14 @@ cv::GCompiled cv::gimpl::GCompiler::produceCompiled(GPtr &&pg)
GCompiled compiled;
compiled.priv().setup(m_metas, outMetas, std::move(pE));
// NB: Need to store input/output GTypeInfo to allocate output arrays for python bindings
auto out_meta = collectInfo(cgr, cgr.metadata().get<cv::gimpl::Protocol>().out_nhs);
auto in_meta = collectInfo(cgr, cgr.metadata().get<cv::gimpl::Protocol>().in_nhs);
compiled.priv().setOutInfo(std::move(out_meta));
compiled.priv().setInInfo(std::move(in_meta));
return compiled;
}
@@ -458,13 +481,15 @@ cv::GStreamingCompiled cv::gimpl::GCompiler::produceStreamingCompiled(GPtr &&pg)
outMetas = GModel::ConstGraph(*pg).metadata().get<OutputMeta>().outMeta;
}
auto out_desc = GModel::ConstGraph(*pg).metadata().get<cv::gimpl::Protocol>().outputs;
GShapes out_shapes;
for (auto&& desc : out_desc)
{
out_shapes.push_back(desc.shape);
}
compiled.priv().setOutShapes(std::move(out_shapes));
GModel::ConstGraph cgr(*pg);
// NB: Need to store input/output GTypeInfo to allocate output arrays for python bindings
auto out_meta = collectInfo(cgr, cgr.metadata().get<cv::gimpl::Protocol>().out_nhs);
auto in_meta = collectInfo(cgr, cgr.metadata().get<cv::gimpl::Protocol>().in_nhs);
compiled.priv().setOutInfo(std::move(out_meta));
compiled.priv().setInInfo(std::move(in_meta));
std::unique_ptr<GStreamingExecutor> pE(new GStreamingExecutor(std::move(pg),
m_args));
+19 -5
View File
@@ -8,6 +8,7 @@
#include "precomp.hpp"
#include <ade/graph.hpp>
#include <ade/util/zip_range.hpp> // util::indexed
#include <opencv2/gapi/gproto.hpp> // can_describe
#include <opencv2/gapi/gcompiled.hpp>
@@ -121,13 +122,13 @@ std::tuple<bool, cv::GRunArgs> cv::GStreamingCompiled::pull()
// FIXME: Why it is not @ priv??
GRunArgs run_args;
GRunArgsP outs;
const auto& out_shapes = m_priv->outShapes();
run_args.reserve(out_shapes.size());
outs.reserve(out_shapes.size());
const auto& out_info = m_priv->outInfo();
run_args.reserve(out_info.size());
outs.reserve(out_info.size());
for (auto&& shape : out_shapes)
for (auto&& info : out_info)
{
switch (shape)
switch (info.shape)
{
case cv::GShape::GMAT:
{
@@ -141,6 +142,19 @@ std::tuple<bool, cv::GRunArgs> cv::GStreamingCompiled::pull()
outs.emplace_back(&cv::util::get<cv::Scalar>(run_args.back()));
break;
}
case cv::GShape::GARRAY:
{
switch (info.kind)
{
case cv::detail::OpaqueKind::CV_POINT2F:
run_args.emplace_back(cv::detail::VectorRef{std::vector<cv::Point2f>{}});
outs.emplace_back(cv::util::get<cv::detail::VectorRef>(run_args.back()));
break;
default:
util::throw_error(std::logic_error("Unsupported kind for GArray"));
}
break;
}
default:
util::throw_error(std::logic_error("Only cv::GMat and cv::GScalar are supported for python output"));
}
@@ -27,7 +27,10 @@ class GAPI_EXPORTS GStreamingCompiled::Priv
GMetaArgs m_metas; // passed by user
GMetaArgs m_outMetas; // inferred by compiler
std::unique_ptr<cv::gimpl::GStreamingExecutor> m_exec;
GShapes m_out_shapes;
// NB: Used by python wrapper to clarify input/output types
GTypesInfo m_out_info;
GTypesInfo m_in_info;
public:
void setup(const GMetaArgs &metaArgs,
@@ -48,10 +51,11 @@ public:
bool running() const;
// NB: std::tuple<bool, cv::GRunArgs> pull() creates GRunArgs for outputs,
// so need to know out shapes to create corresponding GRunArg
void setOutShapes(GShapes shapes) { m_out_shapes = std::move(shapes); }
const GShapes& outShapes() const { return m_out_shapes; }
void setOutInfo(const GTypesInfo& info) { m_out_info = std::move(info); }
const GTypesInfo& outInfo() const { return m_out_info; }
void setInInfo(const GTypesInfo& info) { m_in_info = std::move(info); }
const GTypesInfo& inInfo() const { return m_in_info; }
};
} // namespace cv