mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 23:33:05 +04:00
Merge branch 4.x
This commit is contained in:
@@ -153,10 +153,18 @@ std::ostream& operator<<(std::ostream& os, const cv::GMatDesc &desc)
|
||||
break;
|
||||
}
|
||||
|
||||
os << "C" << desc.chan;
|
||||
if (desc.planar) os << "p";
|
||||
os << " ";
|
||||
os << desc.size.width << "x" << desc.size.height;
|
||||
if (desc.isND()) {
|
||||
os << " [";
|
||||
for (size_t i = 0; i < desc.dims.size() - 1; ++i) {
|
||||
os << desc.dims[i] << "x";
|
||||
}
|
||||
os << desc.dims.back() << "]";
|
||||
} else {
|
||||
os << "C" << desc.chan;
|
||||
if (desc.planar) os << "p";
|
||||
os << " ";
|
||||
os << desc.size.width << "x" << desc.size.height;
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
@@ -227,6 +227,12 @@ inline void convertInt64ToInt32(const int64_t* src, int* dst, size_t size)
|
||||
[](int64_t el) { return static_cast<int>(el); });
|
||||
}
|
||||
|
||||
inline void convertInt32ToInt64(const int* src, int64_t* dst, size_t size)
|
||||
{
|
||||
std::transform(src, src + size, dst,
|
||||
[](int el) { return static_cast<int64_t>(el); });
|
||||
}
|
||||
|
||||
}} // cv::gimpl
|
||||
|
||||
#endif // OPENCV_GAPI_GBACKEND_HPP
|
||||
|
||||
@@ -2320,12 +2320,15 @@ GAPI_FLUID_KERNEL(GFluidSplit3, cv::gapi::core::GSplit3, false)
|
||||
|
||||
static void run(const View &src, Buffer &dst1, Buffer &dst2, Buffer &dst3)
|
||||
{
|
||||
GAPI_Assert((src.meta().depth == CV_8U) && (dst1.meta().depth == CV_8U) &&
|
||||
(dst2.meta().depth == CV_8U) && (dst3.meta().depth == CV_8U) &&
|
||||
(3 == src.meta().chan));
|
||||
|
||||
const auto *in = src.InLine<uchar>(0);
|
||||
auto *out1 = dst1.OutLine<uchar>();
|
||||
auto *out2 = dst2.OutLine<uchar>();
|
||||
auto *out3 = dst3.OutLine<uchar>();
|
||||
|
||||
GAPI_Assert(3 == src.meta().chan);
|
||||
int width = src.length();
|
||||
int w = 0;
|
||||
|
||||
@@ -2348,13 +2351,16 @@ GAPI_FLUID_KERNEL(GFluidSplit4, cv::gapi::core::GSplit4, false)
|
||||
|
||||
static void run(const View &src, Buffer &dst1, Buffer &dst2, Buffer &dst3, Buffer &dst4)
|
||||
{
|
||||
GAPI_Assert((src.meta().depth == CV_8U) && (dst1.meta().depth == CV_8U) &&
|
||||
(dst2.meta().depth == CV_8U) && (dst3.meta().depth == CV_8U) &&
|
||||
(dst4.meta().depth == CV_8U) && (4 == src.meta().chan));
|
||||
|
||||
const auto *in = src.InLine<uchar>(0);
|
||||
auto *out1 = dst1.OutLine<uchar>();
|
||||
auto *out2 = dst2.OutLine<uchar>();
|
||||
auto *out3 = dst3.OutLine<uchar>();
|
||||
auto *out4 = dst4.OutLine<uchar>();
|
||||
|
||||
GAPI_Assert(4 == src.meta().chan);
|
||||
int width = src.length();
|
||||
int w = 0;
|
||||
|
||||
@@ -2372,31 +2378,46 @@ GAPI_FLUID_KERNEL(GFluidSplit4, cv::gapi::core::GSplit4, false)
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
CV_ALWAYS_INLINE void run_merge3(Buffer& dst, const View& src1, const View& src2, const View& src3)
|
||||
{
|
||||
const auto* in1 = src1.InLine<T>(0);
|
||||
const auto* in2 = src2.InLine<T>(0);
|
||||
const auto* in3 = src3.InLine<T>(0);
|
||||
auto* out = dst.OutLine<T>();
|
||||
|
||||
int width = dst.length();
|
||||
int w = 0;
|
||||
|
||||
#if CV_SIMD
|
||||
w = merge3_simd(in1, in2, in3, out, width);
|
||||
#endif
|
||||
|
||||
for (; w < width; w++)
|
||||
{
|
||||
out[3 * w] = in1[w];
|
||||
out[3 * w + 1] = in2[w];
|
||||
out[3 * w + 2] = in3[w];
|
||||
}
|
||||
}
|
||||
|
||||
GAPI_FLUID_KERNEL(GFluidMerge3, cv::gapi::core::GMerge3, false)
|
||||
{
|
||||
static const int Window = 1;
|
||||
|
||||
static void run(const View &src1, const View &src2, const View &src3, Buffer &dst)
|
||||
static void run(const View& src1, const View& src2, const View& src3, Buffer& dst)
|
||||
{
|
||||
const auto *in1 = src1.InLine<uchar>(0);
|
||||
const auto *in2 = src2.InLine<uchar>(0);
|
||||
const auto *in3 = src3.InLine<uchar>(0);
|
||||
auto *out = dst.OutLine<uchar>();
|
||||
GAPI_Assert((src1.meta().depth == dst.meta().depth) &&
|
||||
(src1.meta().depth == src2.meta().depth) &&
|
||||
(src1.meta().depth == src3.meta().depth));
|
||||
|
||||
GAPI_Assert(3 == dst.meta().chan);
|
||||
int width = dst.length();
|
||||
int w = 0;
|
||||
// SRC/DST TYPE OP __VA_ARGS__
|
||||
MERGE3_(uchar, run_merge3, dst, src1, src2, src3);
|
||||
MERGE3_(ushort, run_merge3, dst, src1, src2, src3);
|
||||
MERGE3_(short, run_merge3, dst, src1, src2, src3);
|
||||
MERGE3_(float, run_merge3, dst, src1, src2, src3);
|
||||
|
||||
#if CV_SIMD
|
||||
w = merge3_simd(in1, in2, in3, out, width);
|
||||
#endif
|
||||
|
||||
for (; w < width; w++)
|
||||
{
|
||||
out[3*w ] = in1[w];
|
||||
out[3*w + 1] = in2[w];
|
||||
out[3*w + 2] = in3[w];
|
||||
}
|
||||
CV_Error(cv::Error::StsBadArg, "unsupported combination of types");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2407,13 +2428,16 @@ GAPI_FLUID_KERNEL(GFluidMerge4, cv::gapi::core::GMerge4, false)
|
||||
static void run(const View &src1, const View &src2, const View &src3, const View &src4,
|
||||
Buffer &dst)
|
||||
{
|
||||
GAPI_Assert((dst.meta().depth == CV_8U) && (src1.meta().depth == CV_8U) &&
|
||||
(src2.meta().depth == CV_8U) && (src3.meta().depth == CV_8U) &&
|
||||
(4 == dst.meta().chan));
|
||||
|
||||
const auto *in1 = src1.InLine<uchar>(0);
|
||||
const auto *in2 = src2.InLine<uchar>(0);
|
||||
const auto *in3 = src3.InLine<uchar>(0);
|
||||
const auto *in4 = src4.InLine<uchar>(0);
|
||||
auto *out = dst.OutLine<uchar>();
|
||||
|
||||
GAPI_Assert(4 == dst.meta().chan);
|
||||
int width = dst.length();
|
||||
|
||||
int w = 0; // cycle counter
|
||||
|
||||
@@ -277,13 +277,21 @@ int split4_simd(const uchar in[], uchar out1[], uchar out2[],
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
|
||||
int merge3_simd(const uchar in1[], const uchar in2[], const uchar in3[],
|
||||
uchar out[], const int width)
|
||||
{
|
||||
CV_CPU_DISPATCH(merge3_simd, (in1, in2, in3, out, width),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
#define MERGE3_SIMD(T) \
|
||||
int merge3_simd(const T in1[], const T in2[], const T in3[], \
|
||||
T out[], const int width) \
|
||||
{ \
|
||||
CV_CPU_DISPATCH(merge3_simd, (in1, in2, in3, out, width), \
|
||||
CV_CPU_DISPATCH_MODES_ALL); \
|
||||
}
|
||||
|
||||
MERGE3_SIMD(uchar)
|
||||
MERGE3_SIMD(short)
|
||||
MERGE3_SIMD(ushort)
|
||||
MERGE3_SIMD(float)
|
||||
|
||||
#undef MERGE3_SIMD
|
||||
|
||||
int merge4_simd(const uchar in1[], const uchar in2[], const uchar in3[],
|
||||
const uchar in4[], uchar out[], const int width)
|
||||
{
|
||||
|
||||
@@ -216,8 +216,16 @@ int split3_simd(const uchar in[], uchar out1[], uchar out2[],
|
||||
int split4_simd(const uchar in[], uchar out1[], uchar out2[],
|
||||
uchar out3[], uchar out4[], const int width);
|
||||
|
||||
int merge3_simd(const uchar in1[], const uchar in2[], const uchar in3[],
|
||||
uchar out[], const int width);
|
||||
#define MERGE3_SIMD(T) \
|
||||
int merge3_simd(const T in1[], const T in2[], const T in3[], \
|
||||
T out[], const int width);
|
||||
|
||||
MERGE3_SIMD(uchar)
|
||||
MERGE3_SIMD(short)
|
||||
MERGE3_SIMD(ushort)
|
||||
MERGE3_SIMD(float)
|
||||
|
||||
#undef MERGE3_SIMD
|
||||
|
||||
int merge4_simd(const uchar in1[], const uchar in2[], const uchar in3[],
|
||||
const uchar in4[], uchar out[], const int width);
|
||||
|
||||
@@ -322,12 +322,21 @@ int split3_simd(const uchar in[], uchar out1[], uchar out2[],
|
||||
int split4_simd(const uchar in[], uchar out1[], uchar out2[],
|
||||
uchar out3[], uchar out4[], const int width);
|
||||
|
||||
int merge3_simd(const uchar in1[], const uchar in2[], const uchar in3[],
|
||||
uchar out[], const int width);
|
||||
#define MERGE3_SIMD(T) \
|
||||
int merge3_simd(const T in1[], const T in2[], const T in3[], \
|
||||
T out[], const int width);
|
||||
|
||||
MERGE3_SIMD(uchar)
|
||||
MERGE3_SIMD(short)
|
||||
MERGE3_SIMD(ushort)
|
||||
MERGE3_SIMD(float)
|
||||
|
||||
#undef MERGE3_SIMD
|
||||
|
||||
int merge4_simd(const uchar in1[], const uchar in2[], const uchar in3[],
|
||||
const uchar in4[], uchar out[], const int width);
|
||||
|
||||
|
||||
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
|
||||
|
||||
#define SRC_SHORT_OR_USHORT std::is_same<SRC, short>::value || std::is_same<SRC, ushort>::value
|
||||
@@ -2530,34 +2539,42 @@ int split4_simd(const uchar in[], uchar out1[], uchar out2[],
|
||||
//
|
||||
//-------------------------
|
||||
|
||||
int merge3_simd(const uchar in1[], const uchar in2[], const uchar in3[],
|
||||
uchar out[], const int width)
|
||||
{
|
||||
constexpr int nlanes = v_uint8::nlanes;
|
||||
if (width < nlanes)
|
||||
return 0;
|
||||
|
||||
int x = 0;
|
||||
for (;;)
|
||||
{
|
||||
for (; x <= width - nlanes; x += nlanes)
|
||||
{
|
||||
v_uint8 a, b, c;
|
||||
a = vx_load(&in1[x]);
|
||||
b = vx_load(&in2[x]);
|
||||
c = vx_load(&in3[x]);
|
||||
v_store_interleave(&out[3 * x], a, b, c);
|
||||
}
|
||||
if (x < width)
|
||||
{
|
||||
x = width - nlanes;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return x;
|
||||
#define MERGE3_SIMD(T) \
|
||||
int merge3_simd(const T in1[], const T in2[], const T in3[], \
|
||||
T out[], const int width) \
|
||||
{ \
|
||||
constexpr int nlanes = vector_type_of_t<T>::nlanes; \
|
||||
if (width < nlanes) \
|
||||
return 0; \
|
||||
\
|
||||
int x = 0; \
|
||||
for (;;) \
|
||||
{ \
|
||||
for (; x <= width - nlanes; x += nlanes) \
|
||||
{ \
|
||||
vector_type_of_t<T> a, b, c; \
|
||||
a = vx_load(&in1[x]); \
|
||||
b = vx_load(&in2[x]); \
|
||||
c = vx_load(&in3[x]); \
|
||||
v_store_interleave(&out[3 * x], a, b, c); \
|
||||
} \
|
||||
if (x < width) \
|
||||
{ \
|
||||
x = width - nlanes; \
|
||||
continue; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
return x; \
|
||||
}
|
||||
|
||||
MERGE3_SIMD(uchar)
|
||||
MERGE3_SIMD(short)
|
||||
MERGE3_SIMD(ushort)
|
||||
MERGE3_SIMD(float)
|
||||
|
||||
#undef MERGE3_SIMD
|
||||
|
||||
//-------------------------
|
||||
//
|
||||
// Fluid kernels: Merge4
|
||||
@@ -2926,6 +2943,8 @@ CV_ALWAYS_INLINE void convertto_simd_nocoeff_impl(const SRC* inx, float* outx)
|
||||
int convertto_simd(const SRC in[], DST out[], const int length) \
|
||||
{ \
|
||||
constexpr int nlanes = vector_type_of_t<DST>::nlanes; \
|
||||
if (length < nlanes) \
|
||||
return 0; \
|
||||
\
|
||||
int x = 0; \
|
||||
for (;;) \
|
||||
@@ -3093,6 +3112,9 @@ int convertto_scaled_simd(const SRC in[], DST out[], const float alpha, \
|
||||
const float beta, const int length) \
|
||||
{ \
|
||||
constexpr int nlanes = vector_type_of_t<DST>::nlanes; \
|
||||
if (length < nlanes) \
|
||||
return 0; \
|
||||
\
|
||||
v_float32 v_alpha = vx_setall_f32(alpha); \
|
||||
v_float32 v_beta = vx_setall_f32(beta); \
|
||||
\
|
||||
|
||||
@@ -86,6 +86,23 @@ using cv::gapi::own::rintd;
|
||||
return; \
|
||||
}
|
||||
|
||||
#define MERGE3_(T, OP, ...) \
|
||||
if (cv::DataType<T>::depth == dst.meta().depth && \
|
||||
cv::DataType<T>::depth == src1.meta().depth) \
|
||||
{ \
|
||||
GAPI_DbgAssert(dst.length() == src1.length()); \
|
||||
GAPI_DbgAssert(dst.length() == src2.length()); \
|
||||
GAPI_DbgAssert(dst.length() == src3.length()); \
|
||||
\
|
||||
GAPI_DbgAssert(1 == src1.meta().chan); \
|
||||
GAPI_DbgAssert(1 == src2.meta().chan); \
|
||||
GAPI_DbgAssert(1 == src3.meta().chan); \
|
||||
GAPI_DbgAssert(3 == dst.meta().chan); \
|
||||
\
|
||||
OP<T>(__VA_ARGS__); \
|
||||
return; \
|
||||
}
|
||||
|
||||
} // namespace fluid
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
|
||||
@@ -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) 2018-2022 Intel Corporation
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
@@ -71,6 +71,28 @@ namespace IE = InferenceEngine;
|
||||
|
||||
namespace {
|
||||
|
||||
IE::Layout toIE(const std::string &layout) {
|
||||
const std::unordered_map<std::string, IE::Layout> layouts = {
|
||||
{"NCDHW", IE::Layout::NCDHW},
|
||||
{"NDHWC", IE::Layout::NDHWC},
|
||||
{"NHWC" , IE::Layout::NHWC },
|
||||
{"NCHW" , IE::Layout::NCHW },
|
||||
{"CHW" , IE::Layout::CHW },
|
||||
{"HWC" , IE::Layout::HWC },
|
||||
{"HW" , IE::Layout::HW },
|
||||
{"NC" , IE::Layout::NC },
|
||||
{"CN" , IE::Layout::CN },
|
||||
{"C" , IE::Layout::C },
|
||||
};
|
||||
|
||||
const auto it = layouts.find(layout);
|
||||
if (it == layouts.end()) {
|
||||
cv::util::throw_error(
|
||||
std::logic_error("IE Backend: Unsupported layout: " + layout));
|
||||
}
|
||||
return it->second;
|
||||
};
|
||||
|
||||
inline IE::ROI toIE(const cv::Rect &rc) {
|
||||
return IE::ROI
|
||||
{ 0u
|
||||
@@ -130,11 +152,90 @@ inline int toCV(IE::Precision prec) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline IE::ResizeAlgorithm toIEInterp(int interpolation) {
|
||||
switch (interpolation) {
|
||||
case cv::INTER_LINEAR: return IE::RESIZE_BILINEAR;
|
||||
case cv::INTER_AREA: return IE::RESIZE_AREA;
|
||||
default: GAPI_Error("IE Backend: Unsupported resize algorithm");
|
||||
}
|
||||
// Unreachable code
|
||||
GAPI_Assert(false);
|
||||
}
|
||||
|
||||
template <typename Attr>
|
||||
using AttrMap = cv::gapi::ie::detail::AttrMap<Attr>;
|
||||
|
||||
template <typename Attr>
|
||||
using LayerVariantAttr = cv::gapi::ie::detail::LayerVariantAttr<Attr>;
|
||||
|
||||
template <typename Attr> AttrMap<Attr>
|
||||
broadcastLayerAttr(const LayerVariantAttr<Attr> &layer_attr,
|
||||
const std::vector<std::string> &layer_names) {
|
||||
AttrMap<Attr> map;
|
||||
if (cv::util::holds_alternative<AttrMap<Attr>>(layer_attr)) {
|
||||
map = cv::util::get<AttrMap<Attr>>(layer_attr);
|
||||
// NB: Validate map:
|
||||
std::unordered_set<std::string> existing_layers =
|
||||
{layer_names.begin(), layer_names.end()};
|
||||
|
||||
for (const auto &p : map) {
|
||||
const auto it = existing_layers.find(p.first);
|
||||
if (it == existing_layers.end()) {
|
||||
cv::util::throw_error(
|
||||
std::logic_error("IE Backend: Failed to"
|
||||
" find layer with name: " + p.first));
|
||||
}
|
||||
}
|
||||
} else if (cv::util::holds_alternative<Attr>(layer_attr)) {
|
||||
// NB: Broadcast value to all layers.
|
||||
auto elem = cv::util::get<Attr>(layer_attr);
|
||||
for (auto &&layer_name : layer_names) {
|
||||
map.emplace(layer_name, elem);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// TODO: Move it to some common place
|
||||
template <typename K, typename V>
|
||||
cv::optional<V> lookUp(const std::map<K, V> &map, const K& key) {
|
||||
const auto it = map.find(key);
|
||||
if (it == map.end()) {
|
||||
return {};
|
||||
}
|
||||
return cv::util::make_optional(std::move(it->second));
|
||||
}
|
||||
|
||||
static bool isImage(const cv::GMatDesc &desc,
|
||||
const IE::SizeVector &model_dims) {
|
||||
return (model_dims.size() == 4u) &&
|
||||
(!desc.isND()) /* dims == 2 */ &&
|
||||
(desc.chan == 1 || desc.chan == 3) &&
|
||||
(desc.size.height != 1 && desc.size.width != 1) &&
|
||||
(desc.depth == CV_8U);
|
||||
}
|
||||
|
||||
cv::gapi::ie::TraitAs clarifyTrait(const cv::GMatDesc &mat_desc,
|
||||
const IE::SizeVector &model_dims) {
|
||||
if (isImage(mat_desc, model_dims)) {
|
||||
return cv::gapi::ie::TraitAs::IMAGE;
|
||||
}
|
||||
return cv::gapi::ie::TraitAs::TENSOR;
|
||||
}
|
||||
|
||||
cv::gapi::ie::TraitAs clarifyTrait(const cv::GMetaArg &meta,
|
||||
const IE::SizeVector &model_dims) {
|
||||
// NB: All media formats: BGR, NV12, Gray
|
||||
// are traited as image.
|
||||
if (cv::util::holds_alternative<cv::GFrameDesc>(meta)) {
|
||||
return cv::gapi::ie::TraitAs::IMAGE;
|
||||
}
|
||||
GAPI_Assert(cv::util::holds_alternative<cv::GMatDesc>(meta));
|
||||
return clarifyTrait(cv::util::get<cv::GMatDesc>(meta), model_dims);
|
||||
}
|
||||
|
||||
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).
|
||||
// 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
|
||||
@@ -155,8 +256,72 @@ inline IE::TensorDesc toIE(const cv::Mat &mat, cv::gapi::ie::TraitAs hint) {
|
||||
return IE::TensorDesc(toIE(mat.depth()), toIE(sz), toIELayout(sz.dims()));
|
||||
}
|
||||
|
||||
inline IE::Blob::Ptr wrapIE(const cv::Mat &mat, cv::gapi::ie::TraitAs hint) {
|
||||
const auto tDesc = toIE(mat, hint);
|
||||
// NB: Inference dimmensions always follow NCDHW order
|
||||
// even though the real layout is different.
|
||||
// E.g if user provided Mat({1, 240, 320, 3}, CV_8U) + NHWC layout
|
||||
// need to create Blob(U8, {1, 3, 240, 320}, NHWC).
|
||||
inline IE::SizeVector toIEDims(const IE::SizeVector &dims,
|
||||
const IE::Layout layout) {
|
||||
switch (layout) {
|
||||
case IE::Layout::NDHWC: // NCDHW
|
||||
return {dims[0], dims[4], dims[1], dims[2], dims[3]};
|
||||
case IE::Layout::NHWC: // NCHW
|
||||
return {dims[0], dims[3], dims[1], dims[2]};
|
||||
case IE::Layout::HWC: // CHW
|
||||
return {dims[2], dims[0], dims[1]};
|
||||
default: return dims;
|
||||
}
|
||||
GAPI_Assert(false);
|
||||
}
|
||||
|
||||
// NB: Inference dimmensions always follow NCDHW order
|
||||
// even though the real layout is different.
|
||||
// E.g if U8 blob has {1, 3, 240, 320} dims and NHWC layout
|
||||
// need to create cv::Mat({1, 240, 320, 3}, CV_8U);
|
||||
inline std::vector<int> toCVDims(const std::vector<int> &dims,
|
||||
const IE::Layout layout) {
|
||||
switch (layout) {
|
||||
case IE::Layout::NDHWC: // NCDHW
|
||||
return {dims[0], dims[2], dims[3], dims[4], dims[1]};
|
||||
case IE::Layout::NHWC: // NCHW
|
||||
return {dims[0], dims[2], dims[3], dims[1]};
|
||||
case IE::Layout::HWC: // CHW
|
||||
return {dims[1], dims[2], dims[0]};
|
||||
default: return dims;
|
||||
}
|
||||
GAPI_Assert(false);
|
||||
}
|
||||
|
||||
inline IE::TensorDesc toIE(const cv::Mat &mat,
|
||||
const cv::gapi::ie::TraitAs hint,
|
||||
const IE::Layout layout) {
|
||||
const auto &sz = mat.size;
|
||||
if (sz.dims() == 2 && hint == cv::gapi::ie::TraitAs::IMAGE)
|
||||
{
|
||||
// NB: This logic is mainly taken from IE samples
|
||||
const size_t channels = mat.channels();
|
||||
const size_t height = mat.size().height;
|
||||
const size_t width = mat.size().width;
|
||||
|
||||
const size_t strideH = mat.step1();
|
||||
IE::BlockingDesc bdesc({1, height, width, channels} /* blocking dims */,
|
||||
{0, 2, 3, 1} /* order for NHWC */,
|
||||
0 /* offset */,
|
||||
{0, 0, 0, 0} /* offsets for dims */,
|
||||
{strideH * height, strideH, channels, 1} /* strides for dims */);
|
||||
|
||||
return IE::TensorDesc(toIE(mat.depth()),
|
||||
IE::SizeVector{1, channels, height, width}, bdesc);
|
||||
}
|
||||
return IE::TensorDesc(toIE(mat.depth()),
|
||||
toIEDims(toIE(sz), layout),
|
||||
layout);
|
||||
}
|
||||
|
||||
inline IE::Blob::Ptr wrapIE(const cv::Mat &mat,
|
||||
cv::gapi::ie::TraitAs hint,
|
||||
const IE::Layout layout = IE::Layout::ANY) {
|
||||
const auto tDesc = toIE(mat, hint, layout);
|
||||
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:
|
||||
@@ -303,6 +468,7 @@ struct IEUnit {
|
||||
};
|
||||
|
||||
InputFramesDesc net_input_params;
|
||||
std::unordered_map<std::string, cv::gapi::ie::TraitAs> inputs_type;
|
||||
|
||||
explicit IEUnit(const cv::gapi::ie::detail::ParamDesc &pp)
|
||||
: params(pp) {
|
||||
@@ -481,6 +647,8 @@ public:
|
||||
cv::GRunArgP output (std::size_t idx);
|
||||
cv::Mat& outMatR(std::size_t idx);
|
||||
|
||||
cv::gapi::ie::TraitAs getInputType(const std::string &layer_name) const;
|
||||
|
||||
const IEUnit &uu;
|
||||
cv::gimpl::GIslandExecutable::IOutput &out;
|
||||
|
||||
@@ -524,6 +692,9 @@ private:
|
||||
// keep alive preprocessed frames
|
||||
std::mutex keep_alive_frames_mutex;
|
||||
std::unordered_map<req_key_t, cv::MediaFrame> keep_alive_pp_frames;
|
||||
|
||||
// NB: Hint to wrap input data properly into IE::Blob (see: wrapIE)
|
||||
std::unordered_map<std::string, cv::gapi::ie::TraitAs> input_type;
|
||||
};
|
||||
|
||||
IECallContext::IECallContext(const IEUnit & unit,
|
||||
@@ -558,6 +729,16 @@ IECallContext::IECallContext(const IEUnit &
|
||||
}
|
||||
}
|
||||
|
||||
cv::gapi::ie::TraitAs
|
||||
IECallContext::getInputType(const std::string &layer_name) const {
|
||||
const auto it = uu.inputs_type.find(layer_name);
|
||||
if (it == uu.inputs_type.end()) {
|
||||
cv::util::throw_error(std::logic_error(
|
||||
"Failed to find input type for layer: \"" + layer_name + "\""));
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const cv::GArgs& IECallContext::inArgs() const {
|
||||
return m_args;
|
||||
}
|
||||
@@ -732,7 +913,8 @@ cv::MediaFrame preprocess_frame_impl(cv::MediaFrame &&in_frame, const std::strin
|
||||
|
||||
inline IE::Blob::Ptr extractBlob(IECallContext& ctx,
|
||||
std::size_t i,
|
||||
cv::gapi::ie::TraitAs hint,
|
||||
const cv::gapi::ie::TraitAs hint,
|
||||
const IE::Layout &layout,
|
||||
const std::string& layer_name,
|
||||
const cv::util::optional<cv::Rect> &opt_roi,
|
||||
cv::MediaFrame* out_keep_alive_frame = nullptr,
|
||||
@@ -780,7 +962,7 @@ inline IE::Blob::Ptr extractBlob(IECallContext& ctx,
|
||||
return wrapIE(*(ctx.views.back()), frame.desc());
|
||||
}
|
||||
case cv::GShape::GMAT: {
|
||||
return wrapIE(ctx.inMat(i), hint);
|
||||
return wrapIE(ctx.inMat(i), hint, layout);
|
||||
}
|
||||
default:
|
||||
GAPI_Assert("Unsupported input shape for IE backend");
|
||||
@@ -788,7 +970,6 @@ inline IE::Blob::Ptr extractBlob(IECallContext& ctx,
|
||||
GAPI_Error("InternalError");
|
||||
}
|
||||
|
||||
|
||||
static void setBlob(InferenceEngine::InferRequest& req,
|
||||
const std::string& layer_name,
|
||||
const IE::Blob::Ptr& blob,
|
||||
@@ -1162,55 +1343,109 @@ static void configureInputReshapeByImage(const IE::InputInfo::Ptr& ii,
|
||||
input_reshape_table.emplace(layer_name, input_dims);
|
||||
}
|
||||
|
||||
static void configureInputInfo(const IE::InputInfo::Ptr& ii, const cv::GMetaArg mm) {
|
||||
static void cfgInputPrecision(const IE::InputInfo::Ptr& ii, const cv::GMetaArg mm) {
|
||||
switch (mm.index()) {
|
||||
case cv::GMetaArg::index_of<cv::GMatDesc>():
|
||||
{
|
||||
ii->setPrecision(toIE(util::get<cv::GMatDesc>(mm).depth));
|
||||
case cv::GMetaArg::index_of<cv::GMatDesc>(): {
|
||||
const auto &desc = util::get<cv::GMatDesc>(mm);
|
||||
ii->setPrecision(toIE(desc.depth));
|
||||
break;
|
||||
}
|
||||
case cv::GMetaArg::index_of<cv::GFrameDesc>():
|
||||
{
|
||||
const auto &meta = util::get<cv::GFrameDesc>(mm);
|
||||
switch (meta.fmt) {
|
||||
case cv::MediaFormat::NV12:
|
||||
ii->getPreProcess().setColorFormat(IE::ColorFormat::NV12);
|
||||
break;
|
||||
case cv::MediaFormat::BGR:
|
||||
// NB: Do nothing
|
||||
break;
|
||||
case cv::MediaFormat::GRAY:
|
||||
// NB: Do nothing
|
||||
break;
|
||||
default:
|
||||
GAPI_Error("Unsupported media format for IE backend");
|
||||
}
|
||||
ii->setPrecision(toIE(CV_8U));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
util::throw_error(std::runtime_error("Unsupported input meta for IE backend"));
|
||||
}
|
||||
}
|
||||
|
||||
static bool isApplicableForResize(const IE::TensorDesc& desc) {
|
||||
const auto layout = desc.getLayout();
|
||||
const auto prec = desc.getPrecision();
|
||||
return (layout == IE::Layout::NCHW || layout == IE::Layout::NHWC) &&
|
||||
(prec == IE::Precision::FP32 || prec == IE::Precision::U8);
|
||||
static void cfgImagePreprocessing(const IE::InputInfo::Ptr &ii,
|
||||
const cv::GMetaArg &mm,
|
||||
const IE::ResizeAlgorithm interp) {
|
||||
if (!cv::util::holds_alternative<cv::GMatDesc>(mm) &&
|
||||
!cv::util::holds_alternative<cv::GFrameDesc>(mm)) {
|
||||
util::throw_error(std::runtime_error("Unsupported input meta for IE backend"));
|
||||
}
|
||||
|
||||
ii->getPreProcess().setResizeAlgorithm(interp);
|
||||
if (cv::util::holds_alternative<cv::GFrameDesc>(mm)) {
|
||||
const auto &meta = util::get<cv::GFrameDesc>(mm);
|
||||
if (meta.fmt == cv::MediaFormat::NV12) {
|
||||
ii->getPreProcess().setColorFormat(IE::ColorFormat::NV12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static IE::PreProcessInfo configurePreProcInfo(const IE::InputInfo::CPtr& ii,
|
||||
const cv::GMetaArg& mm) {
|
||||
// NB: This function is used in order to configure
|
||||
// preprocessing for "Load" case networks.
|
||||
static void cfgInputPreprocessing(const cv::gapi::ie::TraitAs trait,
|
||||
const IE::InputInfo::Ptr &ii,
|
||||
const cv::GMetaArg &mm,
|
||||
const std::string &layer_name,
|
||||
const AttrMap<std::string> &layout_map,
|
||||
const AttrMap<int> &interp_map) {
|
||||
cfgInputPrecision(ii, mm);
|
||||
const auto explicit_input_layout = lookUp(layout_map, layer_name);
|
||||
const auto explicit_resize = lookUp(interp_map, layer_name);
|
||||
if (trait == cv::gapi::ie::TraitAs::IMAGE) {
|
||||
// NB: Image case - preprocessing is configured automatically.
|
||||
GAPI_LOG_DEBUG(NULL, "IE Backend: Input: \"" <<
|
||||
layer_name << " " << mm << "\" is image.");
|
||||
// NB: BlockingDesc is used instead (see wrapIE)
|
||||
if (explicit_input_layout) {
|
||||
util::throw_error(std::logic_error("Input data provided for layer: \"" +
|
||||
layer_name + "\" is recognized as \"image\". Explicitly" +
|
||||
" specified layout is prohibited."));
|
||||
}
|
||||
const auto interp = explicit_resize ? toIEInterp(*explicit_resize)
|
||||
: IE::RESIZE_BILINEAR;
|
||||
cfgImagePreprocessing(ii, mm, interp);
|
||||
} else {
|
||||
// NB: Tensor case - preprocessing is configured only if user asked.
|
||||
GAPI_LOG_DEBUG(NULL, "IE Backend: Input: \"" <<
|
||||
layer_name << "\" " << mm << " is tensor.");
|
||||
if (explicit_input_layout) {
|
||||
GAPI_LOG_DEBUG(NULL, "IE Backend: Set input layout \"" <<
|
||||
*explicit_input_layout << "\" for layer \"" << layer_name << "\"");
|
||||
ii->setLayout(toIE(*explicit_input_layout));
|
||||
}
|
||||
if (explicit_resize) {
|
||||
GAPI_LOG_DEBUG(NULL, "IE Backend: Set resize for layer \"" << layer_name << "\"");
|
||||
ii->getPreProcess().setResizeAlgorithm(toIEInterp(*explicit_resize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static IE::PreProcessInfo createImagePreProcInfo(const cv::GMetaArg &mm,
|
||||
const IE::ResizeAlgorithm interp) {
|
||||
if (!cv::util::holds_alternative<cv::GMatDesc>(mm) &&
|
||||
!cv::util::holds_alternative<cv::GFrameDesc>(mm)) {
|
||||
util::throw_error(std::runtime_error("Unsupported input meta for IE backend"));
|
||||
}
|
||||
IE::PreProcessInfo info;
|
||||
info.setResizeAlgorithm(interp);
|
||||
if (cv::util::holds_alternative<cv::GFrameDesc>(mm)) {
|
||||
auto desc = cv::util::get<cv::GFrameDesc>(mm);
|
||||
if (desc.fmt == cv::MediaFormat::NV12) {
|
||||
const auto &meta = util::get<cv::GFrameDesc>(mm);
|
||||
if (meta.fmt == cv::MediaFormat::NV12) {
|
||||
info.setColorFormat(IE::ColorFormat::NV12);
|
||||
}
|
||||
}
|
||||
if (isApplicableForResize(ii->getTensorDesc())) {
|
||||
info.setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
return info;
|
||||
}
|
||||
|
||||
// NB: This function is used in order to create
|
||||
// preprocessing for "Import" case networks.
|
||||
static IE::PreProcessInfo createPreProcInfo(const cv::gapi::ie::TraitAs trait,
|
||||
const cv::GMetaArg& mm,
|
||||
const cv::optional<int> explicit_resize) {
|
||||
if (trait == cv::gapi::ie::TraitAs::IMAGE) {
|
||||
const auto interp = explicit_resize ? toIEInterp(*explicit_resize)
|
||||
: IE::RESIZE_BILINEAR;
|
||||
return createImagePreProcInfo(mm, interp);
|
||||
}
|
||||
// NB: In case "tensor" only resize can't be spefied for "import" models.
|
||||
IE::PreProcessInfo info;
|
||||
if (explicit_resize) {
|
||||
info.setResizeAlgorithm(toIEInterp(*explicit_resize));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
@@ -1237,6 +1472,13 @@ static void configureOutputPrecision(const IE::OutputsDataMap &outputs
|
||||
);
|
||||
}
|
||||
|
||||
static void configureOutputLayout(const IE::OutputsDataMap &outputs_info,
|
||||
const AttrMap<std::string> &output_layout) {
|
||||
for (const auto it : output_layout) {
|
||||
outputs_info.at(it.first)->setLayout(toIE(it.second));
|
||||
}
|
||||
}
|
||||
|
||||
// NB: This is a callback used by async infer
|
||||
// to post outputs blobs (cv::GMat's).
|
||||
static void PostOutputs(InferenceEngine::InferRequest &request,
|
||||
@@ -1356,6 +1598,10 @@ struct Infer: public cv::detail::KernelTag {
|
||||
GAPI_Assert(uu.params.input_names.size() == in_metas.size()
|
||||
&& "Known input layers count doesn't match input meta count");
|
||||
|
||||
const auto input_layout = broadcastLayerAttr(uu.params.input_layout,
|
||||
uu.params.input_names);
|
||||
const auto interpolation = broadcastLayerAttr(uu.params.interpolation,
|
||||
uu.params.input_names);
|
||||
// NB: Configuring input/output precision and network reshape must be done
|
||||
// only in the loadNetwork case.
|
||||
using namespace cv::gapi::ie::detail;
|
||||
@@ -1365,25 +1611,24 @@ struct Infer: public cv::detail::KernelTag {
|
||||
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);
|
||||
const auto &mm = std::get<1>(it);
|
||||
|
||||
configureInputInfo(ii, mm);
|
||||
if (uu.params.layer_names_to_reshape.find(input_name) !=
|
||||
uu.params.layer_names_to_reshape.end()) {
|
||||
configureInputReshapeByImage(ii, mm, input_reshape_table);
|
||||
}
|
||||
|
||||
if (isApplicableForResize(ii->getTensorDesc())) {
|
||||
ii->getPreProcess().setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
}
|
||||
|
||||
const auto trait = clarifyTrait(mm, ii->getTensorDesc().getDims());
|
||||
// FIXME: This is the only place where information about input type
|
||||
// can be stored for the futher execution.
|
||||
const_cast<IEUnit&>(uu).inputs_type.emplace(input_name, trait);
|
||||
cfgInputPreprocessing(trait, ii, mm, input_name,
|
||||
input_layout, interpolation);
|
||||
// NB: configure input param for further preproc
|
||||
if (uu.net_input_params.is_applicable(mm)) {
|
||||
const_cast<IEUnit::InputFramesDesc &>(uu.net_input_params)
|
||||
.set_param(input_name, ii->getTensorDesc());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &&p : uu.params.const_inputs) {
|
||||
const auto ii = inputs.at(p.first);
|
||||
ii->setPrecision(toIE(p.second.first.depth()));
|
||||
@@ -1395,6 +1640,10 @@ struct Infer: public cv::detail::KernelTag {
|
||||
if (!input_reshape_table.empty()) {
|
||||
const_cast<IE::CNNNetwork *>(&uu.net)->reshape(input_reshape_table);
|
||||
}
|
||||
|
||||
const auto output_layout = broadcastLayerAttr(uu.params.output_layout,
|
||||
uu.params.output_names);
|
||||
configureOutputLayout(uu.net.getOutputsInfo(), output_layout);
|
||||
configureOutputPrecision(uu.net.getOutputsInfo(), uu.params.output_precision);
|
||||
} else {
|
||||
GAPI_Assert(uu.params.kind == ParamDesc::Kind::Import);
|
||||
@@ -1406,7 +1655,13 @@ struct Infer: public cv::detail::KernelTag {
|
||||
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));
|
||||
const auto trait = clarifyTrait(mm, ii->getTensorDesc().getDims());
|
||||
// FIXME: This is the only place where information about input type
|
||||
// can be stored for the futher execution.
|
||||
const_cast<IEUnit&>(uu).inputs_type.emplace(input_name, trait);
|
||||
const auto explicit_resize = lookUp(interpolation, input_name);
|
||||
non_const_prepm->emplace(
|
||||
input_name, createPreProcInfo(trait, mm, explicit_resize));
|
||||
|
||||
// NB: configure input param for further preproc
|
||||
if (uu.net_input_params.is_applicable(mm)) {
|
||||
@@ -1428,7 +1683,7 @@ struct Infer: public cv::detail::KernelTag {
|
||||
: uu.this_network.GetOutputsInfo().at(out_name)->getTensorDesc();
|
||||
|
||||
cv::GMatDesc outm(toCV(desc.getPrecision()),
|
||||
toCV(desc.getDims()));
|
||||
toCVDims(toCV(desc.getDims()), desc.getLayout()));
|
||||
result.emplace_back(outm);
|
||||
}
|
||||
return result;
|
||||
@@ -1444,15 +1699,10 @@ struct Infer: public cv::detail::KernelTag {
|
||||
// - assumes all inputs/outputs are always Mats
|
||||
for (auto i : ade::util::iota(ctx->uu.params.num_in)) {
|
||||
const auto& layer_name = ctx->uu.params.input_names[i];
|
||||
auto layout =
|
||||
ctx->uu.this_network.GetInputsInfo().
|
||||
at(layer_name)->getTensorDesc().getLayout();
|
||||
auto hint =
|
||||
(layout == IE::Layout::NCHW || layout == IE::Layout::NHWC)
|
||||
? cv::gapi::ie::TraitAs::IMAGE : cv::gapi::ie::TraitAs::TENSOR;
|
||||
|
||||
const auto hint = ctx->getInputType(layer_name);
|
||||
const auto layout = req.GetBlob(layer_name)->getTensorDesc().getLayout();
|
||||
IE::Blob::Ptr this_blob = extractBlob(*ctx, i, hint,
|
||||
layer_name,
|
||||
layout, layer_name,
|
||||
cv::util::optional<cv::Rect>{});
|
||||
setBlob(req, layer_name, this_blob, *ctx);
|
||||
}
|
||||
@@ -1485,20 +1735,43 @@ struct InferROI: public cv::detail::KernelTag {
|
||||
|
||||
const auto &input_name = uu.params.input_names.at(0);
|
||||
auto &&mm = in_metas.at(1u);
|
||||
const auto &tensor_desc =
|
||||
(uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load)
|
||||
? uu.net.getInputsInfo().at(input_name)->getTensorDesc()
|
||||
: uu.this_network.GetInputsInfo().at(input_name)->getTensorDesc();
|
||||
|
||||
if (cv::util::holds_alternative<cv::GMatDesc>(mm) ||
|
||||
cv::util::holds_alternative<cv::GFrameDesc>(mm)) {
|
||||
const auto trait = clarifyTrait(mm, tensor_desc.getDims());
|
||||
if (trait != cv::gapi::ie::TraitAs::IMAGE) {
|
||||
util::throw_error(std::runtime_error(
|
||||
"IE Backend: Only image is supported"
|
||||
" as the 1th argument for InferROI"));
|
||||
}
|
||||
} else {
|
||||
util::throw_error(std::runtime_error(
|
||||
"IE Backend: Unsupported input meta for"
|
||||
" 1th argument for InferROI"));
|
||||
}
|
||||
|
||||
// NB: Configuring input precision and network reshape must be done
|
||||
// only in the loadNetwork case.
|
||||
const auto input_layout = broadcastLayerAttr(uu.params.input_layout,
|
||||
uu.params.input_names);
|
||||
const auto interpolation = broadcastLayerAttr(uu.params.interpolation,
|
||||
uu.params.input_names);
|
||||
const auto trait = cv::gapi::ie::TraitAs::IMAGE;
|
||||
if (uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
|
||||
// 0th is ROI, 1st is input image
|
||||
auto inputs = uu.net.getInputsInfo();
|
||||
auto ii = inputs.at(input_name);
|
||||
configureInputInfo(ii, mm);
|
||||
|
||||
if (uu.params.layer_names_to_reshape.find(input_name) !=
|
||||
uu.params.layer_names_to_reshape.end()) {
|
||||
configureInputReshapeByImage(ii, mm, input_reshape_table);
|
||||
}
|
||||
if (isApplicableForResize(ii->getTensorDesc())) {
|
||||
ii->getPreProcess().setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
}
|
||||
cfgInputPreprocessing(trait, ii, mm, input_name,
|
||||
input_layout, interpolation);
|
||||
|
||||
// FIXME: This isn't the best place to call reshape function.
|
||||
// Сorrect solution would be to do this in compile() method of network,
|
||||
@@ -1517,6 +1790,9 @@ struct InferROI: public cv::detail::KernelTag {
|
||||
inputs.at(p.first)->setPrecision(toIE(p.second.first.depth()));
|
||||
}
|
||||
|
||||
const auto output_layout = broadcastLayerAttr(uu.params.output_layout,
|
||||
uu.params.output_names);
|
||||
configureOutputLayout(uu.net.getOutputsInfo(), output_layout);
|
||||
configureOutputPrecision(uu.net.getOutputsInfo(), uu.params.output_precision);
|
||||
} else {
|
||||
GAPI_Assert(uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import);
|
||||
@@ -1524,7 +1800,9 @@ struct InferROI: public cv::detail::KernelTag {
|
||||
// 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));
|
||||
const auto explicit_resize = lookUp(interpolation, input_name);
|
||||
non_const_prepm->emplace(
|
||||
input_name, createPreProcInfo(trait, mm, explicit_resize));
|
||||
|
||||
// NB: configure intput param for further preproc
|
||||
if (uu.net_input_params.is_applicable(mm)) {
|
||||
@@ -1545,7 +1823,7 @@ struct InferROI: public cv::detail::KernelTag {
|
||||
: uu.this_network.GetOutputsInfo().at(out_name)->getTensorDesc();
|
||||
|
||||
cv::GMatDesc outm(toCV(desc.getPrecision()),
|
||||
toCV(desc.getDims()));
|
||||
toCVDims(toCV(desc.getDims()), desc.getLayout()));
|
||||
result.emplace_back(outm);
|
||||
}
|
||||
return result;
|
||||
@@ -1568,6 +1846,7 @@ struct InferROI: public cv::detail::KernelTag {
|
||||
bool preprocessed = false;
|
||||
IE::Blob::Ptr this_blob =
|
||||
extractBlob(*ctx, 1, cv::gapi::ie::TraitAs::IMAGE,
|
||||
IE::Layout::ANY,
|
||||
*(ctx->uu.params.input_names.begin()),
|
||||
cv::util::make_optional(this_roi),
|
||||
slot_ptr, &preprocessed);
|
||||
@@ -1613,20 +1892,31 @@ struct InferList: public cv::detail::KernelTag {
|
||||
|
||||
// NB: Configuring input precision and network reshape must be done
|
||||
// only in the loadNetwork case.
|
||||
const auto input_layout = broadcastLayerAttr(uu.params.input_layout,
|
||||
uu.params.input_names);
|
||||
const auto interpolation = broadcastLayerAttr(uu.params.interpolation,
|
||||
uu.params.input_names);
|
||||
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 = inputs.at(input_name);
|
||||
const auto & mm = in_metas[idx++];
|
||||
configureInputInfo(ii, mm);
|
||||
|
||||
// NB: InferList expects the input starts with index 1 wil be the images.
|
||||
const auto input_trait = clarifyTrait(mm, ii->getTensorDesc().getDims());
|
||||
if (input_trait != cv::gapi::ie::TraitAs::IMAGE) {
|
||||
util::throw_error(std::runtime_error(
|
||||
"IE Backend: Only image is supported"
|
||||
" as the " + std::to_string(idx) + "th argument for InferList"));
|
||||
}
|
||||
|
||||
if (uu.params.layer_names_to_reshape.find(input_name) !=
|
||||
uu.params.layer_names_to_reshape.end()) {
|
||||
configureInputReshapeByImage(ii, mm, input_reshape_table);
|
||||
}
|
||||
if (isApplicableForResize(ii->getTensorDesc())) {
|
||||
ii->getPreProcess().setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
}
|
||||
cfgInputPreprocessing(input_trait, ii, mm,
|
||||
input_name, input_layout, interpolation);
|
||||
}
|
||||
|
||||
// FIXME: This isn't the best place to call reshape function.
|
||||
@@ -1641,6 +1931,9 @@ struct InferList: public cv::detail::KernelTag {
|
||||
ii->setPrecision(toIE(p.second.first.depth()));
|
||||
}
|
||||
|
||||
const auto output_layout = broadcastLayerAttr(uu.params.output_layout,
|
||||
uu.params.output_names);
|
||||
configureOutputLayout(uu.net.getOutputsInfo(), output_layout);
|
||||
configureOutputPrecision(uu.net.getOutputsInfo(), uu.params.output_precision);
|
||||
} else {
|
||||
GAPI_Assert(uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import);
|
||||
@@ -1650,7 +1943,18 @@ struct InferList: public cv::detail::KernelTag {
|
||||
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));
|
||||
|
||||
// NB: InferList expects the input starts with index 1 wil be the images.
|
||||
const auto input_trait = clarifyTrait(mm, ii->getTensorDesc().getDims());
|
||||
if (input_trait != cv::gapi::ie::TraitAs::IMAGE) {
|
||||
util::throw_error(std::runtime_error(
|
||||
"IE Backend: Only image is supported"
|
||||
" as the " + std::to_string(idx) + "th argument for InferList"));
|
||||
}
|
||||
|
||||
const auto explicit_resize = lookUp(interpolation, input_name);
|
||||
non_const_prepm->emplace(
|
||||
input_name, createPreProcInfo(input_trait, mm, explicit_resize));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1678,6 +1982,7 @@ struct InferList: public cv::detail::KernelTag {
|
||||
// NB: This blob will be used to make roi from its, so
|
||||
// it should be treated as image
|
||||
IE::Blob::Ptr this_blob = extractBlob(*ctx, 1, cv::gapi::ie::TraitAs::IMAGE,
|
||||
IE::Layout::ANY,
|
||||
ctx->uu.params.input_names[0u],
|
||||
cv::util::optional<cv::Rect>{});
|
||||
|
||||
@@ -1688,7 +1993,7 @@ struct InferList: public cv::detail::KernelTag {
|
||||
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());
|
||||
cached_dims[i] = toCVDims(toCV(desc.getDims()), desc.getLayout());
|
||||
// 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);
|
||||
@@ -1744,51 +2049,52 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
// "blob"-based ones)
|
||||
// FIXME: this is filtering not done, actually! GArrayDesc has
|
||||
// no hint for its underlying type!
|
||||
const auto &mm_0 = in_metas[0u];
|
||||
switch (in_metas[0u].index()) {
|
||||
case cv::GMetaArg::index_of<cv::GMatDesc>(): {
|
||||
const auto &meta_0 = util::get<cv::GMatDesc>(mm_0);
|
||||
GAPI_Assert( !meta_0.isND()
|
||||
&& !meta_0.planar
|
||||
&& "Only images are supported as the 0th argument");
|
||||
break;
|
||||
}
|
||||
case cv::GMetaArg::index_of<cv::GFrameDesc>(): {
|
||||
// FIXME: Is there any validation for GFrame ?
|
||||
break;
|
||||
}
|
||||
default:
|
||||
util::throw_error(std::runtime_error("Unsupported input meta for IE backend"));
|
||||
}
|
||||
|
||||
if (util::holds_alternative<cv::GMatDesc>(mm_0)) {
|
||||
const auto &meta_0 = util::get<cv::GMatDesc>(mm_0);
|
||||
GAPI_Assert( !meta_0.isND()
|
||||
&& !meta_0.planar
|
||||
&& "Only images are supported as the 0th argument");
|
||||
const auto &input_name_0 = uu.params.input_names.front();
|
||||
const auto &mm_0 = in_metas[0u];
|
||||
const auto &tensor_desc_0 =
|
||||
(uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load)
|
||||
? uu.net.getInputsInfo().at(input_name_0)->getTensorDesc()
|
||||
: uu.this_network.GetInputsInfo().at(input_name_0)->getTensorDesc();
|
||||
|
||||
if (cv::util::holds_alternative<cv::GMatDesc>(mm_0) ||
|
||||
cv::util::holds_alternative<cv::GFrameDesc>(mm_0)) {
|
||||
const auto trait = clarifyTrait(mm_0, tensor_desc_0.getDims());
|
||||
if (trait != cv::gapi::ie::TraitAs::IMAGE) {
|
||||
util::throw_error(std::runtime_error(
|
||||
"IE Backend: Only images is"
|
||||
" supported as the 0th argument"));
|
||||
}
|
||||
} else {
|
||||
util::throw_error(std::runtime_error(
|
||||
"IE Backend: Unsupported input meta"
|
||||
" for 0th argument in IE backend"));
|
||||
}
|
||||
|
||||
std::size_t idx = 1u;
|
||||
const auto input_layout = broadcastLayerAttr(uu.params.input_layout,
|
||||
uu.params.input_names);
|
||||
const auto interpolation = broadcastLayerAttr(uu.params.interpolation,
|
||||
uu.params.input_names);
|
||||
for (auto &&input_name : uu.params.input_names) {
|
||||
const auto &mm = in_metas[idx];
|
||||
GAPI_Assert(util::holds_alternative<cv::GArrayDesc>(mm)
|
||||
&& "Non-array inputs are not supported");
|
||||
|
||||
if (op.k.inKinds[idx] == cv::detail::OpaqueKind::CV_RECT) {
|
||||
const auto input_trait = cv::gapi::ie::TraitAs::IMAGE;
|
||||
// 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) {
|
||||
auto inputs = uu.net.getInputsInfo();
|
||||
// This is a cv::Rect -- configure the IE preprocessing
|
||||
auto ii = inputs.at(input_name);
|
||||
configureInputInfo(ii, mm_0);
|
||||
if (uu.params.layer_names_to_reshape.find(input_name) !=
|
||||
uu.params.layer_names_to_reshape.end()) {
|
||||
configureInputReshapeByImage(ii, mm_0, input_reshape_table);
|
||||
}
|
||||
if (isApplicableForResize(ii->getTensorDesc())) {
|
||||
ii->getPreProcess().setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
}
|
||||
cfgInputPreprocessing(input_trait, ii, mm_0,
|
||||
input_name, input_layout, interpolation);
|
||||
|
||||
for (auto &&p : uu.params.const_inputs) {
|
||||
inputs.at(p.first)->setPrecision(toIE(p.second.first.depth()));
|
||||
@@ -1800,19 +2106,32 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
if (!input_reshape_table.empty()) {
|
||||
const_cast<IE::CNNNetwork *>(&uu.net)->reshape(input_reshape_table);
|
||||
}
|
||||
const auto output_layout = broadcastLayerAttr(uu.params.output_layout,
|
||||
uu.params.output_names);
|
||||
configureOutputLayout(uu.net.getOutputsInfo(), output_layout);
|
||||
configureOutputPrecision(uu.net.getOutputsInfo(), uu.params.output_precision);
|
||||
} 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));
|
||||
const auto explicit_resize = lookUp(interpolation, input_name);
|
||||
non_const_prepm->emplace(
|
||||
input_name, createPreProcInfo(input_trait, mm_0, explicit_resize));
|
||||
}
|
||||
} else {
|
||||
// This is a cv::GMat (equals to: cv::Mat)
|
||||
// Just validate that it is really the type
|
||||
// (other types are prohibited here)
|
||||
GAPI_Assert(op.k.inKinds[idx] == cv::detail::OpaqueKind::CV_MAT);
|
||||
// NB: Well, it's even impossible to specify the precision since
|
||||
// there is not such info in GArray<cv::GMat>
|
||||
const auto explicit_resize = lookUp(interpolation, input_name);
|
||||
const auto explicit_layout = lookUp(input_layout , input_name);
|
||||
if (explicit_resize || explicit_layout) {
|
||||
util::throw_error(std::logic_error(
|
||||
"InferList2 doesn't support preprocessing for \"tensor\"'s arguments!"));
|
||||
}
|
||||
}
|
||||
idx++; // NB: Never forget to increment the counter
|
||||
}
|
||||
@@ -1832,6 +2151,7 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
// NB: This blob will be used to make roi from its, so
|
||||
// it should be treated as image
|
||||
IE::Blob::Ptr blob_0 = extractBlob(*ctx, 0, cv::gapi::ie::TraitAs::IMAGE,
|
||||
IE::Layout::ANY,
|
||||
ctx->uu.params.input_names[0u],
|
||||
cv::util::optional<cv::Rect>{});
|
||||
const auto list_size = ctx->inArg<cv::detail::VectorRef>(1u).size();
|
||||
@@ -1851,7 +2171,7 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
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());
|
||||
cached_dims[i] = toCVDims(toCV(desc.getDims()), desc.getLayout());
|
||||
// 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);
|
||||
@@ -1874,8 +2194,10 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
} else if (this_vec.getKind() == cv::detail::OpaqueKind::CV_MAT) {
|
||||
const auto &vec = this_vec.rref<cv::Mat>();
|
||||
const auto &mat = vec[list_idx];
|
||||
setBlob(req, ctx->uu.params.input_names[in_idx],
|
||||
wrapIE(mat, cv::gapi::ie::TraitAs::TENSOR),
|
||||
const auto layer_name = ctx->uu.params.input_names[in_idx];
|
||||
const auto layout = req.GetBlob(layer_name)->getTensorDesc().getLayout();
|
||||
setBlob(req, layer_name,
|
||||
wrapIE(mat, cv::gapi::ie::TraitAs::TENSOR, layout),
|
||||
*ctx);
|
||||
} else {
|
||||
GAPI_Assert(false &&
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
#include <opencv2/gapi/infer/bindings_ov.hpp>
|
||||
|
||||
cv::gapi::ov::PyParams::PyParams(const std::string &tag,
|
||||
const std::string &model_path,
|
||||
const std::string &bin_path,
|
||||
const std::string &device)
|
||||
: m_priv(std::make_shared<Params<cv::gapi::Generic>>(tag, model_path, bin_path, device)) {
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams::PyParams(const std::string &tag,
|
||||
const std::string &blob_path,
|
||||
const std::string &device)
|
||||
: m_priv(std::make_shared<Params<cv::gapi::Generic>>(tag, blob_path, device)) {
|
||||
}
|
||||
|
||||
cv::gapi::GBackend cv::gapi::ov::PyParams::backend() const {
|
||||
return m_priv->backend();
|
||||
}
|
||||
|
||||
std::string cv::gapi::ov::PyParams::tag() const {
|
||||
return m_priv->tag();
|
||||
}
|
||||
|
||||
cv::util::any cv::gapi::ov::PyParams::params() const {
|
||||
return m_priv->params();
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgPluginConfig(
|
||||
const std::map<std::string, std::string> &config) {
|
||||
m_priv->cfgPluginConfig(config);
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgInputTensorLayout(std::string tensor_layout) {
|
||||
m_priv->cfgInputTensorLayout(std::move(tensor_layout));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgInputTensorLayout(
|
||||
std::map<std::string, std::string> layout_map) {
|
||||
m_priv->cfgInputTensorLayout(std::move(layout_map));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgInputModelLayout(std::string tensor_layout) {
|
||||
m_priv->cfgInputModelLayout(std::move(tensor_layout));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgInputModelLayout(
|
||||
std::map<std::string, std::string> layout_map) {
|
||||
m_priv->cfgInputModelLayout(std::move(layout_map));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgOutputTensorLayout(std::string tensor_layout) {
|
||||
m_priv->cfgOutputTensorLayout(std::move(tensor_layout));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgOutputTensorLayout(
|
||||
std::map<std::string, std::string> layout_map) {
|
||||
m_priv->cfgOutputTensorLayout(std::move(layout_map));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgOutputModelLayout(std::string tensor_layout) {
|
||||
m_priv->cfgOutputModelLayout(std::move(tensor_layout));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgOutputModelLayout(
|
||||
std::map<std::string, std::string> layout_map) {
|
||||
m_priv->cfgOutputModelLayout(std::move(layout_map));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgOutputTensorPrecision(int precision) {
|
||||
m_priv->cfgOutputTensorPrecision(precision);
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgOutputTensorPrecision(
|
||||
std::map<std::string, int> precision_map) {
|
||||
m_priv->cfgOutputTensorPrecision(precision_map);
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgReshape(std::vector<size_t> new_shape) {
|
||||
m_priv->cfgReshape(std::move(new_shape));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgReshape(
|
||||
std::map<std::string, std::vector<size_t>> new_shape_map) {
|
||||
m_priv->cfgReshape(std::move(new_shape_map));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgNumRequests(const size_t nireq) {
|
||||
m_priv->cfgNumRequests(nireq);
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgMean(std::vector<float> mean_values) {
|
||||
m_priv->cfgMean(std::move(mean_values));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgMean(
|
||||
std::map<std::string, std::vector<float>> mean_map) {
|
||||
m_priv->cfgMean(std::move(mean_map));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgScale(std::vector<float> scale_values) {
|
||||
m_priv->cfgScale(std::move(scale_values));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgScale(
|
||||
std::map<std::string, std::vector<float>> scale_map) {
|
||||
m_priv->cfgScale(std::move(scale_map));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgResize(int interpolation) {
|
||||
m_priv->cfgResize(interpolation);
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams&
|
||||
cv::gapi::ov::PyParams::cfgResize(std::map<std::string, int> interpolation) {
|
||||
m_priv->cfgResize(std::move(interpolation));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams cv::gapi::ov::params(const std::string &tag,
|
||||
const std::string &model_path,
|
||||
const std::string &weights,
|
||||
const std::string &device) {
|
||||
return {tag, model_path, weights, device};
|
||||
}
|
||||
|
||||
cv::gapi::ov::PyParams cv::gapi::ov::params(const std::string &tag,
|
||||
const std::string &blob_path,
|
||||
const std::string &device) {
|
||||
return {tag, blob_path, device};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
// 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) 2023 Intel Corporation
|
||||
|
||||
#ifndef OPENCV_GAPI_GOVBACKEND_HPP
|
||||
#define OPENCV_GAPI_GOVBACKEND_HPP
|
||||
|
||||
// Include anyway - cv::gapi::ov::backend() still needs to be defined
|
||||
#include "opencv2/gapi/infer/ov.hpp"
|
||||
|
||||
#if defined HAVE_INF_ENGINE && INF_ENGINE_RELEASE >= 2022010000
|
||||
|
||||
#include <openvino/openvino.hpp>
|
||||
|
||||
#include "backends/common/gbackend.hpp"
|
||||
|
||||
namespace cv {
|
||||
namespace gimpl {
|
||||
namespace ov {
|
||||
|
||||
struct OVCompiled {
|
||||
::ov::CompiledModel compiled_model;
|
||||
};
|
||||
|
||||
class RequestPool;
|
||||
|
||||
class GOVExecutable final: public GIslandExecutable
|
||||
{
|
||||
const ade::Graph &m_g;
|
||||
GModel::ConstGraph m_gm;
|
||||
|
||||
// The only executable stuff in this graph
|
||||
// (assuming it is always single-op)
|
||||
ade::NodeHandle this_nh;
|
||||
OVCompiled compiled;
|
||||
|
||||
// List of all resources in graph (both internal and external)
|
||||
std::vector<ade::NodeHandle> m_dataNodes;
|
||||
|
||||
// To manage multiple async requests
|
||||
std::unique_ptr<RequestPool> m_reqPool;
|
||||
|
||||
public:
|
||||
GOVExecutable(const ade::Graph &graph,
|
||||
const std::vector<ade::NodeHandle> &nodes);
|
||||
|
||||
virtual inline bool canReshape() const override { return false; }
|
||||
virtual inline void reshape(ade::Graph&, const GCompileArgs&) override {
|
||||
GAPI_Error("InternalError"); // Not implemented yet
|
||||
}
|
||||
|
||||
virtual void run(std::vector<InObj> &&,
|
||||
std::vector<OutObj> &&) override {
|
||||
GAPI_Error("Not implemented");
|
||||
}
|
||||
|
||||
virtual void run(GIslandExecutable::IInput &in,
|
||||
GIslandExecutable::IOutput &out) override;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif // HAVE_INF_ENGINE && INF_ENGINE_RELEASE >= 2022010000
|
||||
#endif // OPENCV_GAPI_GOVBACKEND_HPP
|
||||
@@ -0,0 +1,35 @@
|
||||
// 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) 2023 Intel Corporation
|
||||
|
||||
#ifndef OPENCV_GAPI_INFER_OV_UTIL_HPP
|
||||
#define OPENCV_GAPI_INFER_OV_UTIL_HPP
|
||||
|
||||
#if defined HAVE_INF_ENGINE && INF_ENGINE_RELEASE >= 2022010000
|
||||
|
||||
// NOTE: This file is not included by default in infer/ov.hpp
|
||||
// and won't be. infer/ov.hpp doesn't depend on OV headers itself.
|
||||
// This file does -- so needs to be included separately by those who care.
|
||||
|
||||
#include <openvino/openvino.hpp>
|
||||
|
||||
#include <opencv2/core/cvdef.h> // GAPI_EXPORTS
|
||||
#include <opencv2/gapi/gkernel.hpp> // GKernelPackage
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace ov {
|
||||
namespace util {
|
||||
|
||||
// NB: These functions are EXPORTed to make them accessible by the
|
||||
// test suite only.
|
||||
GAPI_EXPORTS std::vector<int> to_ocv(const ::ov::Shape &shape);
|
||||
GAPI_EXPORTS int to_ocv(const ::ov::element::Type &type);
|
||||
|
||||
}}}}
|
||||
|
||||
#endif // HAVE_INF_ENGINE && INF_ENGINE_RELEASE >= 2022010000
|
||||
|
||||
#endif // OPENCV_GAPI_INFER_OV_UTIL_HPP
|
||||
Reference in New Issue
Block a user