Merge pull request #15753 from dmatveev:dm/ng-5000-security_barrier-interactive_face
G-API: Introduced Security Barrier & Interactive Face Detection samples * G-API-NG/Samples: Added samples & relevant changes - Security barrier camera sample - Age/Gender/Emotions recognition sample - GIEBackend now loads CPU extension libraries - A couple of API-level workarounds added to deal with cv::Mat/Blob conversions * G-API-NG/Samples: removed HAVE_INF_ENGINE remnants
This commit is contained in:
committed by
Alexander Alekhin
parent
d9efb55d29
commit
fb5e7964b3
@@ -12,7 +12,7 @@
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
|
||||
#if INF_ENGINE_RELEASE <= 2018050000
|
||||
#if INF_ENGINE_RELEASE <= 2019010000
|
||||
# error G-API IE module supports only OpenVINO IE >= 2019 R1
|
||||
#endif
|
||||
|
||||
@@ -26,11 +26,13 @@
|
||||
#include <ade/util/chain_range.hpp>
|
||||
#include <ade/typed_graph.hpp>
|
||||
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#include <opencv2/gapi/gcommon.hpp>
|
||||
#include <opencv2/gapi/garray.hpp>
|
||||
#include <opencv2/gapi/util/any.hpp>
|
||||
#include <opencv2/gapi/gtype_traits.hpp>
|
||||
|
||||
#include <opencv2/gapi/infer.hpp>
|
||||
|
||||
#include "compiler/gobjref.hpp"
|
||||
@@ -66,6 +68,21 @@ inline std::vector<int> toCV(const IE::SizeVector &vsz) {
|
||||
return result;
|
||||
}
|
||||
|
||||
inline IE::Layout toIELayout(const std::size_t ndims) {
|
||||
static const IE::Layout lts[] = {
|
||||
IE::Layout::SCALAR,
|
||||
IE::Layout::C,
|
||||
IE::Layout::NC,
|
||||
IE::Layout::CHW,
|
||||
IE::Layout::NCHW,
|
||||
IE::Layout::NCDHW,
|
||||
};
|
||||
// FIXME: This is not really a good conversion,
|
||||
// since it may also stand for NHWC/HW/CN/NDHWC data
|
||||
CV_Assert(ndims < sizeof(lts) / sizeof(lts[0]));
|
||||
return lts[ndims];
|
||||
}
|
||||
|
||||
inline IE::Precision toIE(int depth) {
|
||||
switch (depth) {
|
||||
case CV_8U: return IE::Precision::U8;
|
||||
@@ -83,13 +100,16 @@ inline int toCV(IE::Precision prec) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline IE::TensorDesc toIE(const cv::Mat &mat) {
|
||||
inline IE::TensorDesc toIE(const cv::Mat &mat, cv::gapi::ie::TraitAs hint) {
|
||||
const auto &sz = mat.size;
|
||||
|
||||
// NB: For some reason RGB image is 2D image
|
||||
// (since channel component is not counted here).
|
||||
if (sz.dims() == 2) {
|
||||
// Note: regular 2D vectors also fall into this category
|
||||
if (sz.dims() == 2 && hint == cv::gapi::ie::TraitAs::IMAGE)
|
||||
{
|
||||
// NB: This logic is mainly taken from IE samples
|
||||
const size_t pixsz = CV_ELEM_SIZE1(mat.type());
|
||||
const size_t channels = mat.channels();
|
||||
const size_t height = mat.size().height;
|
||||
const size_t width = mat.size().width;
|
||||
@@ -98,8 +118,8 @@ inline IE::TensorDesc toIE(const cv::Mat &mat) {
|
||||
const size_t strideW = mat.step.buf[1];
|
||||
|
||||
const bool is_dense =
|
||||
strideW == channels &&
|
||||
strideH == channels * width;
|
||||
strideW == pixsz * channels &&
|
||||
strideH == strideW * width;
|
||||
|
||||
if (!is_dense)
|
||||
cv::util::throw_error(std::logic_error("Doesn't support conversion"
|
||||
@@ -110,12 +130,11 @@ inline IE::TensorDesc toIE(const cv::Mat &mat) {
|
||||
IE::Layout::NHWC);
|
||||
}
|
||||
|
||||
GAPI_Assert(sz.dims() == 4); // NB: Will relax when needed (to known use)
|
||||
return IE::TensorDesc(toIE(mat.depth()), toIE(sz), IE::Layout::NCHW);
|
||||
return IE::TensorDesc(toIE(mat.depth()), toIE(sz), toIELayout(sz.dims()));
|
||||
}
|
||||
|
||||
inline IE::Blob::Ptr wrapIE(const cv::Mat &mat) {
|
||||
const auto tDesc = toIE(mat);
|
||||
inline IE::Blob::Ptr wrapIE(const cv::Mat &mat, cv::gapi::ie::TraitAs hint) {
|
||||
const auto tDesc = toIE(mat, hint);
|
||||
switch (mat.depth()) {
|
||||
// NB: Seems there's no way to create an untyped (T-less) Blob::Ptr
|
||||
// in IE given only precision via TensorDesc. So we have to do this:
|
||||
@@ -187,15 +206,62 @@ struct IEUnit {
|
||||
}
|
||||
|
||||
// This method is [supposed to be] called at Island compilation stage
|
||||
// TODO: Move to a new OpenVINO Core API!
|
||||
cv::gimpl::ie::IECompiled compile() const {
|
||||
auto this_plugin = IE::PluginDispatcher().getPluginByDevice(params.device_id);
|
||||
|
||||
// Load extensions (taken from DNN module)
|
||||
if (params.device_id == "CPU" || params.device_id == "FPGA")
|
||||
{
|
||||
const std::string suffixes[] = { "_avx2", "_sse4", ""};
|
||||
const bool haveFeature[] = {
|
||||
cv::checkHardwareSupport(CPU_AVX2),
|
||||
cv::checkHardwareSupport(CPU_SSE4_2),
|
||||
true
|
||||
};
|
||||
std::vector<std::string> candidates;
|
||||
for (auto &&it : ade::util::zip(ade::util::toRange(suffixes),
|
||||
ade::util::toRange(haveFeature)))
|
||||
{
|
||||
std::string suffix;
|
||||
bool available = false;
|
||||
std::tie(suffix, available) = it;
|
||||
if (!available) continue;
|
||||
#ifdef _WIN32
|
||||
candidates.push_back("cpu_extension" + suffix + ".dll");
|
||||
#elif defined(__APPLE__)
|
||||
candidates.push_back("libcpu_extension" + suffix + ".so"); // built as loadable module
|
||||
candidates.push_back("libcpu_extension" + suffix + ".dylib"); // built as shared library
|
||||
#else
|
||||
candidates.push_back("libcpu_extension" + suffix + ".so");
|
||||
#endif // _WIN32
|
||||
}
|
||||
for (auto &&extlib : candidates)
|
||||
{
|
||||
try
|
||||
{
|
||||
this_plugin.AddExtension(IE::make_so_pointer<IE::IExtension>(extlib));
|
||||
CV_LOG_INFO(NULL, "DNN-IE: Loaded extension plugin: " << extlib);
|
||||
break;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "Failed to load IE extension " << extlib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto this_network = this_plugin.LoadNetwork(net, {}); // FIXME: 2nd parameter to be
|
||||
// configurable via the API
|
||||
auto this_request = this_network.CreateInferRequest();
|
||||
|
||||
// Bind const data to infer request
|
||||
for (auto &&p : params.const_inputs) {
|
||||
this_request.SetBlob(p.first, wrapIE(p.second));
|
||||
// FIXME: SetBlob is known to be inefficient,
|
||||
// it is worth to make a customizable "initializer" and pass the
|
||||
// cv::Mat-wrapped blob there to support IE's optimal "GetBlob idiom"
|
||||
// Still, constant data is to set only once.
|
||||
this_request.SetBlob(p.first, wrapIE(p.second.first, p.second.second));
|
||||
}
|
||||
|
||||
return {this_plugin, this_network, this_request};
|
||||
@@ -444,7 +510,9 @@ struct Infer: public cv::detail::KernelTag {
|
||||
// (A memory dialog comes to the picture again)
|
||||
|
||||
const cv::Mat this_mat = to_ocv(ctx.inMat(i));
|
||||
IE::Blob::Ptr this_blob = wrapIE(this_mat);
|
||||
// FIXME: By default here we trait our inputs as images.
|
||||
// May be we need to make some more intelligence here about it
|
||||
IE::Blob::Ptr this_blob = wrapIE(this_mat, cv::gapi::ie::TraitAs::IMAGE);
|
||||
iec.this_request.SetBlob(uu.params.input_names[i], this_blob);
|
||||
}
|
||||
iec.this_request.Infer();
|
||||
@@ -514,7 +582,8 @@ struct InferList: public cv::detail::KernelTag {
|
||||
|
||||
const auto& in_roi_vec = ctx.inArg<cv::detail::VectorRef>(0u).rref<cv::Rect>();
|
||||
const cv::Mat this_mat = to_ocv(ctx.inMat(1u));
|
||||
IE::Blob::Ptr this_blob = wrapIE(this_mat);
|
||||
// Since we do a ROI list inference, always assume our input buffer is image
|
||||
IE::Blob::Ptr this_blob = wrapIE(this_mat, cv::gapi::ie::TraitAs::IMAGE);
|
||||
|
||||
// FIXME: This could be done ONCE at graph compile stage!
|
||||
std::vector< std::vector<int> > cached_dims(uu.params.num_out);
|
||||
@@ -601,10 +670,11 @@ std::vector<int> cv::gapi::ie::util::to_ocv(const InferenceEngine::SizeVector &d
|
||||
}
|
||||
|
||||
InferenceEngine::Blob::Ptr cv::gapi::ie::util::to_ie(cv::Mat &blob) {
|
||||
return wrapIE(blob);
|
||||
return wrapIE(blob, cv::gapi::ie::TraitAs::IMAGE);
|
||||
}
|
||||
|
||||
#else
|
||||
#else // HAVE_INF_ENGINE
|
||||
|
||||
cv::gapi::GBackend cv::gapi::ie::backend() {
|
||||
// Still provide this symbol to avoid linking issues
|
||||
util::throw_error(std::runtime_error("G-API has been compiled without OpenVINO IE support"));
|
||||
|
||||
Reference in New Issue
Block a user