1
0
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:
Alexander Smorkalov
2023-07-12 13:42:01 +03:00
128 changed files with 9936 additions and 932 deletions
+12 -4
View File
@@ -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
+45 -21
View File
@@ -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
+421 -99
View File
@@ -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
+35
View File
@@ -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