Merge pull request #19310 from TolyaTalamanov:at/generic-infer-overloads

[G-API] Support generic infer overloads

* Overloads for generic infer

* Fix build

* Refactoring

* Fix docs

* Put extra stuff to detail namespace

* Add doc for usings

* Remove uneccessary template in Priv
pull/19879/head^2
Anatoliy Talamanov 4 years ago committed by GitHub
parent 3f52d0e46c
commit 50a264d832
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 346
      modules/gapi/include/opencv2/gapi/infer.hpp
  2. 13
      modules/gapi/include/opencv2/gapi/infer/ie.hpp
  3. 15
      modules/gapi/misc/python/shadow_gapi.hpp
  4. 65
      modules/gapi/src/api/ginfer.cpp
  5. 2
      modules/gapi/src/backends/ie/giebackend.cpp
  6. 352
      modules/gapi/test/infer/gapi_infer_ie_test.cpp

@ -2,7 +2,7 @@
// 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-2020 Intel Corporation
// Copyright (C) 2019-2021 Intel Corporation
#ifndef OPENCV_GAPI_INFER_HPP
@ -76,6 +76,112 @@ struct valid_infer2_types< std::tuple<cv::GMat,Ns...>, std::tuple<T,Ts...> > {
valid_infer2_types< std::tuple<cv::GMat>, std::tuple<T> >::value
&& valid_infer2_types< std::tuple<Ns...>, std::tuple<Ts...> >::value;
};
// Struct stores network input/output names.
// Used by infer<Generic>
struct InOutInfo
{
std::vector<std::string> in_names;
std::vector<std::string> out_names;
};
template <typename OutT>
class GInferOutputsTyped
{
public:
GInferOutputsTyped() = default;
GInferOutputsTyped(std::shared_ptr<cv::GCall> call)
: m_priv(std::make_shared<Priv>(std::move(call)))
{
}
OutT at(const std::string& name)
{
auto it = m_priv->blobs.find(name);
if (it == m_priv->blobs.end()) {
// FIXME: Avoid modifying GKernel
auto shape = cv::detail::GTypeTraits<OutT>::shape;
m_priv->call->kernel().outShapes.push_back(shape);
m_priv->call->kernel().outCtors.emplace_back(cv::detail::GObtainCtor<OutT>::get());
auto out_idx = static_cast<int>(m_priv->blobs.size());
it = m_priv->blobs.emplace(name,
cv::detail::Yield<OutT>::yield(*(m_priv->call), out_idx)).first;
m_priv->info->out_names.push_back(name);
}
return it->second;
}
private:
struct Priv
{
Priv(std::shared_ptr<cv::GCall> c)
: call(std::move(c)), info(cv::util::any_cast<InOutInfo>(&call->params()))
{
}
std::shared_ptr<cv::GCall> call;
InOutInfo* info = nullptr;
std::unordered_map<std::string, OutT> blobs;
};
std::shared_ptr<Priv> m_priv;
};
template <typename... Ts>
class GInferInputsTyped
{
public:
GInferInputsTyped()
: m_priv(std::make_shared<Priv>())
{
}
template <typename U>
void setInput(const std::string& name, U in)
{
m_priv->blobs.emplace(std::piecewise_construct,
std::forward_as_tuple(name),
std::forward_as_tuple(in));
}
using StorageT = cv::util::variant<Ts...>;
StorageT& operator[](const std::string& name) {
return m_priv->blobs[name];
}
using Map = std::unordered_map<std::string, StorageT>;
const Map& getBlobs() const {
return m_priv->blobs;
}
private:
struct Priv
{
std::unordered_map<std::string, StorageT> blobs;
};
std::shared_ptr<Priv> m_priv;
};
template<typename InferT>
std::shared_ptr<cv::GCall> makeCall(const std::string &tag,
std::vector<cv::GArg> &&args,
std::vector<std::string> &&names,
cv::GKinds &&kinds) {
auto call = std::make_shared<cv::GCall>(GKernel{
InferT::id(),
tag,
InferT::getOutMeta,
{}, // outShape will be filled later
std::move(kinds),
{}, // outCtors will be filled later
});
call->setArgs(std::move(args));
call->params() = cv::detail::InOutInfo{std::move(names), {}};
return call;
}
} // namespace detail
// TODO: maybe tuple_wrap_helper from util.hpp may help with this.
@ -166,49 +272,6 @@ struct GInferBase {
}
};
// Struct stores network input/output names.
// Used by infer<Generic>
struct InOutInfo
{
std::vector<std::string> in_names;
std::vector<std::string> out_names;
};
/**
* @{
* @brief G-API object used to collect network inputs
*/
class GAPI_EXPORTS_W_SIMPLE GInferInputs
{
using Map = std::unordered_map<std::string, GMat>;
public:
GAPI_WRAP GInferInputs();
GAPI_WRAP void setInput(const std::string& name, const cv::GMat& value);
cv::GMat& operator[](const std::string& name);
const Map& getBlobs() const;
private:
std::shared_ptr<Map> in_blobs;
};
/** @} */
/**
* @{
* @brief G-API object used to collect network outputs
*/
struct GAPI_EXPORTS_W_SIMPLE GInferOutputs
{
public:
GAPI_WRAP GInferOutputs() = default;
GInferOutputs(std::shared_ptr<cv::GCall> call);
GAPI_WRAP cv::GMat at(const std::string& name);
private:
struct Priv;
std::shared_ptr<Priv> m_priv;
};
/** @} */
// Base "InferROI" kernel.
// All notes from "Infer" kernel apply here as well.
struct GInferROIBase {
@ -295,6 +358,90 @@ struct GInferList2 final
static constexpr const char* tag() { return Net::tag(); }
};
/**
* @brief G-API object used to collect network inputs
*/
using GInferInputs = cv::detail::GInferInputsTyped<cv::GMat, cv::GFrame>;
/**
* @brief G-API object used to collect the list of network inputs
*/
using GInferListInputs = cv::detail::GInferInputsTyped<cv::GArray<cv::GMat>, cv::GArray<cv::Rect>>;
/**
* @brief G-API object used to collect network outputs
*/
using GInferOutputs = cv::detail::GInferOutputsTyped<cv::GMat>;
/**
* @brief G-API object used to collect the list of network outputs
*/
using GInferListOutputs = cv::detail::GInferOutputsTyped<cv::GArray<cv::GMat>>;
namespace detail {
void inline unpackBlobs(const cv::GInferInputs::Map& blobs,
std::vector<cv::GArg>& args,
std::vector<std::string>& names,
cv::GKinds& kinds)
{
for (auto&& p : blobs) {
names.emplace_back(p.first);
switch (p.second.index()) {
case cv::GInferInputs::StorageT::index_of<cv::GMat>():
args.emplace_back(cv::util::get<cv::GMat>(p.second));
kinds.emplace_back(cv::detail::OpaqueKind::CV_MAT);
break;
case cv::GInferInputs::StorageT::index_of<cv::GFrame>():
args.emplace_back(cv::util::get<cv::GFrame>(p.second));
kinds.emplace_back(cv::detail::OpaqueKind::CV_UNKNOWN);
break;
default:
GAPI_Assert(false);
}
}
}
template <typename InferType>
struct InferROITraits;
template <>
struct InferROITraits<GInferROIBase>
{
using outType = cv::GInferOutputs;
using inType = cv::GOpaque<cv::Rect>;
};
template <>
struct InferROITraits<GInferListBase>
{
using outType = cv::GInferListOutputs;
using inType = cv::GArray<cv::Rect>;
};
template<typename InferType>
typename InferROITraits<InferType>::outType
inferGenericROI(const std::string& tag,
const typename InferROITraits<InferType>::inType& in,
const cv::GInferInputs& inputs)
{
std::vector<cv::GArg> args;
std::vector<std::string> names;
cv::GKinds kinds;
args.emplace_back(in);
kinds.emplace_back(cv::detail::OpaqueKind::CV_RECT);
unpackBlobs(inputs.getBlobs(), args, names, kinds);
auto call = cv::detail::makeCall<InferType>(tag,
std::move(args),
std::move(names),
std::move(kinds));
return {std::move(call)};
}
} // namespace detail
} // namespace cv
// FIXME: Probably the <API> signature makes a function/tuple/function round-trip
@ -395,36 +542,101 @@ struct Generic { };
* @param inputs networks's inputs
* @return a GInferOutputs
*/
template<typename T = Generic> GInferOutputs
infer(const std::string& tag, const GInferInputs& inputs)
template<typename T = Generic> cv::GInferOutputs
infer(const std::string& tag, const cv::GInferInputs& inputs)
{
std::vector<GArg> input_args;
std::vector<std::string> input_names;
std::vector<cv::GArg> args;
std::vector<std::string> names;
cv::GKinds kinds;
const auto& blobs = inputs.getBlobs();
for (auto&& p : blobs)
{
input_names.push_back(p.first);
input_args.emplace_back(p.second);
}
cv::detail::unpackBlobs(inputs.getBlobs(), args, names, kinds);
GKinds kinds(blobs.size(), cv::detail::OpaqueKind::CV_MAT);
auto call = std::make_shared<cv::GCall>(GKernel{
GInferBase::id(),
tag,
GInferBase::getOutMeta,
{}, // outShape will be filled later
std::move(kinds),
{}, // outCtors will be filled later
});
auto call = cv::detail::makeCall<GInferBase>(tag,
std::move(args),
std::move(names),
std::move(kinds));
return cv::GInferOutputs{std::move(call)};
}
/** @brief Calculates response for the generic network
* for the specified region in the source image.
* Currently expects a single-input network only.
*
* @param tag a network tag
* @param roi a an object describing the region of interest
* in the source image. May be calculated in the same graph dynamically.
* @param inputs networks's inputs
* @return a cv::GInferOutputs
*/
template<typename T = Generic> cv::GInferOutputs
infer(const std::string& tag, const cv::GOpaque<cv::Rect>& roi, const cv::GInferInputs& inputs)
{
return cv::detail::inferGenericROI<GInferROIBase>(tag, roi, inputs);
}
/** @brief Calculates responses for the specified network
* for every region in the source image.
*
* @param tag a network tag
* @param rois a list of rectangles describing regions of interest
* in the source image. Usually an output of object detector or tracker.
* @param inputs networks's inputs
* @return a cv::GInferListOutputs
*/
template<typename T = Generic> cv::GInferListOutputs
infer(const std::string& tag, const cv::GArray<cv::Rect>& rois, const cv::GInferInputs& inputs)
{
return cv::detail::inferGenericROI<GInferListBase>(tag, rois, inputs);
}
/** @brief Calculates responses for the specified network
* for every region in the source image, extended version.
*
* @param tag a network tag
* @param in a source image containing regions of interest.
* @param inputs networks's inputs
* @return a cv::GInferListOutputs
*/
template<typename T = Generic, typename Input>
typename std::enable_if<cv::detail::accepted_infer_types<Input>::value, cv::GInferListOutputs>::type
infer2(const std::string& tag,
const Input& in,
const cv::GInferListInputs& inputs)
{
std::vector<cv::GArg> args;
std::vector<std::string> names;
cv::GKinds kinds;
args.emplace_back(in);
auto k = cv::detail::GOpaqueTraits<Input>::kind;
kinds.emplace_back(k);
for (auto&& p : inputs.getBlobs()) {
names.emplace_back(p.first);
switch (p.second.index()) {
case cv::GInferListInputs::StorageT::index_of<cv::GArray<cv::GMat>>():
args.emplace_back(cv::util::get<cv::GArray<cv::GMat>>(p.second));
kinds.emplace_back(cv::detail::OpaqueKind::CV_MAT);
break;
case cv::GInferListInputs::StorageT::index_of<cv::GArray<cv::Rect>>():
args.emplace_back(cv::util::get<cv::GArray<cv::Rect>>(p.second));
kinds.emplace_back(cv::detail::OpaqueKind::CV_RECT);
break;
default:
GAPI_Assert(false);
}
}
call->setArgs(std::move(input_args));
call->params() = InOutInfo{input_names, {}};
auto call = cv::detail::makeCall<GInferList2Base>(tag,
std::move(args),
std::move(names),
std::move(kinds));
return GInferOutputs{std::move(call)};
return cv::GInferListOutputs{std::move(call)};
}
GAPI_EXPORTS_W inline GInferOutputs infer(const String& name, const GInferInputs& inputs)
GAPI_EXPORTS_W inline cv::GInferOutputs infer(const String& name, const cv::GInferInputs& inputs)
{
return infer<Generic>(name, inputs);
}

@ -222,6 +222,19 @@ public:
return *this;
}
Params& constInput(const std::string &layer_name,
const cv::Mat &data,
TraitAs hint = TraitAs::TENSOR) {
desc.const_inputs[layer_name] = {data, hint};
return *this;
}
Params& cfgNumRequests(size_t nireq) {
GAPI_Assert(nireq > 0 && "Number of infer requests must be greater than zero!");
desc.nireq = nireq;
return *this;
}
// BEGIN(G-API's network parametrization API)
GBackend backend() const { return cv::gapi::ie::backend(); }
std::string tag() const { return m_tag; }

@ -19,6 +19,21 @@ namespace cv
using GProtoInputArgs = GIOProtoArgs<In_Tag>;
using GProtoOutputArgs = GIOProtoArgs<Out_Tag>;
class GAPI_EXPORTS_W_SIMPLE GInferInputs
{
public:
GAPI_WRAP GInferInputs();
GAPI_WRAP void setInput(const std::string& name, const cv::GMat& value);
GAPI_WRAP void setInput(const std::string& name, const cv::GFrame& value);
};
class GAPI_EXPORTS_W_SIMPLE GInferOutputs
{
public:
GAPI_WRAP GInferOutputs();
GAPI_WRAP cv::GMat at(const std::string& name);
};
namespace detail
{
struct GAPI_EXPORTS_W_SIMPLE ExtractArgsCallback { };

@ -7,15 +7,10 @@
#include "precomp.hpp"
#include <functional> // hash
#include <numeric> // accumulate
#include <unordered_set>
#include <iterator>
#include <ade/util/algorithm.hpp>
#include <opencv2/gapi/infer.hpp>
#include <unordered_set>
cv::gapi::GNetPackage::GNetPackage(std::initializer_list<GNetParam> ii)
: networks(ii) {
}
@ -25,59 +20,3 @@ std::vector<cv::gapi::GBackend> cv::gapi::GNetPackage::backends() const {
for (const auto &nn : networks) unique_set.insert(nn.backend);
return std::vector<cv::gapi::GBackend>(unique_set.begin(), unique_set.end());
}
// FIXME: Inference API is currently only available in full mode
#if !defined(GAPI_STANDALONE)
cv::GInferInputs::GInferInputs()
: in_blobs(std::make_shared<Map>())
{
}
cv::GMat& cv::GInferInputs::operator[](const std::string& name) {
return (*in_blobs)[name];
}
const cv::GInferInputs::Map& cv::GInferInputs::getBlobs() const {
return *in_blobs;
}
void cv::GInferInputs::setInput(const std::string& name, const cv::GMat& value) {
in_blobs->emplace(name, value);
}
struct cv::GInferOutputs::Priv
{
Priv(std::shared_ptr<cv::GCall>);
std::shared_ptr<cv::GCall> call;
InOutInfo* info = nullptr;
std::unordered_map<std::string, cv::GMat> out_blobs;
};
cv::GInferOutputs::Priv::Priv(std::shared_ptr<cv::GCall> c)
: call(std::move(c)), info(cv::util::any_cast<InOutInfo>(&call->params()))
{
}
cv::GInferOutputs::GInferOutputs(std::shared_ptr<cv::GCall> call)
: m_priv(std::make_shared<cv::GInferOutputs::Priv>(std::move(call)))
{
}
cv::GMat cv::GInferOutputs::at(const std::string& name)
{
auto it = m_priv->out_blobs.find(name);
if (it == m_priv->out_blobs.end()) {
// FIXME: Avoid modifying GKernel
// Expect output to be always GMat
m_priv->call->kernel().outShapes.push_back(cv::GShape::GMAT);
// ...so _empty_ constructor is passed here.
m_priv->call->kernel().outCtors.emplace_back(cv::util::monostate{});
int out_idx = static_cast<int>(m_priv->out_blobs.size());
it = m_priv->out_blobs.emplace(name, m_priv->call->yield(out_idx)).first;
m_priv->info->out_names.push_back(name);
}
return it->second;
}
#endif // GAPI_STANDALONE

@ -1242,7 +1242,7 @@ namespace {
// NB: In case generic infer, info about in/out names is stored in operation (op.params)
if (pp.is_generic)
{
auto& info = cv::util::any_cast<cv::InOutInfo>(op.params);
auto& info = cv::util::any_cast<cv::detail::InOutInfo>(op.params);
pp.input_names = info.in_names;
pp.output_names = info.out_names;
pp.num_in = info.in_names.size();

@ -489,6 +489,126 @@ struct ROIListNV12: public ::testing::Test {
}
};
struct SingleROI: public ::testing::Test {
cv::gapi::ie::detail::ParamDesc params;
cv::Mat m_in_mat;
cv::Rect m_roi;
cv::Mat m_out_gapi_age;
cv::Mat m_out_gapi_gender;
cv::Mat m_out_ie_age;
cv::Mat m_out_ie_gender;
void SetUp() {
initDLDTDataPath();
params.model_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.xml");
params.weights_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.bin");
params.device_id = "CPU";
// FIXME: it must be cv::imread(findDataFile("../dnn/grace_hopper_227.png", false));
m_in_mat = cv::Mat(cv::Size(320, 240), CV_8UC3);
cv::randu(m_in_mat, 0, 255);
m_roi = cv::Rect(cv::Point{64, 60}, cv::Size{96, 96});
// Load & run IE network
IE::Blob::Ptr ie_age, ie_gender;
{
auto plugin = cv::gimpl::ie::wrap::getPlugin(params);
auto net = cv::gimpl::ie::wrap::readNetwork(params);
setNetParameters(net);
auto this_network = cv::gimpl::ie::wrap::loadNetwork(plugin, net, params);
auto infer_request = this_network.CreateInferRequest();
const auto ie_rc = IE::ROI {
0u
, static_cast<std::size_t>(m_roi.x)
, static_cast<std::size_t>(m_roi.y)
, static_cast<std::size_t>(m_roi.width)
, static_cast<std::size_t>(m_roi.height)
};
IE::Blob::Ptr roi_blob = IE::make_shared_blob(cv::gapi::ie::util::to_ie(m_in_mat), ie_rc);
infer_request.SetBlob("data", roi_blob);
infer_request.Infer();
using namespace cv::gapi::ie::util;
m_out_ie_age = to_ocv(infer_request.GetBlob("age_conv3")).clone();
m_out_ie_gender = to_ocv(infer_request.GetBlob("prob")).clone();
}
}
void validate() {
// Validate with IE itself (avoid DNN module dependency here)
normAssert(m_out_ie_age , m_out_gapi_age , "Test age output");
normAssert(m_out_ie_gender, m_out_gapi_gender, "Test gender output");
}
};
struct SingleROINV12: public ::testing::Test {
cv::gapi::ie::detail::ParamDesc params;
cv::Mat m_in_y;
cv::Mat m_in_uv;
cv::Rect m_roi;
cv::Mat m_out_gapi_age;
cv::Mat m_out_gapi_gender;
cv::Mat m_out_ie_age;
cv::Mat m_out_ie_gender;
void SetUp() {
initDLDTDataPath();
params.model_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.xml");
params.weights_path = findDataFile(SUBDIR + "age-gender-recognition-retail-0013.bin");
params.device_id = "CPU";
cv::Size sz{320, 240};
m_in_y = cv::Mat{sz, CV_8UC1};
cv::randu(m_in_y, 0, 255);
m_in_uv = cv::Mat{sz / 2, CV_8UC2};
cv::randu(m_in_uv, 0, 255);
m_roi = cv::Rect(cv::Point{64, 60}, cv::Size{96, 96});
// Load & run IE network
IE::Blob::Ptr ie_age, ie_gender;
{
auto plugin = cv::gimpl::ie::wrap::getPlugin(params);
auto net = cv::gimpl::ie::wrap::readNetwork(params);
setNetParameters(net, /* NV12 */ true);
auto this_network = cv::gimpl::ie::wrap::loadNetwork(plugin, net, params);
auto infer_request = this_network.CreateInferRequest();
auto blob = cv::gapi::ie::util::to_ie(m_in_y, m_in_uv);
const auto ie_rc = IE::ROI {
0u
, static_cast<std::size_t>(m_roi.x)
, static_cast<std::size_t>(m_roi.y)
, static_cast<std::size_t>(m_roi.width)
, static_cast<std::size_t>(m_roi.height)
};
IE::Blob::Ptr roi_blob = IE::make_shared_blob(blob, ie_rc);
infer_request.SetBlob("data", roi_blob);
infer_request.Infer();
using namespace cv::gapi::ie::util;
m_out_ie_age = to_ocv(infer_request.GetBlob("age_conv3")).clone();
m_out_ie_gender = to_ocv(infer_request.GetBlob("prob")).clone();
}
}
void validate() {
// Validate with IE itself (avoid DNN module dependency here)
normAssert(m_out_ie_age , m_out_gapi_age , "Test age output");
normAssert(m_out_ie_gender, m_out_gapi_gender, "Test gender output");
}
};
TEST_F(ROIList, TestInfer)
{
cv::GArray<cv::Rect> rr;
@ -501,8 +621,8 @@ TEST_F(ROIList, TestInfer)
params.model_path, params.weights_path, params.device_id
}.cfgOutputLayers({ "age_conv3", "prob" });
comp.apply(cv::gin(m_in_mat, m_roi_list),
cv::gout(m_out_gapi_ages, m_out_gapi_genders),
cv::compile_args(cv::gapi::networks(pp)));
cv::gout(m_out_gapi_ages, m_out_gapi_genders),
cv::compile_args(cv::gapi::networks(pp)));
validate();
}
@ -1062,6 +1182,234 @@ TEST_F(ROIListNV12, Infer2MediaInputNV12)
validate();
}
TEST_F(SingleROI, GenericInfer)
{
// Configure & run G-API
cv::GMat in;
cv::GOpaque<cv::Rect> roi;
cv::GInferInputs inputs;
inputs["data"] = in;
auto outputs = cv::gapi::infer<cv::gapi::Generic>("age-gender-generic", roi, inputs);
auto age = outputs.at("age_conv3");
auto gender = outputs.at("prob");
cv::GComputation comp(cv::GIn(in, roi), cv::GOut(age, gender));
cv::gapi::ie::Params<cv::gapi::Generic> pp{
"age-gender-generic", params.model_path, params.weights_path, params.device_id
};
pp.cfgNumRequests(2u);
comp.apply(cv::gin(m_in_mat, m_roi), cv::gout(m_out_gapi_age, m_out_gapi_gender),
cv::compile_args(cv::gapi::networks(pp)));
validate();
}
TEST_F(SingleROI, GenericInferMediaBGR)
{
// Configure & run G-API
cv::GFrame in;
cv::GOpaque<cv::Rect> roi;
cv::GInferInputs inputs;
inputs["data"] = in;
auto outputs = cv::gapi::infer<cv::gapi::Generic>("age-gender-generic", roi, inputs);
auto age = outputs.at("age_conv3");
auto gender = outputs.at("prob");
cv::GComputation comp(cv::GIn(in, roi), cv::GOut(age, gender));
cv::gapi::ie::Params<cv::gapi::Generic> pp{
"age-gender-generic", params.model_path, params.weights_path, params.device_id
};
pp.cfgNumRequests(2u);
auto frame = MediaFrame::Create<TestMediaBGR>(m_in_mat);
comp.apply(cv::gin(frame, m_roi), cv::gout(m_out_gapi_age, m_out_gapi_gender),
cv::compile_args(cv::gapi::networks(pp)));
validate();
}
TEST_F(SingleROINV12, GenericInferMediaNV12)
{
// Configure & run G-API
cv::GFrame in;
cv::GOpaque<cv::Rect> roi;
cv::GInferInputs inputs;
inputs["data"] = in;
auto outputs = cv::gapi::infer<cv::gapi::Generic>("age-gender-generic", roi, inputs);
auto age = outputs.at("age_conv3");
auto gender = outputs.at("prob");
cv::GComputation comp(cv::GIn(in, roi), cv::GOut(age, gender));
cv::gapi::ie::Params<cv::gapi::Generic> pp{
"age-gender-generic", params.model_path, params.weights_path, params.device_id
};
pp.cfgNumRequests(2u);
auto frame = MediaFrame::Create<TestMediaNV12>(m_in_y, m_in_uv);
comp.apply(cv::gin(frame, m_roi), cv::gout(m_out_gapi_age, m_out_gapi_gender),
cv::compile_args(cv::gapi::networks(pp)));
validate();
}
TEST_F(ROIList, GenericInfer)
{
cv::GMat in;
cv::GArray<cv::Rect> rr;
cv::GInferInputs inputs;
inputs["data"] = in;
auto outputs = cv::gapi::infer<cv::gapi::Generic>("age-gender-generic", rr, inputs);
auto age = outputs.at("age_conv3");
auto gender = outputs.at("prob");
cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
cv::gapi::ie::Params<cv::gapi::Generic> pp{
"age-gender-generic", params.model_path, params.weights_path, params.device_id
};
pp.cfgNumRequests(2u);
comp.apply(cv::gin(m_in_mat, m_roi_list),
cv::gout(m_out_gapi_ages, m_out_gapi_genders),
cv::compile_args(cv::gapi::networks(pp)));
validate();
}
TEST_F(ROIList, GenericInferMediaBGR)
{
cv::GFrame in;
cv::GArray<cv::Rect> rr;
cv::GInferInputs inputs;
inputs["data"] = in;
auto outputs = cv::gapi::infer<cv::gapi::Generic>("age-gender-generic", rr, inputs);
auto age = outputs.at("age_conv3");
auto gender = outputs.at("prob");
cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
cv::gapi::ie::Params<cv::gapi::Generic> pp{
"age-gender-generic", params.model_path, params.weights_path, params.device_id
};
pp.cfgNumRequests(2u);
auto frame = MediaFrame::Create<TestMediaBGR>(m_in_mat);
comp.apply(cv::gin(frame, m_roi_list),
cv::gout(m_out_gapi_ages, m_out_gapi_genders),
cv::compile_args(cv::gapi::networks(pp)));
validate();
}
TEST_F(ROIListNV12, GenericInferMediaNV12)
{
cv::GFrame in;
cv::GArray<cv::Rect> rr;
cv::GInferInputs inputs;
inputs["data"] = in;
auto outputs = cv::gapi::infer<cv::gapi::Generic>("age-gender-generic", rr, inputs);
auto age = outputs.at("age_conv3");
auto gender = outputs.at("prob");
cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
cv::gapi::ie::Params<cv::gapi::Generic> pp{
"age-gender-generic", params.model_path, params.weights_path, params.device_id
};
pp.cfgNumRequests(2u);
auto frame = MediaFrame::Create<TestMediaNV12>(m_in_y, m_in_uv);
comp.apply(cv::gin(frame, m_roi_list),
cv::gout(m_out_gapi_ages, m_out_gapi_genders),
cv::compile_args(cv::gapi::networks(pp)));
validate();
}
TEST_F(ROIList, GenericInfer2)
{
cv::GArray<cv::Rect> rr;
cv::GMat in;
GInferListInputs list;
list["data"] = rr;
auto outputs = cv::gapi::infer2<cv::gapi::Generic>("age-gender-generic", in, list);
auto age = outputs.at("age_conv3");
auto gender = outputs.at("prob");
cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
cv::gapi::ie::Params<cv::gapi::Generic> pp{
"age-gender-generic", params.model_path, params.weights_path, params.device_id
};
pp.cfgNumRequests(2u);
comp.apply(cv::gin(m_in_mat, m_roi_list),
cv::gout(m_out_gapi_ages, m_out_gapi_genders),
cv::compile_args(cv::gapi::networks(pp)));
validate();
}
TEST_F(ROIList, GenericInfer2MediaInputBGR)
{
cv::GArray<cv::Rect> rr;
cv::GFrame in;
GInferListInputs inputs;
inputs["data"] = rr;
auto outputs = cv::gapi::infer2<cv::gapi::Generic>("age-gender-generic", in, inputs);
auto age = outputs.at("age_conv3");
auto gender = outputs.at("prob");
cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
cv::gapi::ie::Params<cv::gapi::Generic> pp{
"age-gender-generic", params.model_path, params.weights_path, params.device_id
};
pp.cfgNumRequests(2u);
auto frame = MediaFrame::Create<TestMediaBGR>(m_in_mat);
comp.apply(cv::gin(frame, m_roi_list),
cv::gout(m_out_gapi_ages, m_out_gapi_genders),
cv::compile_args(cv::gapi::networks(pp)));
validate();
}
TEST_F(ROIListNV12, GenericInfer2MediaInputNV12)
{
cv::GArray<cv::Rect> rr;
cv::GFrame in;
GInferListInputs inputs;
inputs["data"] = rr;
auto outputs = cv::gapi::infer2<cv::gapi::Generic>("age-gender-generic", in, inputs);
auto age = outputs.at("age_conv3");
auto gender = outputs.at("prob");
cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
cv::gapi::ie::Params<cv::gapi::Generic> pp{
"age-gender-generic", params.model_path, params.weights_path, params.device_id
};
pp.cfgNumRequests(2u);
auto frame = MediaFrame::Create<TestMediaNV12>(m_in_y, m_in_uv);
comp.apply(cv::gin(frame, m_roi_list),
cv::gout(m_out_gapi_ages, m_out_gapi_genders),
cv::compile_args(cv::gapi::networks(pp)));
validate();
}
TEST(Infer, SetInvalidNumberOfRequests)
{
using AGInfo = std::tuple<cv::GMat, cv::GMat>;

Loading…
Cancel
Save