mirror of
https://github.com/opencv/opencv.git
synced 2024-11-28 05:06:29 +08:00
Merge pull request #18127 from smirnov-alexey:as/gapi_serialization
[G-API]: Add GOpaque and GArray serialization support * Add GOpaque and GArray serialization support * Address review comments * Remove holds() method * Address review comments * Remove comments * Align streaming with kind changes * Fix kind in kernel * Address review comments
This commit is contained in:
parent
620629593b
commit
a3e8c6e866
@ -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 Intel Corporation
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
|
||||
|
||||
#ifndef OPENCV_GAPI_GARG_HPP
|
||||
@ -170,7 +170,8 @@ inline GRunArgsP& operator += (GRunArgsP &lhs, const GRunArgsP &rhs)
|
||||
namespace gapi
|
||||
{
|
||||
GAPI_EXPORTS cv::GRunArgsP bind(cv::GRunArgs &results);
|
||||
} // namespace gapi
|
||||
GAPI_EXPORTS cv::GRunArg bind(cv::GRunArgP &out); // FIXME: think more about it
|
||||
}
|
||||
|
||||
template<typename... Ts> inline GRunArgs gin(const Ts&... args)
|
||||
{
|
||||
|
@ -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 Intel Corporation
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
|
||||
|
||||
#ifndef OPENCV_GAPI_GARRAY_HPP
|
||||
@ -49,31 +49,6 @@ std::ostream& operator<<(std::ostream& os, const cv::GArrayDesc &desc);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// FIXME: This type spec needs to be:
|
||||
// 1) shared with GOpaque (not needed right now)
|
||||
// 2) unified with the serialization (S11N, not merged right now).
|
||||
// Adding it to type traits is problematic due to our header deps
|
||||
// (which also need to be fixed).
|
||||
enum class TypeSpec: int {
|
||||
OPAQUE_SPEC,
|
||||
MAT,
|
||||
RECT
|
||||
};
|
||||
// FIXME: Reuse the below from "opaque traits" of S11N!
|
||||
template<typename T> struct GTypeSpec;
|
||||
template<typename T> struct GTypeSpec
|
||||
{
|
||||
static constexpr const TypeSpec spec = TypeSpec::OPAQUE_SPEC;
|
||||
};
|
||||
template<> struct GTypeSpec<cv::Mat>
|
||||
{
|
||||
static constexpr const TypeSpec spec = TypeSpec::MAT;
|
||||
};
|
||||
template<> struct GTypeSpec<cv::Rect>
|
||||
{
|
||||
static constexpr const TypeSpec spec = TypeSpec::RECT;
|
||||
};
|
||||
|
||||
// ConstructVec is a callback which stores information about T and is used by
|
||||
// G-API runtime to construct arrays in host memory (T remains opaque for G-API).
|
||||
// ConstructVec is carried into G-API internals by GArrayU.
|
||||
@ -112,6 +87,11 @@ namespace detail
|
||||
template <typename T>
|
||||
void specifyType(); // Store type of initial GArray<T>
|
||||
|
||||
template <typename T>
|
||||
void storeKind();
|
||||
|
||||
void setKind(cv::detail::OpaqueKind);
|
||||
|
||||
std::shared_ptr<GOrigin> m_priv;
|
||||
std::shared_ptr<TypeHintBase> m_hint;
|
||||
};
|
||||
@ -128,6 +108,11 @@ namespace detail
|
||||
m_hint.reset(new TypeHint<typename std::decay<T>::type>);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void GArrayU::storeKind(){
|
||||
setKind(cv::detail::GOpaqueTraits<T>::kind);
|
||||
};
|
||||
|
||||
// This class represents a typed STL vector reference.
|
||||
// Depending on origins, this reference may be either "just a" reference to
|
||||
// an object created externally, OR actually own the underlying object
|
||||
@ -138,7 +123,6 @@ namespace detail
|
||||
// These fields are set by the derived class(es)
|
||||
std::size_t m_elemSize = 0ul;
|
||||
cv::GArrayDesc m_desc;
|
||||
TypeSpec m_spec;
|
||||
virtual ~BasicVectorRef() {}
|
||||
|
||||
virtual void mov(BasicVectorRef &ref) = 0;
|
||||
@ -163,7 +147,6 @@ namespace detail
|
||||
{
|
||||
m_elemSize = sizeof(T);
|
||||
if (vec) m_desc = cv::descr_of(*vec);
|
||||
m_spec = GTypeSpec<T>::spec;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -238,7 +221,6 @@ namespace detail
|
||||
wref() = std::move(tv->wref());
|
||||
}
|
||||
|
||||
|
||||
virtual const void* ptr() const override { return &rref(); }
|
||||
virtual std::size_t size() const override { return rref().size(); }
|
||||
};
|
||||
@ -253,6 +235,7 @@ namespace detail
|
||||
class VectorRef
|
||||
{
|
||||
std::shared_ptr<BasicVectorRef> m_ref;
|
||||
cv::detail::OpaqueKind m_kind;
|
||||
|
||||
template<typename T> inline void check() const
|
||||
{
|
||||
@ -262,9 +245,17 @@ namespace detail
|
||||
|
||||
public:
|
||||
VectorRef() = default;
|
||||
template<typename T> explicit VectorRef(const std::vector<T>& vec) : m_ref(new VectorRefT<T>(vec)) {}
|
||||
template<typename T> explicit VectorRef(std::vector<T>& vec) : m_ref(new VectorRefT<T>(vec)) {}
|
||||
template<typename T> explicit VectorRef(std::vector<T>&& vec) : m_ref(new VectorRefT<T>(vec)) {}
|
||||
template<typename T> explicit VectorRef(const std::vector<T>& vec) :
|
||||
m_ref(new VectorRefT<T>(vec)), m_kind(GOpaqueTraits<T>::kind) {}
|
||||
template<typename T> explicit VectorRef(std::vector<T>& vec) :
|
||||
m_ref(new VectorRefT<T>(vec)), m_kind(GOpaqueTraits<T>::kind) {}
|
||||
template<typename T> explicit VectorRef(std::vector<T>&& vec) :
|
||||
m_ref(new VectorRefT<T>(std::move(vec))), m_kind(GOpaqueTraits<T>::kind) {}
|
||||
|
||||
cv::detail::OpaqueKind getKind() const
|
||||
{
|
||||
return m_kind;
|
||||
}
|
||||
|
||||
template<typename T> void reset()
|
||||
{
|
||||
@ -274,6 +265,12 @@ namespace detail
|
||||
static_cast<VectorRefT<T>&>(*m_ref).reset();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void storeKind()
|
||||
{
|
||||
m_kind = cv::detail::GOpaqueTraits<T>::kind;
|
||||
}
|
||||
|
||||
template<typename T> std::vector<T>& wref()
|
||||
{
|
||||
check<T>();
|
||||
@ -303,11 +300,6 @@ namespace detail
|
||||
|
||||
// May be used to uniquely identify this object internally
|
||||
const void *ptr() const { return m_ref->ptr(); }
|
||||
|
||||
TypeSpec spec() const
|
||||
{
|
||||
return m_ref->m_spec;
|
||||
}
|
||||
};
|
||||
|
||||
// Helper (FIXME: work-around?)
|
||||
@ -349,10 +341,12 @@ private:
|
||||
|
||||
static void VCTor(detail::VectorRef& vref) {
|
||||
vref.reset<HT>();
|
||||
vref.storeKind<HT>();
|
||||
}
|
||||
void putDetails() {
|
||||
m_ref.setConstructFcn(&VCTor);
|
||||
m_ref.specifyType<HT>();
|
||||
m_ref.specifyType<HT>(); // FIXME: to unify those 2 to avoid excessive dynamic_cast
|
||||
m_ref.storeKind<HT>(); //
|
||||
}
|
||||
|
||||
detail::GArrayU m_ref;
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
namespace cv {
|
||||
|
||||
class GMat; // FIXME: forward declaration for GOpaqueTraits
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// This is a trait-like structure to mark backend-specific compile arguments
|
||||
@ -32,6 +34,38 @@ namespace detail
|
||||
{};
|
||||
struct TransformTag
|
||||
{};
|
||||
|
||||
// This enum is utilized mostly by GArray and GOpaque to store and recognize their internal data
|
||||
// types (aka Host type). Also it is widely used during serialization routine.
|
||||
enum class OpaqueKind: int
|
||||
{
|
||||
CV_UNKNOWN, // Unknown, generic, opaque-to-GAPI data type unsupported in graph seriallization
|
||||
CV_BOOL, // bool user G-API data
|
||||
CV_INT, // int user G-API data
|
||||
CV_DOUBLE, // double user G-API data
|
||||
CV_POINT, // cv::Point user G-API data
|
||||
CV_SIZE, // cv::Size user G-API data
|
||||
CV_RECT, // cv::Rect user G-API data
|
||||
CV_SCALAR, // cv::Scalar user G-API data
|
||||
CV_MAT, // cv::Mat user G-API data
|
||||
};
|
||||
|
||||
// Type traits helper which simplifies the extraction of kind from type
|
||||
template<typename T> struct GOpaqueTraits;
|
||||
template<typename T> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_UNKNOWN; };
|
||||
template<> struct GOpaqueTraits<int> { static constexpr const OpaqueKind kind = OpaqueKind::CV_INT; };
|
||||
template<> struct GOpaqueTraits<double> { static constexpr const OpaqueKind kind = OpaqueKind::CV_DOUBLE; };
|
||||
template<> struct GOpaqueTraits<cv::Size> { static constexpr const OpaqueKind kind = OpaqueKind::CV_SIZE; };
|
||||
template<> struct GOpaqueTraits<bool> { static constexpr const OpaqueKind kind = OpaqueKind::CV_BOOL; };
|
||||
template<> struct GOpaqueTraits<cv::Scalar> { static constexpr const OpaqueKind kind = OpaqueKind::CV_SCALAR; };
|
||||
template<> struct GOpaqueTraits<cv::Point> { static constexpr const OpaqueKind kind = OpaqueKind::CV_POINT; };
|
||||
template<> struct GOpaqueTraits<cv::Mat> { static constexpr const OpaqueKind kind = OpaqueKind::CV_MAT; };
|
||||
template<> struct GOpaqueTraits<cv::Rect> { static constexpr const OpaqueKind kind = OpaqueKind::CV_RECT; };
|
||||
template<> struct GOpaqueTraits<cv::GMat> { static constexpr const OpaqueKind kind = OpaqueKind::CV_MAT; };
|
||||
// GArray is not supporting bool type for now due to difference in std::vector<bool> implementation
|
||||
using GOpaqueTraitsArrayTypes = std::tuple<int, double, cv::Size, cv::Scalar, cv::Point, cv::Mat, cv::Rect>;
|
||||
// GOpaque is not supporting cv::Mat and cv::Scalar since there are GScalar and GMat types
|
||||
using GOpaqueTraitsOpaqueTypes = std::tuple<bool, int, double, cv::Size, cv::Point, cv::Rect>;
|
||||
} // namespace detail
|
||||
|
||||
// This definition is here because it is reused by both public(?) and internal
|
||||
|
@ -26,8 +26,8 @@
|
||||
|
||||
namespace cv {
|
||||
|
||||
using GSpecs = std::vector<cv::detail::ArgSpec>;
|
||||
using GShapes = std::vector<GShape>;
|
||||
using GKinds = std::vector<cv::detail::OpaqueKind>;
|
||||
|
||||
// GKernel describes kernel API to the system
|
||||
// FIXME: add attributes of a kernel, (e.g. number and types
|
||||
@ -39,10 +39,10 @@ struct GAPI_EXPORTS GKernel
|
||||
const std::string name; // kernel ID, defined by its API (signature)
|
||||
const std::string tag; // some (implementation-specific) tag
|
||||
const M outMeta; // generic adaptor to API::outMeta(...)
|
||||
const GSpecs inSpecs; // specs of kernel's inputs (FIXME: below)
|
||||
const GShapes outShapes; // types (shapes) kernel's outputs
|
||||
const GKinds inKinds; // kinds of kernel's inputs (fixme: below)
|
||||
};
|
||||
// TODO: It's questionable if inSpecs should really be here. Instead,
|
||||
// TODO: It's questionable if inKinds should really be here. Instead,
|
||||
// this information could come from meta.
|
||||
|
||||
// GKernelImpl describes particular kernel implementation to the system
|
||||
@ -213,8 +213,8 @@ public:
|
||||
cv::GCall call(GKernel{ K::id()
|
||||
, K::tag()
|
||||
, &K::getOutMeta
|
||||
, {detail::GTypeTraits<Args>::spec...}
|
||||
, {detail::GTypeTraits<R>::shape...}});
|
||||
, {detail::GTypeTraits<R>::shape...}
|
||||
, {detail::GTypeTraits<Args>::op_kind...}});
|
||||
call.pass(args...); // TODO: std::forward() here?
|
||||
return yield(call, typename detail::MkSeq<sizeof...(R)>::type());
|
||||
}
|
||||
@ -238,8 +238,8 @@ public:
|
||||
cv::GCall call(GKernel{ K::id()
|
||||
, K::tag()
|
||||
, &K::getOutMeta
|
||||
, {detail::GTypeTraits<Args>::spec...}
|
||||
, {detail::GTypeTraits<R>::shape}});
|
||||
, {detail::GTypeTraits<R>::shape}
|
||||
, {detail::GTypeTraits<Args>::op_kind...}});
|
||||
call.pass(args...);
|
||||
return detail::Yield<R>::yield(call, 0);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// Copyright (C) 2019-2020 Intel Corporation
|
||||
|
||||
|
||||
#ifndef OPENCV_GAPI_GOPAQUE_HPP
|
||||
@ -46,7 +46,6 @@ std::ostream& operator<<(std::ostream& os, const cv::GOpaqueDesc &desc);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// ConstructOpaque is a callback which stores information about T and is used by
|
||||
// G-API runtime to construct an object in host memory (T remains opaque for G-API).
|
||||
// ConstructOpaque is carried into G-API internals by GOpaqueU.
|
||||
@ -81,6 +80,11 @@ namespace detail
|
||||
template <typename T>
|
||||
void specifyType(); // Store type of initial GOpaque<T>
|
||||
|
||||
template <typename T>
|
||||
void storeKind();
|
||||
|
||||
void setKind(cv::detail::OpaqueKind);
|
||||
|
||||
std::shared_ptr<GOrigin> m_priv;
|
||||
std::shared_ptr<TypeHintBase> m_hint;
|
||||
};
|
||||
@ -97,6 +101,12 @@ namespace detail
|
||||
m_hint.reset(new TypeHint<util::decay_t<T>>);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void GOpaqueU::storeKind(){
|
||||
// FIXME: Add assert here on cv::Mat and cv::Scalar?
|
||||
setKind(cv::detail::GOpaqueTraits<T>::kind);
|
||||
};
|
||||
|
||||
// This class represents a typed object reference.
|
||||
// Depending on origins, this reference may be either "just a" reference to
|
||||
// an object created externally, OR actually own the underlying object
|
||||
@ -213,6 +223,7 @@ namespace detail
|
||||
class OpaqueRef
|
||||
{
|
||||
std::shared_ptr<BasicOpaqueRef> m_ref;
|
||||
cv::detail::OpaqueKind m_kind;
|
||||
|
||||
template<typename T> inline void check() const
|
||||
{
|
||||
@ -222,13 +233,19 @@ namespace detail
|
||||
public:
|
||||
OpaqueRef() = default;
|
||||
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename = util::are_different_t<OpaqueRef, T>
|
||||
>
|
||||
// FIXME: probably won't work with const object
|
||||
explicit OpaqueRef(T&& obj) :
|
||||
m_ref(new OpaqueRefT<util::decay_t<T>>(std::forward<T>(obj))) {}
|
||||
m_ref(new OpaqueRefT<util::decay_t<T>>(std::forward<T>(obj))),
|
||||
m_kind(GOpaqueTraits<T>::kind) {}
|
||||
|
||||
cv::detail::OpaqueKind getKind() const
|
||||
{
|
||||
return m_kind;
|
||||
}
|
||||
|
||||
template<typename T> void reset()
|
||||
{
|
||||
@ -238,6 +255,12 @@ namespace detail
|
||||
static_cast<OpaqueRefT<T>&>(*m_ref).reset();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void storeKind()
|
||||
{
|
||||
m_kind = cv::detail::GOpaqueTraits<T>::kind;
|
||||
}
|
||||
|
||||
template<typename T> T& wref()
|
||||
{
|
||||
check<T>();
|
||||
@ -285,10 +308,12 @@ private:
|
||||
|
||||
static void CTor(detail::OpaqueRef& ref) {
|
||||
ref.reset<HT>();
|
||||
ref.storeKind<HT>();
|
||||
}
|
||||
void putDetails() {
|
||||
m_ref.setConstructFcn(&CTor);
|
||||
m_ref.specifyType<HT>();
|
||||
m_ref.specifyType<HT>(); // FIXME: to unify those 2 to avoid excessive dynamic_cast
|
||||
m_ref.storeKind<HT>(); //
|
||||
}
|
||||
|
||||
detail::GOpaqueU m_ref;
|
||||
|
@ -41,98 +41,45 @@ namespace detail
|
||||
GOPAQUE, // a cv::GOpaqueU (note - exactly GOpaqueU, not GOpaque<T>!)
|
||||
};
|
||||
|
||||
// This enum captures some information about T in GArray<T> and GOpaque<T>
|
||||
enum class ArgSpec: int
|
||||
{
|
||||
OPAQUE_SPEC, // Unknown, generic, opaque-to-GAPI data type
|
||||
GMAT, // a GMat
|
||||
RECT, // a cv::Rect
|
||||
// NB: Add more types when required
|
||||
};
|
||||
|
||||
// Describe specialization types of interest first
|
||||
// FIXME: It comes to GArg but ideally it should go to *Desc{}
|
||||
// type family. Bringing it there is a more massive change though.
|
||||
template<typename T> struct GSpecTraits;
|
||||
template<typename T> struct GSpecTraits
|
||||
{
|
||||
static constexpr const ArgSpec spec = ArgSpec::OPAQUE_SPEC;
|
||||
};
|
||||
template<> struct GSpecTraits<cv::GMat>
|
||||
{
|
||||
static constexpr const ArgSpec spec = ArgSpec::GMAT;
|
||||
};
|
||||
template<> struct GSpecTraits<cv::Rect>
|
||||
{
|
||||
static constexpr const ArgSpec spec = ArgSpec::RECT;
|
||||
};
|
||||
|
||||
enum class OpaqueKind: int
|
||||
{
|
||||
CV_UNKNOWN, // Unknown, generic, opaque-to-GAPI data type unsupported in graph seriallization
|
||||
CV_BOOL, // bool user G-API data
|
||||
CV_INT, // int user G-API data
|
||||
CV_DOUBLE, // double user G-API data
|
||||
CV_POINT, // cv::Point user G-API data
|
||||
CV_SIZE, // cv::Size user G-API data
|
||||
CV_RECT, // cv::Rect user G-API data
|
||||
CV_SCALAR, // cv::Scalar user G-API data
|
||||
CV_MAT, // cv::Mat user G-API data
|
||||
};
|
||||
|
||||
template<typename T> struct GOpaqueTraits;
|
||||
template<typename T> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_UNKNOWN; };
|
||||
template<> struct GOpaqueTraits<int> { static constexpr const OpaqueKind kind = OpaqueKind::CV_INT; };
|
||||
template<> struct GOpaqueTraits<double> { static constexpr const OpaqueKind kind = OpaqueKind::CV_DOUBLE; };
|
||||
template<> struct GOpaqueTraits<cv::Size> { static constexpr const OpaqueKind kind = OpaqueKind::CV_SIZE; };
|
||||
template<> struct GOpaqueTraits<bool> { static constexpr const OpaqueKind kind = OpaqueKind::CV_BOOL; };
|
||||
template<> struct GOpaqueTraits<cv::Scalar> { static constexpr const OpaqueKind kind = OpaqueKind::CV_SCALAR; };
|
||||
template<> struct GOpaqueTraits<cv::Point> { static constexpr const OpaqueKind kind = OpaqueKind::CV_POINT; };
|
||||
template<> struct GOpaqueTraits<cv::Mat> { static constexpr const OpaqueKind kind = OpaqueKind::CV_MAT; };
|
||||
template<> struct GOpaqueTraits<cv::Rect> { static constexpr const OpaqueKind kind = OpaqueKind::CV_RECT; };
|
||||
|
||||
// Describe G-API types (G-types) with traits. Mostly used by
|
||||
// cv::GArg to store meta information about types passed into
|
||||
// operation arguments. Please note that cv::GComputation is
|
||||
// defined on GProtoArgs, not GArgs!
|
||||
//
|
||||
// spec is a type specialization (makes sense for GArray<> and GOpaque<>)
|
||||
// for the rest, it is just OPAQUE_VAL by default.
|
||||
template<typename T> struct GTypeTraits;
|
||||
template<typename T> struct GTypeTraits
|
||||
{
|
||||
static constexpr const ArgKind kind = ArgKind::OPAQUE_VAL;
|
||||
static constexpr const ArgSpec spec = ArgSpec::OPAQUE_SPEC;
|
||||
static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN;
|
||||
};
|
||||
template<> struct GTypeTraits<cv::GMat>
|
||||
{
|
||||
static constexpr const ArgKind kind = ArgKind::GMAT;
|
||||
static constexpr const GShape shape = GShape::GMAT;
|
||||
static constexpr const ArgSpec spec = ArgSpec::OPAQUE_SPEC;
|
||||
static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN;
|
||||
};
|
||||
template<> struct GTypeTraits<cv::GMatP>
|
||||
{
|
||||
static constexpr const ArgKind kind = ArgKind::GMATP;
|
||||
static constexpr const GShape shape = GShape::GMAT;
|
||||
static constexpr const ArgSpec spec = ArgSpec::OPAQUE_SPEC;
|
||||
static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN;
|
||||
};
|
||||
template<> struct GTypeTraits<cv::GFrame>
|
||||
{
|
||||
static constexpr const ArgKind kind = ArgKind::GFRAME;
|
||||
static constexpr const GShape shape = GShape::GMAT;
|
||||
static constexpr const ArgSpec spec = ArgSpec::OPAQUE_SPEC;
|
||||
static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN;
|
||||
};
|
||||
template<> struct GTypeTraits<cv::GScalar>
|
||||
{
|
||||
static constexpr const ArgKind kind = ArgKind::GSCALAR;
|
||||
static constexpr const GShape shape = GShape::GSCALAR;
|
||||
static constexpr const ArgSpec spec = ArgSpec::OPAQUE_SPEC;
|
||||
static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN;
|
||||
};
|
||||
template<class T> struct GTypeTraits<cv::GArray<T> >
|
||||
{
|
||||
static constexpr const ArgKind kind = ArgKind::GARRAY;
|
||||
static constexpr const GShape shape = GShape::GARRAY;
|
||||
static constexpr const ArgSpec spec = GSpecTraits<T>::spec;
|
||||
static constexpr const OpaqueKind op_kind = GOpaqueTraits<T>::kind;
|
||||
using host_type = std::vector<T>;
|
||||
using strip_type = cv::detail::VectorRef;
|
||||
static cv::detail::GArrayU wrap_value(const cv::GArray<T> &t) { return t.strip();}
|
||||
@ -143,7 +90,7 @@ namespace detail
|
||||
{
|
||||
static constexpr const ArgKind kind = ArgKind::GOPAQUE;
|
||||
static constexpr const GShape shape = GShape::GOPAQUE;
|
||||
static constexpr const ArgSpec spec = GSpecTraits<T>::spec;
|
||||
static constexpr const OpaqueKind op_kind = GOpaqueTraits<T>::kind;
|
||||
using host_type = T;
|
||||
using strip_type = cv::detail::OpaqueRef;
|
||||
static cv::detail::GOpaqueU wrap_value(const cv::GOpaque<T> &t) { return t.strip();}
|
||||
@ -176,7 +123,6 @@ namespace detail
|
||||
template<> struct GTypeOf<cv::Scalar> { using type = cv::GScalar; };
|
||||
template<typename U> struct GTypeOf<std::vector<U> > { using type = cv::GArray<U>; };
|
||||
template<typename U> struct GTypeOf { using type = cv::GOpaque<U>;};
|
||||
|
||||
// FIXME: This is not quite correct since IStreamSource may produce not only Mat but also Scalar
|
||||
// and vector data. TODO: Extend the type dispatching on these types too.
|
||||
template<> struct GTypeOf<cv::gapi::wip::IStreamSource::Ptr> { using type = cv::GMat;};
|
||||
|
@ -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 Intel Corporation
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
|
||||
|
||||
#include "precomp.hpp"
|
||||
@ -35,6 +35,11 @@ void cv::detail::GArrayU::setConstructFcn(ConstructVec &&cv)
|
||||
m_priv->ctor = std::move(cv);
|
||||
}
|
||||
|
||||
void cv::detail::GArrayU::setKind(cv::detail::OpaqueKind kind)
|
||||
{
|
||||
m_priv->kind = kind;
|
||||
}
|
||||
|
||||
namespace cv {
|
||||
std::ostream& operator<<(std::ostream& os, const cv::GArrayDesc &)
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2019 Intel Corporation
|
||||
// Copyright (C) 2019-2020 Intel Corporation
|
||||
|
||||
|
||||
#include "precomp.hpp"
|
||||
@ -35,6 +35,11 @@ void cv::detail::GOpaqueU::setConstructFcn(ConstructOpaque &&co)
|
||||
m_priv->ctor = std::move(co);
|
||||
}
|
||||
|
||||
void cv::detail::GOpaqueU::setKind(cv::detail::OpaqueKind kind)
|
||||
{
|
||||
m_priv->kind = kind;
|
||||
}
|
||||
|
||||
namespace cv {
|
||||
std::ostream& operator<<(std::ostream& os, const cv::GOpaqueDesc &)
|
||||
{
|
||||
|
@ -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 Intel Corporation
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
|
||||
|
||||
#include "precomp.hpp"
|
||||
@ -14,13 +14,14 @@
|
||||
cv::GOrigin::GOrigin(GShape s,
|
||||
const cv::GNode& n,
|
||||
std::size_t p,
|
||||
const cv::gimpl::HostCtor c)
|
||||
: shape(s), node(n), port(p), ctor(c)
|
||||
const cv::gimpl::HostCtor c,
|
||||
cv::detail::OpaqueKind k)
|
||||
: shape(s), node(n), port(p), ctor(c), kind(k)
|
||||
{
|
||||
}
|
||||
|
||||
cv::GOrigin::GOrigin(GShape s, cv::gimpl::ConstVal v)
|
||||
: shape(s), node(cv::GNode::Const()), value(v), port(INVALID_PORT)
|
||||
: shape(s), node(cv::GNode::Const()), value(v), port(INVALID_PORT), kind(cv::detail::OpaqueKind::CV_UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2,8 +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 Intel Corporation
|
||||
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
|
||||
#ifndef OPENCV_GAPI_GORIGIN_HPP
|
||||
#define OPENCV_GAPI_GORIGIN_HPP
|
||||
@ -30,7 +29,8 @@ struct GOrigin
|
||||
GOrigin(GShape s,
|
||||
const GNode& n,
|
||||
std::size_t p = INVALID_PORT,
|
||||
const gimpl::HostCtor h = {});
|
||||
const gimpl::HostCtor h = {},
|
||||
cv::detail::OpaqueKind kind = cv::detail::OpaqueKind::CV_UNKNOWN);
|
||||
GOrigin(GShape s, gimpl::ConstVal value);
|
||||
|
||||
const GShape shape; // Shape of a produced object
|
||||
@ -38,6 +38,7 @@ struct GOrigin
|
||||
const gimpl::ConstVal value; // Node can have initial constant value, now only scalar is supported
|
||||
const std::size_t port; // GNode's output number; FIXME: "= max_size" in C++14
|
||||
gimpl::HostCtor ctor; // FIXME: replace with an interface?
|
||||
detail::OpaqueKind kind; // primary is needed for GOpaque and GArray
|
||||
};
|
||||
|
||||
namespace detail
|
||||
|
@ -44,6 +44,8 @@ std::vector<char> cv::gapi::serialize(const cv::GRunArgs& ra)
|
||||
return os.data();
|
||||
}
|
||||
|
||||
// FIXME: This function should move from S11N to GRunArg-related entities.
|
||||
// it has nothing to do with the S11N as it is
|
||||
cv::GRunArgsP cv::gapi::bind(cv::GRunArgs &results)
|
||||
{
|
||||
cv::GRunArgsP outputs;
|
||||
@ -77,3 +79,36 @@ cv::GRunArgsP cv::gapi::bind(cv::GRunArgs &results)
|
||||
}
|
||||
return outputs;
|
||||
}
|
||||
|
||||
// FIXME: move it out of s11n to api/
|
||||
// FIXME: don't we have such function already?
|
||||
cv::GRunArg cv::gapi::bind(cv::GRunArgP &out)
|
||||
{
|
||||
using T = cv::GRunArgP;
|
||||
switch (out.index())
|
||||
{
|
||||
#if !defined(GAPI_STANDALONE)
|
||||
case T::index_of<cv::UMat*>() :
|
||||
GAPI_Assert(false && "Please implement this!");
|
||||
break;
|
||||
#endif
|
||||
|
||||
case T::index_of<cv::detail::VectorRef>() :
|
||||
return cv::GRunArg(cv::util::get<cv::detail::VectorRef>(out));
|
||||
|
||||
case T::index_of<cv::detail::OpaqueRef>() :
|
||||
return cv::GRunArg(cv::util::get<cv::detail::OpaqueRef>(out));
|
||||
|
||||
case T::index_of<cv::Mat*>() :
|
||||
return cv::GRunArg(*cv::util::get<cv::Mat*>(out));
|
||||
|
||||
case T::index_of<cv::Scalar*>() :
|
||||
return cv::GRunArg(*cv::util::get<cv::Scalar*>(out));
|
||||
|
||||
default:
|
||||
// ...maybe our types were extended
|
||||
GAPI_Assert(false && "This value type is UNKNOWN!");
|
||||
break;
|
||||
}
|
||||
return cv::GRunArg();
|
||||
}
|
||||
|
@ -292,25 +292,85 @@ I::IStream& operator >> (I::IStream& is, cv::gapi::wip::IStreamSource::Ptr &)
|
||||
return is;
|
||||
}
|
||||
|
||||
I::OStream& operator<< (I::OStream& os, const cv::detail::VectorRef &)
|
||||
namespace
|
||||
{
|
||||
GAPI_Assert(false && "Serialization: Unsupported << for cv::detail::VectorRef &");
|
||||
template<typename Ref, typename T, typename... Ts>
|
||||
struct putToStream;
|
||||
|
||||
template<typename Ref>
|
||||
struct putToStream<Ref, std::tuple<>>
|
||||
{
|
||||
static void put(I::OStream&, const Ref &)
|
||||
{
|
||||
GAPI_Assert(false && "Unsupported type for GArray/GOpaque serialization");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ref, typename T, typename... Ts>
|
||||
struct putToStream<Ref, std::tuple<T, Ts...>>
|
||||
{
|
||||
static void put(I::OStream& os, const Ref &r)
|
||||
{
|
||||
if (r.getKind() == cv::detail::GOpaqueTraits<T>::kind) {
|
||||
os << r.template rref<T>();
|
||||
} else {
|
||||
putToStream<Ref, std::tuple<Ts...> >::put(os, r);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ref, typename T, typename... Ts>
|
||||
struct getFromStream;
|
||||
|
||||
template<typename Ref>
|
||||
struct getFromStream<Ref, std::tuple<>>
|
||||
{
|
||||
static void get(I::IStream&, Ref &, cv::detail::OpaqueKind)
|
||||
{
|
||||
GAPI_Assert(false && "Unsupported type for GArray/GOpaque deserialization");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ref, typename T, typename... Ts>
|
||||
struct getFromStream<Ref, std::tuple<T, Ts...>>
|
||||
{
|
||||
static void get(I::IStream& is, Ref &r, cv::detail::OpaqueKind kind) {
|
||||
if (kind == cv::detail::GOpaqueTraits<T>::kind) {
|
||||
r.template reset<T>();
|
||||
auto& val = r.template wref<T>();
|
||||
is >> val;
|
||||
} else {
|
||||
getFromStream<Ref, std::tuple<Ts...> >::get(is, r, kind);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
I::OStream& operator<< (I::OStream& os, const cv::detail::VectorRef& ref)
|
||||
{
|
||||
os << ref.getKind();
|
||||
putToStream<cv::detail::VectorRef, cv::detail::GOpaqueTraitsArrayTypes>::put(os, ref);
|
||||
return os;
|
||||
}
|
||||
I::IStream& operator >> (I::IStream& is, cv::detail::VectorRef &)
|
||||
I::IStream& operator >> (I::IStream& is, cv::detail::VectorRef& ref)
|
||||
{
|
||||
GAPI_Assert(false && "Serialization: Unsupported >> for cv::detail::VectorRef &");
|
||||
cv::detail::OpaqueKind kind;
|
||||
is >> kind;
|
||||
getFromStream<cv::detail::VectorRef, cv::detail::GOpaqueTraitsArrayTypes>::get(is, ref, kind);
|
||||
return is;
|
||||
}
|
||||
|
||||
I::OStream& operator<< (I::OStream& os, const cv::detail::OpaqueRef &)
|
||||
I::OStream& operator<< (I::OStream& os, const cv::detail::OpaqueRef& ref)
|
||||
{
|
||||
GAPI_Assert(false && "Serialization: Unsupported << for cv::detail::OpaqueRef &");
|
||||
os << ref.getKind();
|
||||
putToStream<cv::detail::OpaqueRef, cv::detail::GOpaqueTraitsOpaqueTypes>::put(os, ref);
|
||||
return os;
|
||||
}
|
||||
I::IStream& operator >> (I::IStream& is, cv::detail::OpaqueRef &)
|
||||
I::IStream& operator >> (I::IStream& is, cv::detail::OpaqueRef& ref)
|
||||
{
|
||||
GAPI_Assert(false && "Serialization: Unsupported >> for cv::detail::OpaqueRef &");
|
||||
cv::detail::OpaqueKind kind;
|
||||
is >> kind;
|
||||
getFromStream<cv::detail::OpaqueRef, cv::detail::GOpaqueTraitsOpaqueTypes>::get(is, ref, kind);
|
||||
return is;
|
||||
}
|
||||
// Enums and structures
|
||||
@ -350,7 +410,6 @@ I::IStream& operator>> (I::IStream& is, cv::gimpl::Data::Storage &s) {
|
||||
return get_enum<cv::gimpl::Data::Storage>(is, s);
|
||||
}
|
||||
|
||||
|
||||
I::OStream& operator<< (I::OStream& os, const cv::GArg &arg) {
|
||||
// Only GOBJREF and OPAQUE_VAL kinds can be serialized/deserialized
|
||||
GAPI_Assert( arg.kind == cv::detail::ArgKind::OPAQUE_VAL
|
||||
@ -376,6 +435,7 @@ I::OStream& operator<< (I::OStream& os, const cv::GArg &arg) {
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
I::IStream& operator>> (I::IStream& is, cv::GArg &arg) {
|
||||
is >> arg.kind >> arg.opaque_kind;
|
||||
|
||||
@ -447,12 +507,50 @@ I::IStream& operator>> (I::IStream& is, cv::gimpl::Op &op) {
|
||||
I::OStream& operator<< (I::OStream& os, const cv::gimpl::Data &d) {
|
||||
// FIXME: HostCtor is not stored here!!
|
||||
// FIXME: Storage may be incorrect for subgraph-to-graph process
|
||||
return os << d.shape << d.rc << d.meta << d.storage;
|
||||
return os << d.shape << d.rc << d.meta << d.storage << d.kind;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename Ref, typename T, typename... Ts>
|
||||
struct initCtor;
|
||||
|
||||
template<typename Ref>
|
||||
struct initCtor<Ref, std::tuple<>>
|
||||
{
|
||||
static void init(cv::gimpl::Data&)
|
||||
{
|
||||
GAPI_Assert(false && "Unsupported type for GArray/GOpaque deserialization");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ref, typename T, typename... Ts>
|
||||
struct initCtor<Ref, std::tuple<T, Ts...>>
|
||||
{
|
||||
static void init(cv::gimpl::Data& d) {
|
||||
if (d.kind == cv::detail::GOpaqueTraits<T>::kind) {
|
||||
static std::function<void(Ref&)> ctor = [](Ref& ref){ref.template reset<T>();};
|
||||
d.ctor = ctor;
|
||||
} else {
|
||||
initCtor<Ref, std::tuple<Ts...> >::init(d);
|
||||
}
|
||||
}
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
I::IStream& operator>> (I::IStream& is, cv::gimpl::Data &d) {
|
||||
// FIXME: HostCtor is not stored here!!
|
||||
// FIXME: Storage may be incorrect for subgraph-to-graph process
|
||||
return is >> d.shape >> d.rc >> d.meta >> d.storage;
|
||||
is >> d.shape >> d.rc >> d.meta >> d.storage >> d.kind;
|
||||
if (d.shape == cv::GShape::GARRAY)
|
||||
{
|
||||
initCtor<cv::detail::VectorRef, cv::detail::GOpaqueTraitsArrayTypes>::init(d);
|
||||
}
|
||||
else if (d.shape == cv::GShape::GOPAQUE)
|
||||
{
|
||||
initCtor<cv::detail::OpaqueRef, cv::detail::GOpaqueTraitsOpaqueTypes>::init(d);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
@ -478,6 +576,14 @@ void serialize( I::OStream& os
|
||||
, const ade::Graph &g
|
||||
, const std::vector<ade::NodeHandle> &nodes) {
|
||||
cv::gimpl::GModel::ConstGraph cg(g);
|
||||
serialize(os, g, cg.metadata().get<cv::gimpl::Protocol>(), nodes);
|
||||
}
|
||||
|
||||
void serialize( I::OStream& os
|
||||
, const ade::Graph &g
|
||||
, const cv::gimpl::Protocol &p
|
||||
, const std::vector<ade::NodeHandle> &nodes) {
|
||||
cv::gimpl::GModel::ConstGraph cg(g);
|
||||
GSerialized s;
|
||||
for (auto &nh : nodes) {
|
||||
switch (cg.metadata(nh).get<NodeType>().t)
|
||||
@ -488,7 +594,7 @@ void serialize( I::OStream& os
|
||||
}
|
||||
}
|
||||
s.m_counter = cg.metadata().get<cv::gimpl::DataObjectCounter>();
|
||||
s.m_proto = cg.metadata().get<cv::gimpl::Protocol>();
|
||||
s.m_proto = p;
|
||||
os << s.m_ops << s.m_datas << s.m_counter << s.m_proto;
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,6 @@ GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GArg &arg);
|
||||
//I::OStream& operator<< (I::OStream& os, const cv::GRunArg &arg);
|
||||
//I::IStream& operator>> (I::IStream& is, cv::GRunArg &arg);
|
||||
|
||||
|
||||
GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::GKernel &k);
|
||||
GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GKernel &k);
|
||||
|
||||
@ -167,6 +166,14 @@ GAPI_EXPORTS void serialize( I::OStream& os
|
||||
, const ade::Graph &g
|
||||
, const std::vector<ade::NodeHandle> &nodes);
|
||||
|
||||
// The top-level serialization routine.
|
||||
// Note it is just a single function which takes a GModel and a list of nodes
|
||||
// and writes the data to the stream (recursively)
|
||||
GAPI_EXPORTS void serialize( I::OStream& os
|
||||
, const ade::Graph &g
|
||||
, const cv::gimpl::Protocol &p
|
||||
, const std::vector<ade::NodeHandle> &nodes);
|
||||
|
||||
// The top-level deserialization routineS.
|
||||
// Unfortunately the deserialization is a two-step process:
|
||||
// 1. First we decode a stream into some intermediate representation
|
||||
|
@ -194,7 +194,7 @@ void cv::gimpl::GCPUExecutable::run(std::vector<InObj> &&input_objs,
|
||||
{
|
||||
const auto &desc = gm.metadata(nh).get<Data>();
|
||||
|
||||
if ( desc.storage == Data::Storage::INTERNAL
|
||||
if ( desc.storage == Data::Storage::INTERNAL // FIXME: to reconsider
|
||||
&& !util::holds_alternative<util::monostate>(desc.ctor))
|
||||
{
|
||||
// FIXME: Note that compile-time constant data objects (like
|
||||
|
@ -614,7 +614,7 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
GAPI_Assert(util::holds_alternative<cv::GArrayDesc>(mm)
|
||||
&& "Non-array inputs are not supported");
|
||||
|
||||
if (op.k.inSpecs[idx] == cv::detail::ArgSpec::RECT) {
|
||||
if (op.k.inKinds[idx] == cv::detail::OpaqueKind::CV_RECT) {
|
||||
// This is a cv::Rect -- configure the IE preprocessing
|
||||
ii->setPrecision(toIE(meta_0.depth));
|
||||
ii->getPreProcess().setResizeAlgorithm(IE::RESIZE_BILINEAR);
|
||||
@ -622,7 +622,7 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
// 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.inSpecs[idx] == cv::detail::ArgSpec::GMAT);
|
||||
GAPI_Assert(op.k.inKinds[idx] == cv::detail::OpaqueKind::CV_MAT);
|
||||
}
|
||||
idx++; // NB: Never forget to increment the counter
|
||||
}
|
||||
@ -666,11 +666,11 @@ struct InferList2: public cv::detail::KernelTag {
|
||||
GAPI_Assert(this_vec.size() == list_size);
|
||||
// Prepare input {{{
|
||||
IE::Blob::Ptr this_blob;
|
||||
if (this_vec.spec() == cv::detail::TypeSpec::RECT) {
|
||||
if (this_vec.getKind() == cv::detail::OpaqueKind::CV_RECT) {
|
||||
// ROI case - create an ROI blob
|
||||
const auto &vec = this_vec.rref<cv::Rect>();
|
||||
this_blob = IE::make_shared_blob(blob_0, toIE(vec[list_idx]));
|
||||
} else if (this_vec.spec() == cv::detail::TypeSpec::MAT) {
|
||||
} else if (this_vec.getKind() == cv::detail::OpaqueKind::CV_MAT) {
|
||||
// Mat case - create a regular blob
|
||||
// FIXME: NOW Assume Mats are always BLOBS (not
|
||||
// images)
|
||||
|
@ -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 Intel Corporation
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
|
||||
|
||||
#include "precomp.hpp"
|
||||
@ -54,7 +54,7 @@ ade::NodeHandle GModel::mkDataNode(GModel::Graph &g, const GOrigin& origin)
|
||||
// associated host-type constructor (e.g. when the array is
|
||||
// somewhere in the middle of the graph).
|
||||
auto ctor_copy = origin.ctor;
|
||||
g.metadata(data_h).set(Data{origin.shape, id, meta, ctor_copy, storage});
|
||||
g.metadata(data_h).set(Data{origin.shape, id, meta, ctor_copy, origin.kind, storage});
|
||||
return data_h;
|
||||
}
|
||||
|
||||
@ -67,8 +67,9 @@ ade::NodeHandle GModel::mkDataNode(GModel::Graph &g, const GShape shape)
|
||||
GMetaArg meta;
|
||||
HostCtor ctor;
|
||||
Data::Storage storage = Data::Storage::INTERNAL; // By default, all objects are marked INTERNAL
|
||||
cv::detail::OpaqueKind kind = cv::detail::OpaqueKind::CV_UNKNOWN;
|
||||
|
||||
g.metadata(data_h).set(Data{shape, id, meta, ctor, storage});
|
||||
g.metadata(data_h).set(Data{shape, id, meta, ctor, kind, storage});
|
||||
return data_h;
|
||||
}
|
||||
|
||||
|
@ -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 Intel Corporation
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
|
||||
|
||||
#ifndef OPENCV_GAPI_GMODEL_HPP
|
||||
@ -26,6 +26,7 @@
|
||||
|
||||
#include <opencv2/gapi/garg.hpp>
|
||||
#include <opencv2/gapi/gkernel.hpp>
|
||||
#include <opencv2/gapi/gcommon.hpp>
|
||||
|
||||
#include "compiler/gobjref.hpp"
|
||||
#include "compiler/gislandmodel.hpp"
|
||||
@ -71,6 +72,7 @@ struct Data
|
||||
int rc;
|
||||
GMetaArg meta;
|
||||
HostCtor ctor; // T-specific helper to deal with unknown types in our code
|
||||
cv::detail::OpaqueKind kind; // FIXME: is needed to store GArray/GOpaque type
|
||||
// FIXME: Why rc+shape+meta is not represented as RcDesc here?
|
||||
|
||||
enum class Storage: int
|
||||
|
@ -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 Intel Corporation
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -139,7 +139,7 @@ cv::gimpl::Unrolled cv::gimpl::unrollExpr(const GProtoArgs &ins,
|
||||
std::size_t port = ade::util::index(it);
|
||||
GShape shape = ade::util::value(it);
|
||||
|
||||
GOrigin org { shape, node, port};
|
||||
GOrigin org { shape, node, port, {}, origin.kind };
|
||||
origins.insert(org);
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,6 @@ namespace detail
|
||||
template<> struct GTypeTraits<cv::gimpl::RcDesc>
|
||||
{
|
||||
static constexpr const ArgKind kind = ArgKind::GOBJREF;
|
||||
static constexpr const ArgSpec spec = ArgSpec::OPAQUE_SPEC;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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 Intel Corporation
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
|
||||
|
||||
#include "precomp.hpp"
|
||||
@ -94,18 +94,21 @@ void cv::gimpl::passes::inferMeta(ade::passes::PassContext &ctx, bool meta_is_in
|
||||
GAPI_Assert(gr.metadata(output_nh).get<NodeType>().t == NodeType::DATA);
|
||||
|
||||
auto &output_meta = gr.metadata(output_nh).get<Data>().meta;
|
||||
if (!meta_is_initialized && !util::holds_alternative<util::monostate>(output_meta))
|
||||
{
|
||||
GAPI_LOG_INFO(NULL,
|
||||
"!!! Output object has an initialized meta - "
|
||||
"how it is possible today?" << std::endl; );
|
||||
if (output_meta != out_metas.at(output_port))
|
||||
{
|
||||
util::throw_error(std::logic_error("Fatal: meta mismatch"));
|
||||
// FIXME: New exception type?
|
||||
// FIXME: More details!
|
||||
}
|
||||
}
|
||||
|
||||
cv::util::suppress_unused_warning(meta_is_initialized);
|
||||
// FIXME: calling compile() with meta the second time when cannot reshape will lead to error below
|
||||
//if (!meta_is_initialized && !util::holds_alternative<util::monostate>(output_meta))
|
||||
//{
|
||||
// GAPI_LOG_INFO(NULL,
|
||||
// "!!! Output object has an initialized meta - "
|
||||
// "how it is possible today?" << std::endl; );
|
||||
// if (output_meta != out_metas.at(output_port))
|
||||
// {
|
||||
// util::throw_error(std::logic_error("Fatal: meta mismatch"));
|
||||
// // FIXME: New exception type?
|
||||
// // FIXME: More details!
|
||||
// }
|
||||
//}
|
||||
// Store meta in graph
|
||||
output_meta = out_metas.at(output_port);
|
||||
}
|
||||
|
@ -188,18 +188,38 @@ TEST(GArray_VectorRef, TestMov)
|
||||
EXPECT_EQ(V{}, vtest);
|
||||
}
|
||||
|
||||
TEST(GArray_VectorRef, Spec)
|
||||
TEST(GArray_VectorRef, Kind)
|
||||
{
|
||||
cv::detail::VectorRef v1(std::vector<cv::Rect>{});
|
||||
EXPECT_EQ(cv::detail::TypeSpec::RECT, v1.spec());
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_RECT, v1.getKind());
|
||||
|
||||
cv::detail::VectorRef v2(std::vector<cv::Mat>{});
|
||||
EXPECT_EQ(cv::detail::TypeSpec::MAT, v2.spec());
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_MAT, v2.getKind());
|
||||
|
||||
cv::detail::VectorRef v3(std::vector<int>{});
|
||||
EXPECT_EQ(cv::detail::TypeSpec::OPAQUE_SPEC, v3.spec());
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, v3.getKind());
|
||||
|
||||
cv::detail::VectorRef v4(std::vector<std::string>{});
|
||||
EXPECT_EQ(cv::detail::TypeSpec::OPAQUE_SPEC, v4.spec());
|
||||
cv::detail::VectorRef v4(std::vector<double>{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_DOUBLE, v4.getKind());
|
||||
|
||||
cv::detail::VectorRef v5(std::vector<cv::Scalar>{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_SCALAR, v5.getKind());
|
||||
|
||||
cv::detail::VectorRef v6(std::vector<cv::Point>{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_POINT, v6.getKind());
|
||||
|
||||
cv::detail::VectorRef v7(std::vector<cv::Size>{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_SIZE, v7.getKind());
|
||||
|
||||
cv::detail::VectorRef v8(std::vector<std::string>{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_UNKNOWN, v8.getKind());
|
||||
}
|
||||
|
||||
TEST(GArray_VectorRef, TestRvalue)
|
||||
{
|
||||
// Warning: this test is testing some not-very-public APIs
|
||||
cv::detail::VectorRef vref(std::vector<int>{3, 5, -4});
|
||||
auto v = std::vector<int>{3, 5, -4};
|
||||
EXPECT_EQ(vref.rref<int>(), v);
|
||||
}
|
||||
} // namespace opencv_test
|
||||
|
@ -214,4 +214,25 @@ TEST(GOpaque_OpaqueRef, TestMov)
|
||||
EXPECT_EQ(test, ref.rref<I>()); // ref = test
|
||||
EXPECT_NE(test, mov.rref<I>()); // ref lost the data
|
||||
}
|
||||
|
||||
TEST(GOpaque_OpaqueRef, Kind)
|
||||
{
|
||||
cv::detail::OpaqueRef v1(cv::Rect{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_RECT, v1.getKind());
|
||||
|
||||
cv::detail::OpaqueRef v3(int{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, v3.getKind());
|
||||
|
||||
cv::detail::OpaqueRef v4(double{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_DOUBLE, v4.getKind());
|
||||
|
||||
cv::detail::OpaqueRef v6(cv::Point{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_POINT, v6.getKind());
|
||||
|
||||
cv::detail::OpaqueRef v7(cv::Size{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_SIZE, v7.getKind());
|
||||
|
||||
cv::detail::OpaqueRef v8(std::string{});
|
||||
EXPECT_EQ(cv::detail::OpaqueKind::CV_UNKNOWN, v8.getKind());
|
||||
}
|
||||
} // namespace opencv_test
|
||||
|
@ -76,61 +76,6 @@ TYPED_TEST(GArgKind, RValue)
|
||||
EXPECT_EQ(TestFixture::Kind, arg.kind);
|
||||
}
|
||||
|
||||
// Repeat the same for Spec
|
||||
|
||||
template<class T, cv::detail::ArgSpec Exp>
|
||||
struct ExpectedS
|
||||
{
|
||||
using type = T;
|
||||
static const constexpr cv::detail::ArgSpec spec = Exp;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ArgSpec: public ::testing::Test
|
||||
{
|
||||
using Type = typename T::type;
|
||||
const cv::detail::ArgSpec Spec = T::spec;
|
||||
};
|
||||
|
||||
using Arg_Spec_Types = ::testing::Types
|
||||
<
|
||||
// G-API types
|
||||
ExpectedS<cv::GMat, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::GMatP, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::GFrame, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::GScalar, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::GArray<int>, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::GArray<float>, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::GArray<cv::Point>, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::GArray<cv::Rect>, cv::detail::ArgSpec::RECT>
|
||||
, ExpectedS<cv::GArray<cv::GMat>, cv::detail::ArgSpec::GMAT>
|
||||
, ExpectedS<cv::GOpaque<int>, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::GOpaque<float>, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::GOpaque<cv::Point>, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::GOpaque<cv::Rect>, cv::detail::ArgSpec::RECT>
|
||||
// FIXME: causes internal conflicts in GOpaque/descr_of
|
||||
// , ExpectedS<cv::GOpaque<cv::Mat>, cv::detail::ArgSpec::GMAT>
|
||||
|
||||
// Built-in types
|
||||
, ExpectedS<int, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<float, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<int*, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::Point, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<std::string, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<cv::Mat, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<std::vector<int>, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
, ExpectedS<std::vector<cv::Point>, cv::detail::ArgSpec::OPAQUE_SPEC>
|
||||
>;
|
||||
|
||||
TYPED_TEST_CASE(ArgSpec, Arg_Spec_Types);
|
||||
|
||||
TYPED_TEST(ArgSpec, Basic)
|
||||
{
|
||||
const auto this_spec = cv::detail::GTypeTraits<typename TestFixture::Type>::spec;
|
||||
EXPECT_EQ(TestFixture::Spec, this_spec);
|
||||
}
|
||||
|
||||
// }}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(GArg, HasWrap)
|
||||
@ -170,6 +115,4 @@ TEST(GArg, GOpaqueU)
|
||||
cv::GArg arg2 = cv::GArg(cv::GOpaque<cv::Point>());
|
||||
EXPECT_NO_THROW(arg2.get<cv::detail::GOpaqueU>());
|
||||
}
|
||||
|
||||
|
||||
} // namespace opencv_test
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <ade/util/zip_range.hpp> // util::indexed
|
||||
|
||||
#include <opencv2/gapi/gkernel.hpp>
|
||||
#include <opencv2/gapi/gcommon.hpp>
|
||||
#include "compiler/gmodelbuilder.hpp"
|
||||
#include "compiler/gmodel.hpp" // RcDesc, GModel::init
|
||||
|
||||
@ -27,8 +28,8 @@ namespace
|
||||
return cv::GCall(cv::GKernel{ "gapi.test.unaryop"
|
||||
, ""
|
||||
, nullptr
|
||||
, { D::ArgSpec::OPAQUE_SPEC }
|
||||
, { GShape::GMAT } }).pass(m).yield(0);
|
||||
, { GShape::GMAT }
|
||||
, { D::OpaqueKind::CV_UNKNOWN } }).pass(m).yield(0);
|
||||
}
|
||||
|
||||
cv::GMat binaryOp(cv::GMat m1, cv::GMat m2)
|
||||
@ -36,8 +37,8 @@ namespace
|
||||
return cv::GCall(cv::GKernel{ "gapi.test.binaryOp"
|
||||
, ""
|
||||
, nullptr
|
||||
, { D::ArgSpec::OPAQUE_SPEC, D::ArgSpec::OPAQUE_SPEC }
|
||||
, { GShape::GMAT } }).pass(m1, m2).yield(0);
|
||||
, { GShape::GMAT }
|
||||
, { D::OpaqueKind::CV_UNKNOWN, D::OpaqueKind::CV_UNKNOWN } }).pass(m1, m2).yield(0);
|
||||
}
|
||||
|
||||
std::vector<ade::NodeHandle> collectOperations(const cv::gimpl::GModel::Graph& gr)
|
||||
|
@ -23,6 +23,21 @@ private:
|
||||
std::vector<char> m_buffer;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename T>
|
||||
bool operator==(const cv::detail::VectorRef& a, const cv::detail::VectorRef& b)
|
||||
{
|
||||
return a.rref<T>() == b.rref<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool operator==(const cv::detail::OpaqueRef& a, const cv::detail::OpaqueRef& b)
|
||||
{
|
||||
return a.rref<T>() == b.rref<T>();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(S11N_Basic, Test_int_pos) {
|
||||
int x = 42;
|
||||
put(x);
|
||||
@ -213,6 +228,60 @@ TEST_F(S11N_Basic, Test_RunArgs_Scalar) {
|
||||
EXPECT_EQ(scalar2, out_scalar2);
|
||||
}
|
||||
|
||||
TEST_F(S11N_Basic, Test_RunArg_Opaque) {
|
||||
auto op = cv::detail::OpaqueRef(42);
|
||||
auto v = cv::GRunArg{ op };
|
||||
put(v);
|
||||
cv::GRunArg out_v = get<cv::GRunArg>();
|
||||
cv::detail::OpaqueRef out_op = cv::util::get<cv::detail::OpaqueRef>(out_v);
|
||||
EXPECT_TRUE(operator==<int>(op, out_op));
|
||||
}
|
||||
|
||||
TEST_F(S11N_Basic, Test_RunArgs_Opaque) {
|
||||
cv::detail::OpaqueRef op1 = cv::detail::OpaqueRef(cv::Point(1, 2));
|
||||
cv::detail::OpaqueRef op2 = cv::detail::OpaqueRef(cv::Size(12, 21));
|
||||
GRunArgs v;
|
||||
v.resize(2);
|
||||
v[0] = cv::GRunArg{ op1 };
|
||||
v[1] = cv::GRunArg{ op2 };
|
||||
put(v);
|
||||
cv::GRunArgs out_v = get<cv::GRunArgs>();
|
||||
cv::detail::OpaqueRef out_op1 = cv::util::get<cv::detail::OpaqueRef>(out_v[0]);
|
||||
cv::detail::OpaqueRef out_op2 = cv::util::get<cv::detail::OpaqueRef>(out_v[1]);
|
||||
EXPECT_TRUE(operator==<cv::Point>(op1, out_op1));
|
||||
EXPECT_TRUE(operator==<cv::Size>(op2, out_op2));
|
||||
}
|
||||
|
||||
TEST_F(S11N_Basic, Test_RunArg_Array) {
|
||||
auto op = cv::detail::VectorRef(std::vector<cv::Mat>{cv::Mat::eye(3, 3, CV_8UC1), cv::Mat::zeros(5, 5, CV_8UC3)});
|
||||
|
||||
auto v = cv::GRunArg{ op };
|
||||
put(v);
|
||||
cv::GRunArg out_v = get<cv::GRunArg>();
|
||||
cv::detail::VectorRef out_op = cv::util::get<cv::detail::VectorRef>(out_v);
|
||||
auto vec1 = op.rref<cv::Mat>();
|
||||
auto vec2 = out_op.rref<cv::Mat>();
|
||||
EXPECT_EQ(0, cv::norm(vec1[0], vec2[0], cv::NORM_INF));
|
||||
EXPECT_EQ(0, cv::norm(vec1[1], vec2[1], cv::NORM_INF));
|
||||
}
|
||||
|
||||
TEST_F(S11N_Basic, Test_RunArgs_Array) {
|
||||
auto vec_sc = std::vector<cv::Scalar>{cv::Scalar(11), cv::Scalar(31)};
|
||||
auto vec_d = std::vector<double>{0.4, 1.0, 123.55, 22.08};
|
||||
cv::detail::VectorRef op1 = cv::detail::VectorRef(vec_sc);
|
||||
cv::detail::VectorRef op2 = cv::detail::VectorRef(vec_d);
|
||||
GRunArgs v;
|
||||
v.resize(2);
|
||||
v[0] = cv::GRunArg{ op1 };
|
||||
v[1] = cv::GRunArg{ op2 };
|
||||
put(v);
|
||||
cv::GRunArgs out_v = get<cv::GRunArgs>();
|
||||
cv::detail::VectorRef out_op1 = cv::util::get<cv::detail::VectorRef>(out_v[0]);
|
||||
cv::detail::VectorRef out_op2 = cv::util::get<cv::detail::VectorRef>(out_v[1]);
|
||||
EXPECT_TRUE(operator==<cv::Scalar>(op1, out_op1));
|
||||
EXPECT_TRUE(operator==<double>(op2, out_op2));
|
||||
}
|
||||
|
||||
TEST_F(S11N_Basic, Test_RunArgs_MatScalar) {
|
||||
cv::Mat mat = cv::Mat::eye(cv::Size(64, 64), CV_8UC3);
|
||||
cv::Scalar scalar = cv::Scalar(128, 33, 53);
|
||||
@ -254,7 +323,6 @@ TEST_F(S11N_Basic, Test_Bind_RunArgs_MatScalar) {
|
||||
v[0] = cv::GRunArg{ mat };
|
||||
v[1] = cv::GRunArg{ scalar };
|
||||
GRunArgsP output = cv::gapi::bind(v);
|
||||
std::cout << "output size " << output.size() << std::endl;
|
||||
unsigned int i = 0;
|
||||
for (auto it : output)
|
||||
{
|
||||
|
@ -282,4 +282,206 @@ TEST(S11N, Pipeline_CustomRGB2YUV)
|
||||
}
|
||||
}
|
||||
|
||||
namespace ThisTest
|
||||
{
|
||||
using GOpBool = GOpaque<bool>;
|
||||
using GOpInt = GOpaque<int>;
|
||||
using GOpDouble = GOpaque<double>;
|
||||
using GOpPoint = GOpaque<cv::Point>;
|
||||
using GOpSize = GOpaque<cv::Size>;
|
||||
using GOpRect = GOpaque<cv::Rect>;
|
||||
|
||||
using GOpOut = std::tuple<GOpPoint, GOpSize, GOpRect>;
|
||||
|
||||
G_TYPED_KERNEL_M(OpGenerate, <GOpOut(GOpBool, GOpInt, GOpDouble)>, "test.s11n.gopaque")
|
||||
{
|
||||
static std::tuple<GOpaqueDesc, GOpaqueDesc, GOpaqueDesc> outMeta(const GOpaqueDesc&, const GOpaqueDesc&, const GOpaqueDesc&) {
|
||||
return std::make_tuple(empty_gopaque_desc(), empty_gopaque_desc(), empty_gopaque_desc());
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL(OCVOpGenerate, OpGenerate)
|
||||
{
|
||||
static void run(const bool& b, const int& i, const double& d,
|
||||
cv::Point& p, cv::Size& s, cv::Rect& r)
|
||||
{
|
||||
p = cv::Point(i, i*2);
|
||||
s = b ? cv::Size(42, 42) : cv::Size(7, 7);
|
||||
int ii = static_cast<int>(d);
|
||||
r = cv::Rect(ii, ii, ii, ii);
|
||||
}
|
||||
};
|
||||
|
||||
using GArrInt = GArray<int>;
|
||||
using GArrDouble = GArray<double>;
|
||||
using GArrPoint = GArray<cv::Point>;
|
||||
using GArrSize = GArray<cv::Size>;
|
||||
using GArrRect = GArray<cv::Rect>;
|
||||
using GArrMat = GArray<cv::Mat>;
|
||||
using GArrScalar = GArray<cv::Scalar>;
|
||||
|
||||
using GArrOut = std::tuple<GArrPoint, GArrSize, GArrRect, GArrMat>;
|
||||
|
||||
G_TYPED_KERNEL_M(ArrGenerate, <GArrOut(GArrInt, GArrInt, GArrDouble, GArrScalar)>, "test.s11n.garray")
|
||||
{
|
||||
static std::tuple<GArrayDesc, GArrayDesc, GArrayDesc, GArrayDesc> outMeta(const GArrayDesc&, const GArrayDesc&,
|
||||
const GArrayDesc&, const GArrayDesc&) {
|
||||
return std::make_tuple(empty_array_desc(), empty_array_desc(), empty_array_desc(), empty_array_desc());
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL(OCVArrGenerate, ArrGenerate)
|
||||
{
|
||||
static void run(const std::vector<int>& b, const std::vector<int>& i,
|
||||
const std::vector<double>& d, const std::vector<cv::Scalar>& sc,
|
||||
std::vector<cv::Point>& p, std::vector<cv::Size>& s,
|
||||
std::vector<cv::Rect>& r, std::vector<cv::Mat>& m)
|
||||
{
|
||||
p.clear(); p.resize(b.size());
|
||||
s.clear(); s.resize(b.size());
|
||||
r.clear(); r.resize(b.size());
|
||||
m.clear(); m.resize(b.size());
|
||||
|
||||
for (std::size_t idx = 0; idx < b.size(); ++idx)
|
||||
{
|
||||
p[idx] = cv::Point(i[idx], i[idx]*2);
|
||||
s[idx] = b[idx] == 1 ? cv::Size(42, 42) : cv::Size(7, 7);
|
||||
int ii = static_cast<int>(d[idx]);
|
||||
r[idx] = cv::Rect(ii, ii, ii, ii);
|
||||
m[idx] = cv::Mat(3, 3, CV_8UC1, sc[idx]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
G_TYPED_KERNEL_M(OpArrK1, <std::tuple<GArrInt,GOpSize>(GOpInt, GArrSize)>, "test.s11n.oparrk1")
|
||||
{
|
||||
static std::tuple<GArrayDesc, GOpaqueDesc> outMeta(const GOpaqueDesc&, const GArrayDesc&) {
|
||||
return std::make_tuple(empty_array_desc(), empty_gopaque_desc());
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL(OCVOpArrK1, OpArrK1)
|
||||
{
|
||||
static void run(const int& i, const std::vector<cv::Size>& vs,
|
||||
std::vector<int>& vi, cv::Size& s)
|
||||
{
|
||||
vi.clear(); vi.resize(vs.size());
|
||||
s = cv::Size(i, i);
|
||||
for (std::size_t idx = 0; idx < vs.size(); ++ idx)
|
||||
vi[idx] = vs[idx].area();
|
||||
}
|
||||
};
|
||||
|
||||
G_TYPED_KERNEL_M(OpArrK2, <std::tuple<GOpDouble,GArrPoint>(GArrInt, GOpSize)>, "test.s11n.oparrk2")
|
||||
{
|
||||
static std::tuple<GOpaqueDesc, GArrayDesc> outMeta(const GArrayDesc&, const GOpaqueDesc&) {
|
||||
return std::make_tuple(empty_gopaque_desc(), empty_array_desc());
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL(OCVOpArrK2, OpArrK2)
|
||||
{
|
||||
static void run(const std::vector<int>& vi, const cv::Size& s,
|
||||
double& d, std::vector<cv::Point>& vp)
|
||||
{
|
||||
vp.clear(); vp.resize(vi.size());
|
||||
d = s.area() * 1.5;
|
||||
for (std::size_t idx = 0; idx < vi.size(); ++ idx)
|
||||
vp[idx] = cv::Point(vi[idx], vi[idx]);
|
||||
}
|
||||
};
|
||||
} // namespace ThisTest
|
||||
|
||||
TEST(S11N, Pipeline_GOpaque)
|
||||
{
|
||||
using namespace ThisTest;
|
||||
GOpBool in1;
|
||||
GOpInt in2;
|
||||
GOpDouble in3;
|
||||
|
||||
auto out = OpGenerate::on(in1, in2, in3);
|
||||
cv::GComputation c(cv::GIn(in1, in2, in3), cv::GOut(std::get<0>(out), std::get<1>(out), std::get<2>(out)));
|
||||
|
||||
auto p = cv::gapi::serialize(c);
|
||||
auto dc = cv::gapi::deserialize<cv::GComputation>(p);
|
||||
|
||||
bool b = true;
|
||||
int i = 33;
|
||||
double d = 128.7;
|
||||
cv::Point pp;
|
||||
cv::Size s;
|
||||
cv::Rect r;
|
||||
dc.apply(cv::gin(b, i, d), cv::gout(pp, s, r), cv::compile_args(cv::gapi::kernels<OCVOpGenerate>()));
|
||||
|
||||
EXPECT_EQ(pp, cv::Point(i, i*2));
|
||||
EXPECT_EQ(s, cv::Size(42, 42));
|
||||
int ii = static_cast<int>(d);
|
||||
EXPECT_EQ(r, cv::Rect(ii, ii, ii, ii));
|
||||
}
|
||||
|
||||
TEST(S11N, Pipeline_GArray)
|
||||
{
|
||||
using namespace ThisTest;
|
||||
GArrInt in1, in2;
|
||||
GArrDouble in3;
|
||||
GArrScalar in4;
|
||||
|
||||
auto out = ArrGenerate::on(in1, in2, in3, in4);
|
||||
cv::GComputation c(cv::GIn(in1, in2, in3, in4),
|
||||
cv::GOut(std::get<0>(out), std::get<1>(out),
|
||||
std::get<2>(out), std::get<3>(out)));
|
||||
|
||||
auto p = cv::gapi::serialize(c);
|
||||
auto dc = cv::gapi::deserialize<cv::GComputation>(p);
|
||||
|
||||
std::vector<int> b {1, 0, -1};
|
||||
std::vector<int> i {3, 0 , 59};
|
||||
std::vector<double> d {0.7, 120.5, 44.14};
|
||||
std::vector<cv::Scalar> sc {cv::Scalar::all(10), cv::Scalar::all(15), cv::Scalar::all(99)};
|
||||
std::vector<cv::Point> pp;
|
||||
std::vector<cv::Size> s;
|
||||
std::vector<cv::Rect> r;
|
||||
std::vector<cv::Mat> m;
|
||||
dc.apply(cv::gin(b, i, d, sc), cv::gout(pp, s, r, m), cv::compile_args(cv::gapi::kernels<OCVArrGenerate>()));
|
||||
|
||||
for (std::size_t idx = 0; idx < b.size(); ++idx)
|
||||
{
|
||||
EXPECT_EQ(pp[idx], cv::Point(i[idx], i[idx]*2));
|
||||
EXPECT_EQ(s[idx], b[idx] == 1 ? cv::Size(42, 42) : cv::Size(7, 7));
|
||||
int ii = static_cast<int>(d[idx]);
|
||||
EXPECT_EQ(r[idx], cv::Rect(ii, ii, ii, ii));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(S11N, Pipeline_GArray_GOpaque_Multinode)
|
||||
{
|
||||
using namespace ThisTest;
|
||||
GOpInt in1;
|
||||
GArrSize in2;
|
||||
|
||||
auto tmp = OpArrK1::on(in1, in2);
|
||||
auto out = OpArrK2::on(std::get<0>(tmp), std::get<1>(tmp));
|
||||
|
||||
cv::GComputation c(cv::GIn(in1, in2),
|
||||
cv::GOut(std::get<0>(out), std::get<1>(out)));
|
||||
|
||||
auto p = cv::gapi::serialize(c);
|
||||
auto dc = cv::gapi::deserialize<cv::GComputation>(p);
|
||||
|
||||
int i = 42;
|
||||
std::vector<cv::Size> s{cv::Size(11, 22), cv::Size(13, 18)};
|
||||
double d;
|
||||
std::vector<cv::Point> pp;
|
||||
|
||||
dc.apply(cv::gin(i, s), cv::gout(d, pp), cv::compile_args(cv::gapi::kernels<OCVOpArrK1, OCVOpArrK2>()));
|
||||
|
||||
auto st = cv::Size(i ,i);
|
||||
EXPECT_EQ(d, st.area() * 1.5);
|
||||
|
||||
for (std::size_t idx = 0; idx < s.size(); ++idx)
|
||||
{
|
||||
EXPECT_EQ(pp[idx], cv::Point(s[idx].area(), s[idx].area()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace opencv_test
|
||||
|
Loading…
Reference in New Issue
Block a user