Merge pull request #20918 from TolyaTalamanov:at/fix-empty-map-importNetwork
[G-API] Fix bugs in GIEBackend * Remove inputs/outputs map from IEUnit * Add test * Add NV12 test * Reorganize setBlob function * Check that backend don't overwrite blob precision * Stop setting config to global IE::Core * Replace mutable to const_cast * Update modules/gapi/test/infer/gapi_infer_ie_test.cpp * Update modules/gapi/test/infer/gapi_infer_ie_test.cpp * Make blob parameter as const ref * Cosmetic fixes * Fix failed test on inferROI * Removed double ref for ii * Disable tests * Skip tests if device not available * Use Sync prim under shared_ptr to avoid issue on MAC * Apply WA for IE::Core * Apply WA for MAC build * Try to apply another WA * Not release IE::Core for apple * Put comment * Support PreprocInfo for * InferROI * InferList * InferList2 * Remove empty line * Fix alignment Co-authored-by: Maxim Pashchenkov <maxim.pashchenkov@intel.com>
This commit is contained in:
parent
394e640909
commit
2b2e515a30
@ -218,14 +218,18 @@ struct IEUnit {
|
||||
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
IE::CNNNetwork net;
|
||||
IE::InputsDataMap inputs;
|
||||
IE::OutputsDataMap outputs;
|
||||
|
||||
IE::ExecutableNetwork this_network;
|
||||
cv::gimpl::ie::wrap::Plugin this_plugin;
|
||||
|
||||
InferenceEngine::RemoteContext::Ptr rctx = nullptr;
|
||||
|
||||
// FIXME: Unlike loadNetwork case, importNetwork requires that preprocessing
|
||||
// should be passed as ExecutableNetwork::SetBlob method, so need to collect
|
||||
// and store this information at the graph compilation stage (outMeta) and use in runtime.
|
||||
using PreProcMap = std::unordered_map<std::string, IE::PreProcessInfo>;
|
||||
PreProcMap preproc_map;
|
||||
|
||||
explicit IEUnit(const cv::gapi::ie::detail::ParamDesc &pp)
|
||||
: params(pp) {
|
||||
InferenceEngine::ParamMap* ctx_params =
|
||||
@ -238,11 +242,8 @@ struct IEUnit {
|
||||
if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
|
||||
net = cv::gimpl::ie::wrap::readNetwork(params);
|
||||
net.setBatchSize(params.batch_size);
|
||||
inputs = net.getInputsInfo();
|
||||
outputs = net.getOutputsInfo();
|
||||
} else if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import) {
|
||||
this_plugin = cv::gimpl::ie::wrap::getPlugin(params);
|
||||
this_plugin.SetConfig(params.config);
|
||||
this_network = cv::gimpl::ie::wrap::importNetwork(this_plugin, params, rctx);
|
||||
if (!params.reshape_table.empty() || !params.layer_names_to_reshape.empty()) {
|
||||
GAPI_LOG_WARNING(NULL, "Reshape isn't supported for imported network");
|
||||
@ -268,14 +269,14 @@ struct IEUnit {
|
||||
}
|
||||
if (params.num_in == 1u && params.input_names.empty()) {
|
||||
if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
|
||||
params.input_names = { inputs.begin()->first };
|
||||
params.input_names = { net.getInputsInfo().begin()->first };
|
||||
} else {
|
||||
params.input_names = { this_network.GetInputsInfo().begin()->first };
|
||||
}
|
||||
}
|
||||
if (params.num_out == 1u && params.output_names.empty()) {
|
||||
if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
|
||||
params.output_names = { outputs.begin()->first };
|
||||
params.output_names = { net.getOutputsInfo().begin()->first };
|
||||
} else {
|
||||
params.output_names = { this_network.GetOutputsInfo().begin()->first };
|
||||
}
|
||||
@ -290,11 +291,11 @@ struct IEUnit {
|
||||
// This method is [supposed to be] called at Island compilation stage
|
||||
cv::gimpl::ie::IECompiled compile() const {
|
||||
IEUnit* non_const_this = const_cast<IEUnit*>(this);
|
||||
// FIXME: LoadNetwork must be called only after all necessary model
|
||||
// inputs information is set, since it's done in outMeta and compile called after that,
|
||||
// this place seems to be suitable, but consider another place not to break const agreements.
|
||||
if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
|
||||
// FIXME: In case importNetwork for fill inputs/outputs need to obtain ExecutableNetwork, but
|
||||
// for loadNetwork they can be obtained by using readNetwork
|
||||
non_const_this->this_plugin = cv::gimpl::ie::wrap::getPlugin(params);
|
||||
non_const_this->this_plugin.SetConfig(params.config);
|
||||
non_const_this->this_network = cv::gimpl::ie::wrap::loadNetwork(non_const_this->this_plugin,
|
||||
net, params, rctx);
|
||||
}
|
||||
@ -540,19 +541,16 @@ inline IE::Blob::Ptr extractBlob(IECallContext& ctx, std::size_t i) {
|
||||
}
|
||||
|
||||
|
||||
static void setBlob(InferenceEngine::InferRequest& req,
|
||||
cv::gapi::ie::detail::ParamDesc::Kind kind,
|
||||
const std::string& layer_name,
|
||||
IE::Blob::Ptr blob) {
|
||||
// NB: In case importNetwork preprocessing must be
|
||||
// passed as SetBlob argument.
|
||||
if (kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
|
||||
static void setBlob(InferenceEngine::InferRequest& req,
|
||||
const std::string& layer_name,
|
||||
const IE::Blob::Ptr& blob,
|
||||
const IECallContext& ctx) {
|
||||
using namespace cv::gapi::ie::detail;
|
||||
if (ctx.uu.params.kind == ParamDesc::Kind::Load) {
|
||||
req.SetBlob(layer_name, blob);
|
||||
} else {
|
||||
GAPI_Assert(kind == cv::gapi::ie::detail::ParamDesc::Kind::Import);
|
||||
IE::PreProcessInfo info;
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
req.SetBlob(layer_name, blob, info);
|
||||
GAPI_Assert(ctx.uu.params.kind == ParamDesc::Kind::Import);
|
||||
req.SetBlob(layer_name, blob, ctx.uu.preproc_map.at(layer_name));
|
||||
}
|
||||
}
|
||||
|
||||
@ -822,6 +820,23 @@ static void configureInputInfo(const IE::InputInfo::Ptr& ii, const cv::GMetaArg
|
||||
}
|
||||
}
|
||||
|
||||
static IE::PreProcessInfo configurePreProcInfo(const IE::InputInfo::CPtr& ii,
|
||||
const cv::GMetaArg& mm) {
|
||||
IE::PreProcessInfo info;
|
||||
if (cv::util::holds_alternative<cv::GFrameDesc>(mm)) {
|
||||
auto desc = cv::util::get<cv::GFrameDesc>(mm);
|
||||
if (desc.fmt == cv::MediaFormat::NV12) {
|
||||
info.setColorFormat(IE::ColorFormat::NV12);
|
||||
}
|
||||
}
|
||||
const auto layout = ii->getTensorDesc().getLayout();
|
||||
if (layout == IE::Layout::NCHW ||
|
||||
layout == IE::Layout::NHWC) {
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
// NB: This is a callback used by async infer
|
||||
// to post outputs blobs (cv::GMat's).
|
||||
static void PostOutputs(InferenceEngine::InferRequest &request,
|
||||
@ -921,11 +936,13 @@ struct Infer: public cv::detail::KernelTag {
|
||||
|
||||
// NB: Configuring input precision and network reshape must be done
|
||||
// only in the loadNetwork case.
|
||||
if (uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
|
||||
using namespace cv::gapi::ie::detail;
|
||||
if (uu.params.kind == ParamDesc::Kind::Load) {
|
||||
auto inputs = uu.net.getInputsInfo();
|
||||
for (auto &&it : ade::util::zip(ade::util::toRange(uu.params.input_names),
|
||||
ade::util::toRange(in_metas))) {
|
||||
const auto &input_name = std::get<0>(it);
|
||||
auto &&ii = uu.inputs.at(input_name);
|
||||
auto ii = inputs.at(input_name);
|
||||
const auto & mm = std::get<1>(it);
|
||||
|
||||
configureInputInfo(ii, mm);
|
||||
@ -942,6 +959,18 @@ struct Infer: public cv::detail::KernelTag {
|
||||
if (!input_reshape_table.empty()) {
|
||||
const_cast<IE::CNNNetwork *>(&uu.net)->reshape(input_reshape_table);
|
||||
}
|
||||
} else {
|
||||
GAPI_Assert(uu.params.kind == ParamDesc::Kind::Import);
|
||||
auto inputs = uu.this_network.GetInputsInfo();
|
||||
// FIXME: This isn't the best place to collect PreProcMap.
|
||||
auto* non_const_prepm = const_cast<IEUnit::PreProcMap*>(&uu.preproc_map);
|
||||
for (auto &&it : ade::util::zip(ade::util::toRange(uu.params.input_names),
|
||||
ade::util::toRange(in_metas))) {
|
||||
const auto &input_name = std::get<0>(it);
|
||||
auto ii = inputs.at(input_name);
|
||||
const auto & mm = std::get<1>(it);
|
||||
non_const_prepm->emplace(input_name, configurePreProcInfo(ii, mm));
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: It would be nice here to have an exact number of network's
|
||||
@ -950,11 +979,13 @@ struct Infer: public cv::detail::KernelTag {
|
||||
for (const auto &out_name : uu.params.output_names) {
|
||||
// NOTE: our output_names vector follows the API order
|
||||
// of this operation's outputs
|
||||
const IE::DataPtr& ie_out = uu.outputs.at(out_name);
|
||||
const IE::SizeVector dims = ie_out->getTensorDesc().getDims();
|
||||
const auto& desc =
|
||||
uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load
|
||||
? uu.net.getOutputsInfo().at(out_name)->getTensorDesc()
|
||||
: uu.this_network.GetOutputsInfo().at(out_name)->getTensorDesc();
|
||||
|
||||
cv::GMatDesc outm(toCV(ie_out->getPrecision()),
|
||||
toCV(ie_out->getTensorDesc().getDims()));
|
||||
cv::GMatDesc outm(toCV(desc.getPrecision()),
|
||||
toCV(desc.getDims()));
|
||||
result.emplace_back(outm);
|
||||
}
|
||||
return result;
|
||||
@ -973,10 +1004,7 @@ struct Infer: public cv::detail::KernelTag {
|
||||
// and redirect our data producers to this memory
|
||||
// (A memory dialog comes to the picture again)
|
||||
IE::Blob::Ptr this_blob = extractBlob(*ctx, i);
|
||||
setBlob(req,
|
||||
ctx->uu.params.kind,
|
||||
ctx->uu.params.input_names[i],
|
||||
this_blob);
|
||||
setBlob(req, ctx->uu.params.input_names[i], this_blob, *ctx);
|
||||
}
|
||||
// FIXME: Should it be done by kernel ?
|
||||
// What about to do that in RequestPool ?
|
||||
@ -1008,13 +1036,13 @@ struct InferROI: public cv::detail::KernelTag {
|
||||
GAPI_Assert(1u == uu.params.input_names.size());
|
||||
GAPI_Assert(2u == in_metas.size());
|
||||
|
||||
const auto &input_name = uu.params.input_names.at(0);
|
||||
auto &&mm = in_metas.at(1u);
|
||||
// NB: Configuring input precision and network reshape must be done
|
||||
// only in the loadNetwork case.
|
||||
if (uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
|
||||
// 0th is ROI, 1st is input image
|
||||
const auto &input_name = uu.params.input_names.at(0);
|
||||
auto &&ii = uu.inputs.at(input_name);
|
||||
auto &&mm = in_metas.at(1u);
|
||||
auto ii = uu.net.getInputsInfo().at(input_name);
|
||||
configureInputInfo(ii, mm);
|
||||
if (uu.params.layer_names_to_reshape.find(input_name) !=
|
||||
uu.params.layer_names_to_reshape.end()) {
|
||||
@ -1028,6 +1056,13 @@ struct InferROI: public cv::detail::KernelTag {
|
||||
if (!input_reshape_table.empty()) {
|
||||
const_cast<IE::CNNNetwork *>(&uu.net)->reshape(input_reshape_table);
|
||||
}
|
||||
} else {
|
||||
GAPI_Assert(uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import);
|
||||
auto inputs = uu.this_network.GetInputsInfo();
|
||||
// FIXME: This isn't the best place to collect PreProcMap.
|
||||
auto* non_const_prepm = const_cast<IEUnit::PreProcMap*>(&uu.preproc_map);
|
||||
auto ii = inputs.at(input_name);
|
||||
non_const_prepm->emplace(input_name, configurePreProcInfo(ii, mm));
|
||||
}
|
||||
|
||||
// FIXME: It would be nice here to have an exact number of network's
|
||||
@ -1036,11 +1071,13 @@ struct InferROI: public cv::detail::KernelTag {
|
||||
for (const auto &out_name : uu.params.output_names) {
|
||||
// NOTE: our output_names vector follows the API order
|
||||
// of this operation's outputs
|
||||
const IE::DataPtr& ie_out = uu.outputs.at(out_name);
|
||||
const IE::SizeVector dims = ie_out->getTensorDesc().getDims();
|
||||
const auto& desc =
|
||||
uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load
|
||||
? uu.net.getOutputsInfo().at(out_name)->getTensorDesc()
|
||||
: uu.this_network.GetOutputsInfo().at(out_name)->getTensorDesc();
|
||||
|
||||
cv::GMatDesc outm(toCV(ie_out->getPrecision()),
|
||||
toCV(ie_out->getTensorDesc().getDims()));
|
||||
cv::GMatDesc outm(toCV(desc.getPrecision()),
|
||||
toCV(desc.getDims()));
|
||||
result.emplace_back(outm);
|
||||
}
|
||||
return result;
|
||||
@ -1057,10 +1094,9 @@ struct InferROI: public cv::detail::KernelTag {
|
||||
|
||||
IE::Blob::Ptr this_blob = extractBlob(*ctx, 1);
|
||||
setBlob(req,
|
||||
ctx->uu.params.kind,
|
||||
*(ctx->uu.params.input_names.begin()),
|
||||
IE::make_shared_blob(this_blob,
|
||||
toIE(this_roi)));
|
||||
IE::make_shared_blob(this_blob, toIE(this_roi)),
|
||||
*ctx);
|
||||
// FIXME: Should it be done by kernel ?
|
||||
// What about to do that in RequestPool ?
|
||||
req.StartAsync();
|
||||
@ -1099,8 +1135,9 @@ struct InferList: public cv::detail::KernelTag {
|
||||
// only in the loadNetwork case.
|
||||
if (uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
|
||||
std::size_t idx = 1u;
|
||||
auto inputs = uu.net.getInputsInfo();
|
||||
for (auto &&input_name : uu.params.input_names) {
|
||||
auto &&ii = uu.inputs.at(input_name);
|
||||
auto ii = inputs.at(input_name);
|
||||
const auto & mm = in_metas[idx++];
|
||||
configureInputInfo(ii, mm);
|
||||
if (uu.params.layer_names_to_reshape.find(input_name) !=
|
||||
@ -1116,6 +1153,16 @@ struct InferList: public cv::detail::KernelTag {
|
||||
if (!input_reshape_table.empty()) {
|
||||
const_cast<IE::CNNNetwork *>(&uu.net)->reshape(input_reshape_table);
|
||||
}
|
||||
} else {
|
||||
GAPI_Assert(uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import);
|
||||
std::size_t idx = 1u;
|
||||
auto inputs = uu.this_network.GetInputsInfo();
|
||||
auto* non_const_prepm = const_cast<IEUnit::PreProcMap*>(&uu.preproc_map);
|
||||
for (auto &&input_name : uu.params.input_names) {
|
||||
auto ii = inputs.at(input_name);
|
||||
const auto & mm = in_metas[idx++];
|
||||
non_const_prepm->emplace(input_name, configurePreProcInfo(ii, mm));
|
||||
}
|
||||
}
|
||||
|
||||
// roi-list version is much easier at the moment.
|
||||
@ -1144,8 +1191,12 @@ struct InferList: public cv::detail::KernelTag {
|
||||
|
||||
std::vector<std::vector<int>> cached_dims(ctx->uu.params.num_out);
|
||||
for (auto i : ade::util::iota(ctx->uu.params.num_out)) {
|
||||
const IE::DataPtr& ie_out = ctx->uu.outputs.at(ctx->uu.params.output_names[i]);
|
||||
cached_dims[i] = toCV(ie_out->getTensorDesc().getDims());
|
||||
const auto& out_name = ctx->uu.params.output_names[i];
|
||||
const auto& desc =
|
||||
ctx->uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load
|
||||
? ctx->uu.net.getOutputsInfo().at(out_name)->getTensorDesc()
|
||||
: ctx->uu.this_network.GetOutputsInfo().at(out_name)->getTensorDesc();
|
||||
cached_dims[i] = toCV(desc.getDims());
|
||||
// FIXME: Isn't this should be done automatically
|
||||
// by some resetInternalData(), etc? (Probably at the GExecutor level)
|
||||
auto& out_vec = ctx->outVecR<cv::Mat>(i);
|
||||
@ -1161,10 +1212,7 @@ struct InferList: public cv::detail::KernelTag {
|
||||
cv::gimpl::ie::RequestPool::Task {
|
||||
[ctx, rc, this_blob](InferenceEngine::InferRequest &req) {
|
||||
IE::Blob::Ptr roi_blob = IE::make_shared_blob(this_blob, toIE(rc));
|
||||
setBlob(req,
|
||||
ctx->uu.params.kind,
|
||||
ctx->uu.params.input_names[0u],
|
||||
roi_blob);
|
||||
setBlob(req, ctx->uu.params.input_names[0u], roi_blob, *ctx);
|
||||
req.StartAsync();
|
||||
},
|
||||
std::bind(callback, std::placeholders::_1, pos)
|
||||
@ -1232,7 +1280,6 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
|
||||
std::size_t idx = 1u;
|
||||
for (auto &&input_name : uu.params.input_names) {
|
||||
auto &ii = uu.inputs.at(input_name);
|
||||
const auto &mm = in_metas[idx];
|
||||
GAPI_Assert(util::holds_alternative<cv::GArrayDesc>(mm)
|
||||
&& "Non-array inputs are not supported");
|
||||
@ -1242,6 +1289,7 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
// only in the loadNetwork case.
|
||||
if (uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
|
||||
// This is a cv::Rect -- configure the IE preprocessing
|
||||
auto ii = uu.net.getInputsInfo().at(input_name);
|
||||
configureInputInfo(ii, mm_0);
|
||||
if (uu.params.layer_names_to_reshape.find(input_name) !=
|
||||
uu.params.layer_names_to_reshape.end()) {
|
||||
@ -1255,6 +1303,12 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
if (!input_reshape_table.empty()) {
|
||||
const_cast<IE::CNNNetwork *>(&uu.net)->reshape(input_reshape_table);
|
||||
}
|
||||
} else {
|
||||
GAPI_Assert(uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import);
|
||||
auto inputs = uu.this_network.GetInputsInfo();
|
||||
auto* non_const_prepm = const_cast<IEUnit::PreProcMap*>(&uu.preproc_map);
|
||||
auto ii = inputs.at(input_name);
|
||||
non_const_prepm->emplace(input_name, configurePreProcInfo(ii, mm_0));
|
||||
}
|
||||
} else {
|
||||
// This is a cv::GMat (equals to: cv::Mat)
|
||||
@ -1290,8 +1344,12 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
// FIXME: This could be done ONCE at graph compile stage!
|
||||
std::vector< std::vector<int> > cached_dims(ctx->uu.params.num_out);
|
||||
for (auto i : ade::util::iota(ctx->uu.params.num_out)) {
|
||||
const IE::DataPtr& ie_out = ctx->uu.outputs.at(ctx->uu.params.output_names[i]);
|
||||
cached_dims[i] = toCV(ie_out->getTensorDesc().getDims());
|
||||
const auto& out_name = ctx->uu.params.output_names[i];
|
||||
const auto& desc =
|
||||
ctx->uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load
|
||||
? ctx->uu.net.getOutputsInfo().at(out_name)->getTensorDesc()
|
||||
: ctx->uu.this_network.GetOutputsInfo().at(out_name)->getTensorDesc();
|
||||
cached_dims[i] = toCV(desc.getDims());
|
||||
// FIXME: Isn't this should be done automatically
|
||||
// by some resetInternalData(), etc? (Probably at the GExecutor level)
|
||||
auto& out_vec = ctx->outVecR<cv::Mat>(i);
|
||||
@ -1319,10 +1377,7 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
GAPI_Assert(false &&
|
||||
"Only Rect and Mat types are supported for infer list 2!");
|
||||
}
|
||||
setBlob(req,
|
||||
ctx->uu.params.kind,
|
||||
ctx->uu.params.input_names[in_idx],
|
||||
this_blob);
|
||||
setBlob(req, ctx->uu.params.input_names[in_idx], this_blob, *ctx);
|
||||
}
|
||||
req.StartAsync();
|
||||
},
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
|
||||
namespace IE = InferenceEngine;
|
||||
namespace giewrap = cv::gimpl::ie::wrap;
|
||||
using GIEParam = cv::gapi::ie::detail::ParamDesc;
|
||||
@ -93,11 +95,38 @@ IE::InferencePlugin giewrap::getPlugin(const GIEParam& params) {
|
||||
return plugin;
|
||||
}
|
||||
#else // >= 2019.R2
|
||||
IE::Core giewrap::getCore() {
|
||||
|
||||
// NB: Some of IE plugins fail during IE::Core destroying in specific cases.
|
||||
// Solution is allocate IE::Core in heap and doesn't destroy it, which cause
|
||||
// leak, but fixes tests on CI. This behaviour is configurable by using
|
||||
// OPENCV_GAPI_INFERENCE_ENGINE_CORE_LIFETIME_WORKAROUND=0
|
||||
static IE::Core create_IE_Core_pointer() {
|
||||
// NB: 'delete' is never called
|
||||
static IE::Core* core = new IE::Core();
|
||||
return *core;
|
||||
}
|
||||
|
||||
static IE::Core create_IE_Core_instance() {
|
||||
static IE::Core core;
|
||||
return core;
|
||||
}
|
||||
|
||||
IE::Core giewrap::getCore() {
|
||||
// NB: to make happy memory leak tools use:
|
||||
// - OPENCV_GAPI_INFERENCE_ENGINE_CORE_LIFETIME_WORKAROUND=0
|
||||
static bool param_GAPI_INFERENCE_ENGINE_CORE_LIFETIME_WORKAROUND =
|
||||
utils::getConfigurationParameterBool(
|
||||
"OPENCV_GAPI_INFERENCE_ENGINE_CORE_LIFETIME_WORKAROUND",
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
);
|
||||
return param_GAPI_INFERENCE_ENGINE_CORE_LIFETIME_WORKAROUND
|
||||
? create_IE_Core_pointer() : create_IE_Core_instance();
|
||||
}
|
||||
|
||||
IE::Core giewrap::getPlugin(const GIEParam& params) {
|
||||
auto plugin = giewrap::getCore();
|
||||
if (params.device_id == "CPU" || params.device_id == "FPGA")
|
||||
|
||||
@ -34,13 +34,12 @@ using Plugin = IE::InferencePlugin;
|
||||
GAPI_EXPORTS IE::InferencePlugin getPlugin(const GIEParam& params);
|
||||
GAPI_EXPORTS inline IE::ExecutableNetwork loadNetwork( IE::InferencePlugin& plugin,
|
||||
const IE::CNNNetwork& net,
|
||||
const GIEParam&) {
|
||||
return plugin.LoadNetwork(net, {}); // FIXME: 2nd parameter to be
|
||||
// configurable via the API
|
||||
const GIEParam& params) {
|
||||
return plugin.LoadNetwork(net, params.config);
|
||||
}
|
||||
GAPI_EXPORTS inline IE::ExecutableNetwork importNetwork( IE::CNNNetwork& plugin,
|
||||
const GIEParam& param) {
|
||||
return plugin.ImportNetwork(param.model_path, param.device_id, {});
|
||||
const GIEParam& params) {
|
||||
return plugin.ImportNetwork(param.model_path, param.device_id, params.config);
|
||||
}
|
||||
#else // >= 2019.R2
|
||||
using Plugin = IE::Core;
|
||||
@ -51,9 +50,9 @@ GAPI_EXPORTS inline IE::ExecutableNetwork loadNetwork( IE::Core& core
|
||||
const GIEParam& params,
|
||||
IE::RemoteContext::Ptr rctx = nullptr) {
|
||||
if (rctx != nullptr) {
|
||||
return core.LoadNetwork(net, rctx);
|
||||
return core.LoadNetwork(net, rctx, params.config);
|
||||
} else {
|
||||
return core.LoadNetwork(net, params.device_id);
|
||||
return core.LoadNetwork(net, params.device_id, params.config);
|
||||
}
|
||||
}
|
||||
GAPI_EXPORTS inline IE::ExecutableNetwork importNetwork( IE::Core& core,
|
||||
@ -67,9 +66,9 @@ GAPI_EXPORTS inline IE::ExecutableNetwork importNetwork( IE::Core& core,
|
||||
throw std::runtime_error("Could not open file");
|
||||
}
|
||||
std::istream graphBlob(&blobFile);
|
||||
return core.ImportNetwork(graphBlob, rctx);
|
||||
return core.ImportNetwork(graphBlob, rctx, params.config);
|
||||
} else {
|
||||
return core.ImportNetwork(params.model_path, params.device_id, {});
|
||||
return core.ImportNetwork(params.model_path, params.device_id, params.config);
|
||||
}
|
||||
}
|
||||
#endif // INF_ENGINE_RELEASE < 2019020000
|
||||
|
||||
@ -139,6 +139,48 @@ void setNetParameters(IE::CNNNetwork& net, bool is_nv12 = false) {
|
||||
}
|
||||
}
|
||||
|
||||
bool checkDeviceIsAvailable(const std::string& device) {
|
||||
const static auto available_devices = [&](){
|
||||
auto devices = cv::gimpl::ie::wrap::getCore().GetAvailableDevices();
|
||||
return std::unordered_set<std::string>{devices.begin(), devices.end()};
|
||||
}();
|
||||
return available_devices.find(device) != available_devices.end();
|
||||
}
|
||||
|
||||
void skipIfDeviceNotAvailable(const std::string& device) {
|
||||
if (!checkDeviceIsAvailable(device)) {
|
||||
throw SkipTestException("Device: " + device + " isn't available!");
|
||||
}
|
||||
}
|
||||
|
||||
void compileBlob(const cv::gapi::ie::detail::ParamDesc& params,
|
||||
const std::string& output,
|
||||
const IE::Precision& ip) {
|
||||
auto plugin = cv::gimpl::ie::wrap::getPlugin(params);
|
||||
auto net = cv::gimpl::ie::wrap::readNetwork(params);
|
||||
for (auto&& ii : net.getInputsInfo()) {
|
||||
ii.second->setPrecision(ip);
|
||||
}
|
||||
auto this_network = cv::gimpl::ie::wrap::loadNetwork(plugin, net, params);
|
||||
std::ofstream out_file{output, std::ios::out | std::ios::binary};
|
||||
GAPI_Assert(out_file.is_open());
|
||||
this_network.Export(out_file);
|
||||
}
|
||||
|
||||
std::string compileAgeGenderBlob(const std::string& device) {
|
||||
const static std::string blob_path = [&](){
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
const std::string model_name = "age-gender-recognition-retail-0013";
|
||||
const std::string output = model_name + ".blob";
|
||||
params.model_path = findDataFile(SUBDIR + model_name + ".xml");
|
||||
params.weights_path = findDataFile(SUBDIR + model_name + ".bin");
|
||||
params.device_id = device;
|
||||
compileBlob(params, output, IE::Precision::U8);
|
||||
return output;
|
||||
}();
|
||||
return blob_path;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// TODO: Probably DNN/IE part can be further parametrized with a template
|
||||
@ -471,10 +513,10 @@ struct ROIListNV12: public ::testing::Test {
|
||||
for (auto &&rc : m_roi_list) {
|
||||
const auto ie_rc = IE::ROI {
|
||||
0u
|
||||
, static_cast<std::size_t>(rc.x)
|
||||
, static_cast<std::size_t>(rc.y)
|
||||
, static_cast<std::size_t>(rc.width)
|
||||
, static_cast<std::size_t>(rc.height)
|
||||
, static_cast<std::size_t>(rc.x)
|
||||
, static_cast<std::size_t>(rc.y)
|
||||
, static_cast<std::size_t>(rc.width)
|
||||
, static_cast<std::size_t>(rc.height)
|
||||
};
|
||||
infer_request.SetBlob("data", IE::make_shared_blob(frame_blob, ie_rc));
|
||||
infer_request.Infer();
|
||||
@ -534,11 +576,11 @@ struct SingleROI: public ::testing::Test {
|
||||
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)
|
||||
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);
|
||||
@ -596,11 +638,11 @@ struct SingleROINV12: public ::testing::Test {
|
||||
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)
|
||||
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);
|
||||
@ -2065,7 +2107,7 @@ struct Sync {
|
||||
|
||||
class GMockMediaAdapter final: public cv::MediaFrame::IAdapter {
|
||||
public:
|
||||
explicit GMockMediaAdapter(cv::Mat m, Sync& sync)
|
||||
explicit GMockMediaAdapter(cv::Mat m, std::shared_ptr<Sync> sync)
|
||||
: m_mat(m), m_sync(sync) {
|
||||
}
|
||||
|
||||
@ -2081,15 +2123,15 @@ public:
|
||||
|
||||
~GMockMediaAdapter() {
|
||||
{
|
||||
std::lock_guard<std::mutex> lk{m_sync.m};
|
||||
m_sync.counter--;
|
||||
std::lock_guard<std::mutex> lk{m_sync->m};
|
||||
m_sync->counter--;
|
||||
}
|
||||
m_sync.cv.notify_one();
|
||||
m_sync->cv.notify_one();
|
||||
}
|
||||
|
||||
private:
|
||||
cv::Mat m_mat;
|
||||
Sync& m_sync;
|
||||
cv::Mat m_mat;
|
||||
std::shared_ptr<Sync> m_sync;
|
||||
};
|
||||
|
||||
// NB: This source is needed to simulate real
|
||||
@ -2099,15 +2141,16 @@ private:
|
||||
class GMockSource : public cv::gapi::wip::IStreamSource {
|
||||
public:
|
||||
explicit GMockSource(int limit)
|
||||
: m_limit(limit), m_mat(cv::Size(1920, 1080), CV_8UC3) {
|
||||
: m_limit(limit), m_mat(cv::Size(1920, 1080), CV_8UC3),
|
||||
m_sync(new Sync{}) {
|
||||
cv::randu(m_mat, cv::Scalar::all(0), cv::Scalar::all(255));
|
||||
}
|
||||
|
||||
bool pull(cv::gapi::wip::Data& data) {
|
||||
std::unique_lock<std::mutex> lk(m_sync.m);
|
||||
m_sync.counter++;
|
||||
std::unique_lock<std::mutex> lk(m_sync->m);
|
||||
m_sync->counter++;
|
||||
// NB: Can't produce new frames until old ones are released.
|
||||
m_sync.cv.wait(lk, [this]{return m_sync.counter <= m_limit;});
|
||||
m_sync->cv.wait(lk, [this]{return m_sync->counter <= m_limit;});
|
||||
|
||||
data = cv::MediaFrame::Create<GMockMediaAdapter>(m_mat, m_sync);
|
||||
return true;
|
||||
@ -2118,9 +2161,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
int m_limit;
|
||||
cv::Mat m_mat;
|
||||
Sync m_sync;
|
||||
int m_limit;
|
||||
cv::Mat m_mat;
|
||||
std::shared_ptr<Sync> m_sync;
|
||||
};
|
||||
|
||||
struct LimitedSourceInfer: public ::testing::Test {
|
||||
@ -2239,6 +2282,582 @@ TEST(TestAgeGenderIE, InferWithBatch)
|
||||
normAssert(cv::gapi::ie::util::to_ocv(ie_gender), gapi_gender, "Test gender output");
|
||||
}
|
||||
|
||||
TEST(ImportNetwork, Infer)
|
||||
{
|
||||
const std::string device = "MYRIAD";
|
||||
skipIfDeviceNotAvailable(device);
|
||||
|
||||
initDLDTDataPath();
|
||||
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
params.model_path = compileAgeGenderBlob(device);
|
||||
params.device_id = device;
|
||||
|
||||
cv::Mat in_mat(320, 240, CV_8UC3);
|
||||
cv::randu(in_mat, 0, 255);
|
||||
cv::Mat gapi_age, gapi_gender;
|
||||
|
||||
// Load & run IE network
|
||||
IE::Blob::Ptr ie_age, ie_gender;
|
||||
{
|
||||
auto plugin = cv::gimpl::ie::wrap::getPlugin(params);
|
||||
auto this_network = cv::gimpl::ie::wrap::importNetwork(plugin, params);
|
||||
auto infer_request = this_network.CreateInferRequest();
|
||||
IE::PreProcessInfo info;
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
infer_request.SetBlob("data", cv::gapi::ie::util::to_ie(in_mat), info);
|
||||
infer_request.Infer();
|
||||
ie_age = infer_request.GetBlob("age_conv3");
|
||||
ie_gender = infer_request.GetBlob("prob");
|
||||
}
|
||||
|
||||
// Configure & run G-API
|
||||
using AGInfo = std::tuple<cv::GMat, cv::GMat>;
|
||||
G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "test-age-gender");
|
||||
|
||||
cv::GMat in;
|
||||
cv::GMat age, gender;
|
||||
std::tie(age, gender) = cv::gapi::infer<AgeGender>(in);
|
||||
cv::GComputation comp(cv::GIn(in), cv::GOut(age, gender));
|
||||
|
||||
auto pp = cv::gapi::ie::Params<AgeGender> {
|
||||
params.model_path, params.device_id
|
||||
}.cfgOutputLayers({ "age_conv3", "prob" });
|
||||
|
||||
comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
|
||||
cv::compile_args(cv::gapi::networks(pp)));
|
||||
|
||||
// Validate with IE itself (avoid DNN module dependency here)
|
||||
normAssert(cv::gapi::ie::util::to_ocv(ie_age), gapi_age, "Test age output" );
|
||||
normAssert(cv::gapi::ie::util::to_ocv(ie_gender), gapi_gender, "Test gender output");
|
||||
}
|
||||
|
||||
TEST(ImportNetwork, InferNV12)
|
||||
{
|
||||
const std::string device = "MYRIAD";
|
||||
skipIfDeviceNotAvailable(device);
|
||||
|
||||
initDLDTDataPath();
|
||||
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
params.model_path= compileAgeGenderBlob(device);
|
||||
params.device_id = device;
|
||||
|
||||
cv::Size sz{320, 240};
|
||||
cv::Mat in_y_mat(sz, CV_8UC1);
|
||||
cv::randu(in_y_mat, 0, 255);
|
||||
cv::Mat in_uv_mat(sz / 2, CV_8UC2);
|
||||
cv::randu(in_uv_mat, 0, 255);
|
||||
|
||||
cv::Mat gapi_age, gapi_gender;
|
||||
|
||||
// Load & run IE network
|
||||
IE::Blob::Ptr ie_age, ie_gender;
|
||||
{
|
||||
auto plugin = cv::gimpl::ie::wrap::getPlugin(params);
|
||||
auto this_network = cv::gimpl::ie::wrap::importNetwork(plugin, params);
|
||||
auto infer_request = this_network.CreateInferRequest();
|
||||
IE::PreProcessInfo info;
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
info.setColorFormat(IE::ColorFormat::NV12);
|
||||
infer_request.SetBlob("data", cv::gapi::ie::util::to_ie(in_y_mat, in_uv_mat), info);
|
||||
infer_request.Infer();
|
||||
ie_age = infer_request.GetBlob("age_conv3");
|
||||
ie_gender = infer_request.GetBlob("prob");
|
||||
}
|
||||
|
||||
// Configure & run G-API
|
||||
using AGInfo = std::tuple<cv::GMat, cv::GMat>;
|
||||
G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "test-age-gender");
|
||||
|
||||
cv::GFrame in;
|
||||
cv::GMat age, gender;
|
||||
std::tie(age, gender) = cv::gapi::infer<AgeGender>(in);
|
||||
cv::GComputation comp(cv::GIn(in), cv::GOut(age, gender));
|
||||
|
||||
auto frame = MediaFrame::Create<TestMediaNV12>(in_y_mat, in_uv_mat);
|
||||
|
||||
auto pp = cv::gapi::ie::Params<AgeGender> {
|
||||
params.model_path, params.device_id
|
||||
}.cfgOutputLayers({ "age_conv3", "prob" });
|
||||
comp.apply(cv::gin(frame), cv::gout(gapi_age, gapi_gender),
|
||||
cv::compile_args(cv::gapi::networks(pp)));
|
||||
|
||||
// Validate with IE itself (avoid DNN module dependency here)
|
||||
normAssert(cv::gapi::ie::util::to_ocv(ie_age), gapi_age, "Test age output" );
|
||||
normAssert(cv::gapi::ie::util::to_ocv(ie_gender), gapi_gender, "Test gender output");
|
||||
}
|
||||
|
||||
TEST(ImportNetwork, InferROI)
|
||||
{
|
||||
const std::string device = "MYRIAD";
|
||||
skipIfDeviceNotAvailable(device);
|
||||
|
||||
initDLDTDataPath();
|
||||
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
params.model_path = compileAgeGenderBlob(device);
|
||||
params.device_id = device;
|
||||
|
||||
cv::Mat in_mat(320, 240, CV_8UC3);
|
||||
cv::randu(in_mat, 0, 255);
|
||||
cv::Mat gapi_age, gapi_gender;
|
||||
cv::Rect 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 this_network = cv::gimpl::ie::wrap::importNetwork(plugin, params);
|
||||
auto infer_request = this_network.CreateInferRequest();
|
||||
const auto ie_rc = IE::ROI {
|
||||
0u
|
||||
, static_cast<std::size_t>(rect.x)
|
||||
, static_cast<std::size_t>(rect.y)
|
||||
, static_cast<std::size_t>(rect.width)
|
||||
, static_cast<std::size_t>(rect.height)
|
||||
};
|
||||
IE::Blob::Ptr roi_blob = IE::make_shared_blob(cv::gapi::ie::util::to_ie(in_mat), ie_rc);
|
||||
IE::PreProcessInfo info;
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
infer_request.SetBlob("data", roi_blob, info);
|
||||
infer_request.Infer();
|
||||
ie_age = infer_request.GetBlob("age_conv3");
|
||||
ie_gender = infer_request.GetBlob("prob");
|
||||
}
|
||||
|
||||
using AGInfo = std::tuple<cv::GMat, cv::GMat>;
|
||||
G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "test-age-gender");
|
||||
|
||||
cv::GMat in;
|
||||
cv::GOpaque<cv::Rect> roi;
|
||||
cv::GMat age, gender;
|
||||
std::tie(age, gender) = cv::gapi::infer<AgeGender>(roi, in);
|
||||
cv::GComputation comp(cv::GIn(in, roi), cv::GOut(age, gender));
|
||||
|
||||
auto pp = cv::gapi::ie::Params<AgeGender> {
|
||||
params.model_path, params.device_id
|
||||
}.cfgOutputLayers({ "age_conv3", "prob" });
|
||||
|
||||
comp.apply(cv::gin(in_mat, rect), cv::gout(gapi_age, gapi_gender),
|
||||
cv::compile_args(cv::gapi::networks(pp)));
|
||||
|
||||
// Validate with IE itself (avoid DNN module dependency here)
|
||||
normAssert(cv::gapi::ie::util::to_ocv(ie_age), gapi_age, "Test age output" );
|
||||
normAssert(cv::gapi::ie::util::to_ocv(ie_gender), gapi_gender, "Test gender output");
|
||||
}
|
||||
|
||||
TEST(ImportNetwork, InferROINV12)
|
||||
{
|
||||
const std::string device = "MYRIAD";
|
||||
skipIfDeviceNotAvailable(device);
|
||||
|
||||
initDLDTDataPath();
|
||||
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
params.model_path = compileAgeGenderBlob(device);
|
||||
params.device_id = device;
|
||||
|
||||
cv::Size sz{320, 240};
|
||||
cv::Mat in_y_mat(sz, CV_8UC1);
|
||||
cv::randu(in_y_mat, 0, 255);
|
||||
cv::Mat in_uv_mat(sz / 2, CV_8UC2);
|
||||
cv::randu(in_uv_mat, 0, 255);
|
||||
cv::Rect rect(cv::Point{64, 60}, cv::Size{96, 96});
|
||||
|
||||
cv::Mat gapi_age, gapi_gender;
|
||||
|
||||
// Load & run IE network
|
||||
IE::Blob::Ptr ie_age, ie_gender;
|
||||
{
|
||||
auto plugin = cv::gimpl::ie::wrap::getPlugin(params);
|
||||
auto this_network = cv::gimpl::ie::wrap::importNetwork(plugin, params);
|
||||
auto infer_request = this_network.CreateInferRequest();
|
||||
const auto ie_rc = IE::ROI {
|
||||
0u
|
||||
, static_cast<std::size_t>(rect.x)
|
||||
, static_cast<std::size_t>(rect.y)
|
||||
, static_cast<std::size_t>(rect.width)
|
||||
, static_cast<std::size_t>(rect.height)
|
||||
};
|
||||
IE::Blob::Ptr roi_blob =
|
||||
IE::make_shared_blob(cv::gapi::ie::util::to_ie(in_y_mat, in_uv_mat), ie_rc);
|
||||
IE::PreProcessInfo info;
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
info.setColorFormat(IE::ColorFormat::NV12);
|
||||
infer_request.SetBlob("data", roi_blob, info);
|
||||
infer_request.Infer();
|
||||
ie_age = infer_request.GetBlob("age_conv3");
|
||||
ie_gender = infer_request.GetBlob("prob");
|
||||
}
|
||||
|
||||
using AGInfo = std::tuple<cv::GMat, cv::GMat>;
|
||||
G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "test-age-gender");
|
||||
|
||||
cv::GFrame in;
|
||||
cv::GOpaque<cv::Rect> roi;
|
||||
cv::GMat age, gender;
|
||||
std::tie(age, gender) = cv::gapi::infer<AgeGender>(roi, in);
|
||||
cv::GComputation comp(cv::GIn(in, roi), cv::GOut(age, gender));
|
||||
|
||||
auto frame = MediaFrame::Create<TestMediaNV12>(in_y_mat, in_uv_mat);
|
||||
|
||||
auto pp = cv::gapi::ie::Params<AgeGender> {
|
||||
params.model_path, params.device_id
|
||||
}.cfgOutputLayers({ "age_conv3", "prob" });
|
||||
|
||||
comp.apply(cv::gin(frame, rect), cv::gout(gapi_age, gapi_gender),
|
||||
cv::compile_args(cv::gapi::networks(pp)));
|
||||
|
||||
// Validate with IE itself (avoid DNN module dependency here)
|
||||
normAssert(cv::gapi::ie::util::to_ocv(ie_age), gapi_age, "Test age output" );
|
||||
normAssert(cv::gapi::ie::util::to_ocv(ie_gender), gapi_gender, "Test gender output");
|
||||
}
|
||||
|
||||
TEST(ImportNetwork, InferList)
|
||||
{
|
||||
const std::string device = "MYRIAD";
|
||||
skipIfDeviceNotAvailable(device);
|
||||
|
||||
initDLDTDataPath();
|
||||
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
params.model_path = compileAgeGenderBlob(device);
|
||||
params.device_id = device;
|
||||
|
||||
cv::Mat in_mat(320, 240, CV_8UC3);
|
||||
cv::randu(in_mat, 0, 255);
|
||||
std::vector<cv::Rect> roi_list = {
|
||||
cv::Rect(cv::Point{64, 60}, cv::Size{ 96, 96}),
|
||||
cv::Rect(cv::Point{50, 32}, cv::Size{128, 160}),
|
||||
};
|
||||
std::vector<cv::Mat> out_ie_ages, out_ie_genders, out_gapi_ages, out_gapi_genders;
|
||||
|
||||
// Load & run IE network
|
||||
{
|
||||
auto plugin = cv::gimpl::ie::wrap::getPlugin(params);
|
||||
auto this_network = cv::gimpl::ie::wrap::importNetwork(plugin, params);
|
||||
auto infer_request = this_network.CreateInferRequest();
|
||||
for (auto &&rc : roi_list) {
|
||||
const auto ie_rc = IE::ROI {
|
||||
0u
|
||||
, static_cast<std::size_t>(rc.x)
|
||||
, static_cast<std::size_t>(rc.y)
|
||||
, static_cast<std::size_t>(rc.width)
|
||||
, static_cast<std::size_t>(rc.height)
|
||||
};
|
||||
IE::Blob::Ptr roi_blob =
|
||||
IE::make_shared_blob(cv::gapi::ie::util::to_ie(in_mat), ie_rc);
|
||||
IE::PreProcessInfo info;
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
infer_request.SetBlob("data", roi_blob, info);
|
||||
infer_request.Infer();
|
||||
using namespace cv::gapi::ie::util;
|
||||
out_ie_ages.push_back(to_ocv(infer_request.GetBlob("age_conv3")).clone());
|
||||
out_ie_genders.push_back(to_ocv(infer_request.GetBlob("prob")).clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Configure & run G-API
|
||||
using AGInfo = std::tuple<cv::GMat, cv::GMat>;
|
||||
G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "test-age-gender");
|
||||
|
||||
cv::GArray<cv::Rect> rr;
|
||||
cv::GMat in;
|
||||
cv::GArray<cv::GMat> age, gender;
|
||||
std::tie(age, gender) = cv::gapi::infer<AgeGender>(rr, in);
|
||||
cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
|
||||
|
||||
auto pp = cv::gapi::ie::Params<AgeGender> {
|
||||
params.model_path, params.device_id
|
||||
}.cfgOutputLayers({ "age_conv3", "prob" });
|
||||
|
||||
comp.apply(cv::gin(in_mat, roi_list), cv::gout(out_gapi_ages, out_gapi_genders),
|
||||
cv::compile_args(cv::gapi::networks(pp)));
|
||||
|
||||
// Validate with IE itself (avoid DNN module dependency here)
|
||||
GAPI_Assert(!out_gapi_ages.empty());
|
||||
ASSERT_EQ(out_gapi_genders.size(), out_gapi_ages.size());
|
||||
ASSERT_EQ(out_gapi_ages.size(), out_ie_ages.size());
|
||||
ASSERT_EQ(out_gapi_genders.size(), out_ie_genders.size());
|
||||
|
||||
const size_t size = out_gapi_ages.size();
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
normAssert(out_ie_ages [i], out_gapi_ages [i], "Test age output");
|
||||
normAssert(out_ie_genders[i], out_gapi_genders[i], "Test gender output");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ImportNetwork, InferListNV12)
|
||||
{
|
||||
const std::string device = "MYRIAD";
|
||||
skipIfDeviceNotAvailable(device);
|
||||
|
||||
initDLDTDataPath();
|
||||
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
params.model_path = compileAgeGenderBlob(device);
|
||||
params.device_id = device;
|
||||
|
||||
cv::Size sz{320, 240};
|
||||
cv::Mat in_y_mat(sz, CV_8UC1);
|
||||
cv::randu(in_y_mat, 0, 255);
|
||||
cv::Mat in_uv_mat(sz / 2, CV_8UC2);
|
||||
cv::randu(in_uv_mat, 0, 255);
|
||||
std::vector<cv::Rect> roi_list = {
|
||||
cv::Rect(cv::Point{64, 60}, cv::Size{ 96, 96}),
|
||||
cv::Rect(cv::Point{50, 32}, cv::Size{128, 160}),
|
||||
};
|
||||
std::vector<cv::Mat> out_ie_ages, out_ie_genders, out_gapi_ages, out_gapi_genders;
|
||||
|
||||
// Load & run IE network
|
||||
{
|
||||
auto plugin = cv::gimpl::ie::wrap::getPlugin(params);
|
||||
auto this_network = cv::gimpl::ie::wrap::importNetwork(plugin, params);
|
||||
auto infer_request = this_network.CreateInferRequest();
|
||||
for (auto &&rc : roi_list) {
|
||||
const auto ie_rc = IE::ROI {
|
||||
0u
|
||||
, static_cast<std::size_t>(rc.x)
|
||||
, static_cast<std::size_t>(rc.y)
|
||||
, static_cast<std::size_t>(rc.width)
|
||||
, static_cast<std::size_t>(rc.height)
|
||||
};
|
||||
IE::Blob::Ptr roi_blob =
|
||||
IE::make_shared_blob(cv::gapi::ie::util::to_ie(in_y_mat, in_uv_mat), ie_rc);
|
||||
IE::PreProcessInfo info;
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
info.setColorFormat(IE::ColorFormat::NV12);
|
||||
infer_request.SetBlob("data", roi_blob, info);
|
||||
infer_request.Infer();
|
||||
using namespace cv::gapi::ie::util;
|
||||
out_ie_ages.push_back(to_ocv(infer_request.GetBlob("age_conv3")).clone());
|
||||
out_ie_genders.push_back(to_ocv(infer_request.GetBlob("prob")).clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Configure & run G-API
|
||||
using AGInfo = std::tuple<cv::GMat, cv::GMat>;
|
||||
G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "test-age-gender");
|
||||
|
||||
cv::GArray<cv::Rect> rr;
|
||||
cv::GFrame in;
|
||||
cv::GArray<cv::GMat> age, gender;
|
||||
std::tie(age, gender) = cv::gapi::infer<AgeGender>(rr, in);
|
||||
cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
|
||||
|
||||
auto pp = cv::gapi::ie::Params<AgeGender> {
|
||||
params.model_path, params.device_id
|
||||
}.cfgOutputLayers({ "age_conv3", "prob" });
|
||||
|
||||
auto frame = MediaFrame::Create<TestMediaNV12>(in_y_mat, in_uv_mat);
|
||||
|
||||
comp.apply(cv::gin(frame, roi_list), cv::gout(out_gapi_ages, out_gapi_genders),
|
||||
cv::compile_args(cv::gapi::networks(pp)));
|
||||
|
||||
// Validate with IE itself (avoid DNN module dependency here)
|
||||
GAPI_Assert(!out_gapi_ages.empty());
|
||||
ASSERT_EQ(out_gapi_genders.size(), out_gapi_ages.size());
|
||||
ASSERT_EQ(out_gapi_ages.size(), out_ie_ages.size());
|
||||
ASSERT_EQ(out_gapi_genders.size(), out_ie_genders.size());
|
||||
|
||||
const size_t size = out_gapi_ages.size();
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
normAssert(out_ie_ages [i], out_gapi_ages [i], "Test age output");
|
||||
normAssert(out_ie_genders[i], out_gapi_genders[i], "Test gender output");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ImportNetwork, InferList2)
|
||||
{
|
||||
const std::string device = "MYRIAD";
|
||||
skipIfDeviceNotAvailable(device);
|
||||
|
||||
initDLDTDataPath();
|
||||
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
params.model_path = compileAgeGenderBlob(device);
|
||||
params.device_id = device;
|
||||
|
||||
cv::Mat in_mat(320, 240, CV_8UC3);
|
||||
cv::randu(in_mat, 0, 255);
|
||||
std::vector<cv::Rect> roi_list = {
|
||||
cv::Rect(cv::Point{64, 60}, cv::Size{ 96, 96}),
|
||||
cv::Rect(cv::Point{50, 32}, cv::Size{128, 160}),
|
||||
};
|
||||
std::vector<cv::Mat> out_ie_ages, out_ie_genders, out_gapi_ages, out_gapi_genders;
|
||||
|
||||
// Load & run IE network
|
||||
{
|
||||
auto plugin = cv::gimpl::ie::wrap::getPlugin(params);
|
||||
auto this_network = cv::gimpl::ie::wrap::importNetwork(plugin, params);
|
||||
auto infer_request = this_network.CreateInferRequest();
|
||||
for (auto &&rc : roi_list) {
|
||||
const auto ie_rc = IE::ROI {
|
||||
0u
|
||||
, static_cast<std::size_t>(rc.x)
|
||||
, static_cast<std::size_t>(rc.y)
|
||||
, static_cast<std::size_t>(rc.width)
|
||||
, static_cast<std::size_t>(rc.height)
|
||||
};
|
||||
IE::Blob::Ptr roi_blob =
|
||||
IE::make_shared_blob(cv::gapi::ie::util::to_ie(in_mat), ie_rc);
|
||||
IE::PreProcessInfo info;
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
infer_request.SetBlob("data", roi_blob, info);
|
||||
infer_request.Infer();
|
||||
using namespace cv::gapi::ie::util;
|
||||
out_ie_ages.push_back(to_ocv(infer_request.GetBlob("age_conv3")).clone());
|
||||
out_ie_genders.push_back(to_ocv(infer_request.GetBlob("prob")).clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Configure & run G-API
|
||||
using AGInfo = std::tuple<cv::GMat, cv::GMat>;
|
||||
G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "test-age-gender");
|
||||
|
||||
cv::GArray<cv::Rect> rr;
|
||||
cv::GMat in;
|
||||
cv::GArray<cv::GMat> age, gender;
|
||||
std::tie(age, gender) = cv::gapi::infer2<AgeGender>(in, rr);
|
||||
cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
|
||||
|
||||
auto pp = cv::gapi::ie::Params<AgeGender> {
|
||||
params.model_path, params.device_id
|
||||
}.cfgOutputLayers({ "age_conv3", "prob" });
|
||||
|
||||
comp.apply(cv::gin(in_mat, roi_list), cv::gout(out_gapi_ages, out_gapi_genders),
|
||||
cv::compile_args(cv::gapi::networks(pp)));
|
||||
|
||||
// Validate with IE itself (avoid DNN module dependency here)
|
||||
GAPI_Assert(!out_gapi_ages.empty());
|
||||
ASSERT_EQ(out_gapi_genders.size(), out_gapi_ages.size());
|
||||
ASSERT_EQ(out_gapi_ages.size(), out_ie_ages.size());
|
||||
ASSERT_EQ(out_gapi_genders.size(), out_ie_genders.size());
|
||||
|
||||
const size_t size = out_gapi_ages.size();
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
normAssert(out_ie_ages [i], out_gapi_ages [i], "Test age output");
|
||||
normAssert(out_ie_genders[i], out_gapi_genders[i], "Test gender output");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ImportNetwork, InferList2NV12)
|
||||
{
|
||||
const std::string device = "MYRIAD";
|
||||
skipIfDeviceNotAvailable(device);
|
||||
|
||||
initDLDTDataPath();
|
||||
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
params.model_path = compileAgeGenderBlob(device);
|
||||
params.device_id = device;
|
||||
|
||||
cv::Size sz{320, 240};
|
||||
cv::Mat in_y_mat(sz, CV_8UC1);
|
||||
cv::randu(in_y_mat, 0, 255);
|
||||
cv::Mat in_uv_mat(sz / 2, CV_8UC2);
|
||||
cv::randu(in_uv_mat, 0, 255);
|
||||
std::vector<cv::Rect> roi_list = {
|
||||
cv::Rect(cv::Point{64, 60}, cv::Size{ 96, 96}),
|
||||
cv::Rect(cv::Point{50, 32}, cv::Size{128, 160}),
|
||||
};
|
||||
std::vector<cv::Mat> out_ie_ages, out_ie_genders, out_gapi_ages, out_gapi_genders;
|
||||
|
||||
// Load & run IE network
|
||||
{
|
||||
auto plugin = cv::gimpl::ie::wrap::getPlugin(params);
|
||||
auto this_network = cv::gimpl::ie::wrap::importNetwork(plugin, params);
|
||||
auto infer_request = this_network.CreateInferRequest();
|
||||
for (auto &&rc : roi_list) {
|
||||
const auto ie_rc = IE::ROI {
|
||||
0u
|
||||
, static_cast<std::size_t>(rc.x)
|
||||
, static_cast<std::size_t>(rc.y)
|
||||
, static_cast<std::size_t>(rc.width)
|
||||
, static_cast<std::size_t>(rc.height)
|
||||
};
|
||||
IE::Blob::Ptr roi_blob =
|
||||
IE::make_shared_blob(cv::gapi::ie::util::to_ie(in_y_mat, in_uv_mat), ie_rc);
|
||||
IE::PreProcessInfo info;
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
info.setColorFormat(IE::ColorFormat::NV12);
|
||||
infer_request.SetBlob("data", roi_blob, info);
|
||||
infer_request.Infer();
|
||||
using namespace cv::gapi::ie::util;
|
||||
out_ie_ages.push_back(to_ocv(infer_request.GetBlob("age_conv3")).clone());
|
||||
out_ie_genders.push_back(to_ocv(infer_request.GetBlob("prob")).clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Configure & run G-API
|
||||
using AGInfo = std::tuple<cv::GMat, cv::GMat>;
|
||||
G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "test-age-gender");
|
||||
|
||||
cv::GArray<cv::Rect> rr;
|
||||
cv::GFrame in;
|
||||
cv::GArray<cv::GMat> age, gender;
|
||||
std::tie(age, gender) = cv::gapi::infer2<AgeGender>(in, rr);
|
||||
cv::GComputation comp(cv::GIn(in, rr), cv::GOut(age, gender));
|
||||
|
||||
auto pp = cv::gapi::ie::Params<AgeGender> {
|
||||
params.model_path, params.device_id
|
||||
}.cfgOutputLayers({ "age_conv3", "prob" });
|
||||
|
||||
auto frame = MediaFrame::Create<TestMediaNV12>(in_y_mat, in_uv_mat);
|
||||
|
||||
comp.apply(cv::gin(frame, roi_list), cv::gout(out_gapi_ages, out_gapi_genders),
|
||||
cv::compile_args(cv::gapi::networks(pp)));
|
||||
|
||||
// Validate with IE itself (avoid DNN module dependency here)
|
||||
GAPI_Assert(!out_gapi_ages.empty());
|
||||
ASSERT_EQ(out_gapi_genders.size(), out_gapi_ages.size());
|
||||
ASSERT_EQ(out_gapi_ages.size(), out_ie_ages.size());
|
||||
ASSERT_EQ(out_gapi_genders.size(), out_ie_genders.size());
|
||||
|
||||
const size_t size = out_gapi_ages.size();
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
normAssert(out_ie_ages [i], out_gapi_ages [i], "Test age output");
|
||||
normAssert(out_ie_genders[i], out_gapi_genders[i], "Test gender output");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TestAgeGender, ThrowBlobAndInputPrecisionMismatch)
|
||||
{
|
||||
const std::string device = "MYRIAD";
|
||||
skipIfDeviceNotAvailable(device);
|
||||
|
||||
initDLDTDataPath();
|
||||
|
||||
cv::gapi::ie::detail::ParamDesc params;
|
||||
// NB: Precision for inputs is U8.
|
||||
params.model_path = compileAgeGenderBlob(device);
|
||||
params.device_id = device;
|
||||
|
||||
// Configure & run G-API
|
||||
using AGInfo = std::tuple<cv::GMat, cv::GMat>;
|
||||
G_API_NET(AgeGender, <AGInfo(cv::GMat)>, "test-age-gender");
|
||||
|
||||
cv::GMat in, age, gender;
|
||||
std::tie(age, gender) = cv::gapi::infer<AgeGender>(in);
|
||||
cv::GComputation comp(cv::GIn(in), cv::GOut(age, gender));
|
||||
|
||||
auto pp = cv::gapi::ie::Params<AgeGender> {
|
||||
params.model_path, params.device_id
|
||||
}.cfgOutputLayers({ "age_conv3", "prob" });
|
||||
|
||||
cv::Mat in_mat(320, 240, CV_32FC3);
|
||||
cv::randu(in_mat, 0, 1);
|
||||
cv::Mat gapi_age, gapi_gender;
|
||||
|
||||
// NB: Blob precision is U8, but user pass FP32 data, so exception will be thrown.
|
||||
// Now exception comes directly from IE, but since G-API has information
|
||||
// about data precision at the compile stage, consider the possibility of
|
||||
// throwing exception from there.
|
||||
EXPECT_ANY_THROW(comp.apply(cv::gin(in_mat), cv::gout(gapi_age, gapi_gender),
|
||||
cv::compile_args(cv::gapi::networks(pp))));
|
||||
}
|
||||
|
||||
} // namespace opencv_test
|
||||
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
Loading…
Reference in New Issue
Block a user