288 lines
9.9 KiB
C++
288 lines
9.9 KiB
C++
|
// 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) 2018-2020 Intel Corporation
|
||
|
|
||
|
|
||
|
#ifndef OPENCV_GAPI_GCOMMON_HPP
|
||
|
#define OPENCV_GAPI_GCOMMON_HPP
|
||
|
|
||
|
#include <functional> // std::hash
|
||
|
#include <vector> // std::vector
|
||
|
#include <type_traits> // decay
|
||
|
|
||
|
#include <opencv2/gapi/opencv_includes.hpp>
|
||
|
|
||
|
#include <opencv2/gapi/util/any.hpp>
|
||
|
#include <opencv2/gapi/util/optional.hpp>
|
||
|
#include <opencv2/gapi/own/exports.hpp>
|
||
|
#include <opencv2/gapi/own/assert.hpp>
|
||
|
#include <opencv2/gapi/render/render_types.hpp>
|
||
|
#include <opencv2/gapi/s11n/base.hpp>
|
||
|
|
||
|
namespace cv {
|
||
|
|
||
|
class GMat; // FIXME: forward declaration for GOpaqueTraits
|
||
|
|
||
|
namespace detail
|
||
|
{
|
||
|
// This is a trait-like structure to mark backend-specific compile arguments
|
||
|
// with tags
|
||
|
template<typename T> struct CompileArgTag;
|
||
|
|
||
|
// These structures are tags which separate kernels and transformations
|
||
|
struct KernelTag
|
||
|
{};
|
||
|
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_INT64, // int64_t user G-API data
|
||
|
CV_DOUBLE, // double user G-API data
|
||
|
CV_FLOAT, // float user G-API data
|
||
|
CV_UINT64, // uint64_t user G-API data
|
||
|
CV_STRING, // std::string user G-API data
|
||
|
CV_POINT, // cv::Point user G-API data
|
||
|
CV_POINT2F, // cv::Point2f 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
|
||
|
CV_DRAW_PRIM, // cv::gapi::wip::draw::Prim 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<int64_t> { static constexpr const OpaqueKind kind = OpaqueKind::CV_INT64; };
|
||
|
template<> struct GOpaqueTraits<double> { static constexpr const OpaqueKind kind = OpaqueKind::CV_DOUBLE; };
|
||
|
template<> struct GOpaqueTraits<float> { static constexpr const OpaqueKind kind = OpaqueKind::CV_FLOAT; };
|
||
|
template<> struct GOpaqueTraits<uint64_t> { static constexpr const OpaqueKind kind = OpaqueKind::CV_UINT64; };
|
||
|
template<> struct GOpaqueTraits<bool> { static constexpr const OpaqueKind kind = OpaqueKind::CV_BOOL; };
|
||
|
template<> struct GOpaqueTraits<std::string> { static constexpr const OpaqueKind kind = OpaqueKind::CV_STRING; };
|
||
|
template<> struct GOpaqueTraits<cv::Size> { static constexpr const OpaqueKind kind = OpaqueKind::CV_SIZE; };
|
||
|
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::Point2f> { static constexpr const OpaqueKind kind = OpaqueKind::CV_POINT2F; };
|
||
|
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; };
|
||
|
template<> struct GOpaqueTraits<cv::gapi::wip::draw::Prim>
|
||
|
{ static constexpr const OpaqueKind kind = OpaqueKind::CV_DRAW_PRIM; };
|
||
|
using GOpaqueTraitsArrayTypes = std::tuple<int, double, float, uint64_t, bool, std::string, cv::Size, cv::Scalar, cv::Point, cv::Point2f,
|
||
|
cv::Mat, cv::Rect, cv::gapi::wip::draw::Prim>;
|
||
|
// GOpaque is not supporting cv::Mat and cv::Scalar since there are GScalar and GMat types
|
||
|
using GOpaqueTraitsOpaqueTypes = std::tuple<int, double, float, uint64_t, bool, std::string, cv::Size, cv::Point, cv::Point2f, cv::Rect,
|
||
|
cv::gapi::wip::draw::Prim>;
|
||
|
} // namespace detail
|
||
|
|
||
|
// This definition is here because it is reused by both public(?) and internal
|
||
|
// modules. Keeping it here wouldn't expose public details (e.g., API-level)
|
||
|
// to components which are internal and operate on a lower-level entities
|
||
|
// (e.g., compiler, backends).
|
||
|
// FIXME: merge with ArgKind?
|
||
|
// FIXME: replace with variant[format desc]?
|
||
|
enum class GShape: int
|
||
|
{
|
||
|
GMAT,
|
||
|
GSCALAR,
|
||
|
GARRAY,
|
||
|
GOPAQUE,
|
||
|
GFRAME,
|
||
|
};
|
||
|
|
||
|
namespace gapi {
|
||
|
namespace s11n {
|
||
|
namespace detail {
|
||
|
template<typename T> struct wrap_serialize;
|
||
|
} // namespace detail
|
||
|
} // namespace s11n
|
||
|
} // namespace gapi
|
||
|
|
||
|
|
||
|
struct GCompileArg;
|
||
|
|
||
|
namespace detail {
|
||
|
template<typename T>
|
||
|
using is_compile_arg = std::is_same<GCompileArg, typename std::decay<T>::type>;
|
||
|
} // namespace detail
|
||
|
|
||
|
// CompileArg is an unified interface over backend-specific compilation
|
||
|
// information
|
||
|
// FIXME: Move to a separate file?
|
||
|
/** \addtogroup gapi_compile_args
|
||
|
* @{
|
||
|
*
|
||
|
* @brief Compilation arguments: data structures controlling the
|
||
|
* compilation process
|
||
|
*
|
||
|
* G-API comes with a number of graph compilation options which can be
|
||
|
* passed to cv::GComputation::apply() or
|
||
|
* cv::GComputation::compile(). Known compilation options are listed
|
||
|
* in this page, while extra backends may introduce their own
|
||
|
* compilation options (G-API transparently accepts _everything_ which
|
||
|
* can be passed to cv::compile_args(), it depends on underlying
|
||
|
* backends if an option would be interpreted or not).
|
||
|
*
|
||
|
* For example, if an example computation is executed like this:
|
||
|
*
|
||
|
* @snippet samples/cpp/tutorial_code/gapi/doc_snippets/api_ref_snippets.cpp graph_decl_apply
|
||
|
*
|
||
|
* Extra parameter specifying which kernels to compile with can be
|
||
|
* passed like this:
|
||
|
*
|
||
|
* @snippet samples/cpp/tutorial_code/gapi/doc_snippets/api_ref_snippets.cpp apply_with_param
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief Represents an arbitrary compilation argument.
|
||
|
*
|
||
|
* Any value can be wrapped into cv::GCompileArg, but only known ones
|
||
|
* (to G-API or its backends) can be interpreted correctly.
|
||
|
*
|
||
|
* Normally objects of this class shouldn't be created manually, use
|
||
|
* cv::compile_args() function which automatically wraps everything
|
||
|
* passed in (a variadic template parameter pack) into a vector of
|
||
|
* cv::GCompileArg objects.
|
||
|
*/
|
||
|
struct GCompileArg
|
||
|
{
|
||
|
public:
|
||
|
// NB: Required for pythnon bindings
|
||
|
GCompileArg() = default;
|
||
|
|
||
|
std::string tag;
|
||
|
|
||
|
// FIXME: use decay in GArg/other trait-based wrapper before leg is shot!
|
||
|
template<typename T, typename std::enable_if<!detail::is_compile_arg<T>::value, int>::type = 0>
|
||
|
explicit GCompileArg(T &&t)
|
||
|
: tag(detail::CompileArgTag<typename std::decay<T>::type>::tag())
|
||
|
, serializeF(cv::gapi::s11n::detail::has_S11N_spec<T>::value ?
|
||
|
&cv::gapi::s11n::detail::wrap_serialize<T>::serialize :
|
||
|
nullptr)
|
||
|
, arg(t)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
template<typename T> T& get()
|
||
|
{
|
||
|
return util::any_cast<T>(arg);
|
||
|
}
|
||
|
|
||
|
template<typename T> const T& get() const
|
||
|
{
|
||
|
return util::any_cast<T>(arg);
|
||
|
}
|
||
|
|
||
|
void serialize(cv::gapi::s11n::IOStream& os) const
|
||
|
{
|
||
|
if (serializeF)
|
||
|
{
|
||
|
serializeF(os, *this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
std::function<void(cv::gapi::s11n::IOStream&, const GCompileArg&)> serializeF;
|
||
|
util::any arg;
|
||
|
};
|
||
|
|
||
|
using GCompileArgs = std::vector<GCompileArg>;
|
||
|
|
||
|
inline cv::GCompileArgs& operator += ( cv::GCompileArgs &lhs,
|
||
|
const cv::GCompileArgs &rhs)
|
||
|
{
|
||
|
lhs.reserve(lhs.size() + rhs.size());
|
||
|
lhs.insert(lhs.end(), rhs.begin(), rhs.end());
|
||
|
return lhs;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Wraps a list of arguments (a parameter pack) into a vector of
|
||
|
* compilation arguments (cv::GCompileArg).
|
||
|
*/
|
||
|
template<typename... Ts> GCompileArgs compile_args(Ts&&... args)
|
||
|
{
|
||
|
return GCompileArgs{ GCompileArg(args)... };
|
||
|
}
|
||
|
|
||
|
namespace gapi
|
||
|
{
|
||
|
/**
|
||
|
* @brief Retrieves particular compilation argument by its type from
|
||
|
* cv::GCompileArgs
|
||
|
*/
|
||
|
template<typename T>
|
||
|
inline cv::util::optional<T> getCompileArg(const cv::GCompileArgs &args)
|
||
|
{
|
||
|
for (auto &compile_arg : args)
|
||
|
{
|
||
|
if (compile_arg.tag == cv::detail::CompileArgTag<T>::tag())
|
||
|
{
|
||
|
return cv::util::optional<T>(compile_arg.get<T>());
|
||
|
}
|
||
|
}
|
||
|
return cv::util::optional<T>();
|
||
|
}
|
||
|
|
||
|
namespace s11n {
|
||
|
namespace detail {
|
||
|
template<typename T> struct wrap_serialize
|
||
|
{
|
||
|
static void serialize(IOStream& os, const GCompileArg& arg)
|
||
|
{
|
||
|
using DT = typename std::decay<T>::type;
|
||
|
S11N<DT>::serialize(os, arg.get<DT>());
|
||
|
}
|
||
|
};
|
||
|
} // namespace detail
|
||
|
} // namespace s11n
|
||
|
} // namespace gapi
|
||
|
|
||
|
/**
|
||
|
* @brief Ask G-API to dump compiled graph in Graphviz format under
|
||
|
* the given file name.
|
||
|
*
|
||
|
* Specifies a graph dump path (path to .dot file to be generated).
|
||
|
* G-API will dump a .dot file under specified path during a
|
||
|
* compilation process if this flag is passed.
|
||
|
*/
|
||
|
struct graph_dump_path
|
||
|
{
|
||
|
std::string m_dump_path;
|
||
|
};
|
||
|
/** @} */
|
||
|
|
||
|
namespace detail
|
||
|
{
|
||
|
template<> struct CompileArgTag<cv::graph_dump_path>
|
||
|
{
|
||
|
static const char* tag() { return "gapi.graph_dump_path"; }
|
||
|
};
|
||
|
}
|
||
|
|
||
|
} // namespace cv
|
||
|
|
||
|
// std::hash overload for GShape
|
||
|
namespace std
|
||
|
{
|
||
|
template<> struct hash<cv::GShape>
|
||
|
{
|
||
|
size_t operator() (cv::GShape sh) const
|
||
|
{
|
||
|
return std::hash<int>()(static_cast<int>(sh));
|
||
|
}
|
||
|
};
|
||
|
} // namespace std
|
||
|
|
||
|
|
||
|
#endif // OPENCV_GAPI_GCOMMON_HPP
|