1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

Merge pull request #20163 from smirnov-alexey:as/gapi_serialization_docs

G-API: add documentation on serialization functionality

* Add documentation on serialization/deserialization

* Add docs on bind() methods

* Fix typo

* Docs refactoring

* Fix s11n docs

* Fix deserialize() docs

* Change deserialize docs

* Fix warning

* Address review comments

* Fix sample

* Fix warnings and errors

* Fix docs warnings

* Fix warnings

* Address review comments

* Add prefixes to snippets and fix indentation

* Address review comments and move snippets to a single file
This commit is contained in:
Alexey Smirnov
2021-07-07 22:07:59 +03:00
committed by GitHub
parent c0f63eb21f
commit 59ae0e0013
8 changed files with 338 additions and 55 deletions
+2 -1
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 Intel Corporation
// Copyright (C) 2018-2021 Intel Corporation
#ifndef OPENCV_GAPI_HPP
@@ -19,6 +19,7 @@
@}
@defgroup gapi_std_backends G-API Standard Backends
@defgroup gapi_compile_args G-API Graph Compilation Arguments
@defgroup gapi_serialization G-API Serialization functionality
@}
*/
+36 -5
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-2020 Intel Corporation
// Copyright (C) 2018-2021 Intel Corporation
#ifndef OPENCV_GAPI_GARG_HPP
@@ -171,7 +171,7 @@ using GRunArgs = std::vector<GRunArg>;
* It's an ordinary overload of addition assignment operator.
*
* Example of usage:
* @snippet dynamic_graph.cpp GRunArgs usage
* @snippet modules/gapi/samples/dynamic_graph.cpp GRunArgs usage
*
*/
inline GRunArgs& operator += (GRunArgs &lhs, const GRunArgs &rhs)
@@ -223,7 +223,7 @@ using GRunArgsP = std::vector<GRunArgP>;
* It's an ordinary overload of addition assignment operator.
*
* Example of usage:
* @snippet dynamic_graph.cpp GRunArgsP usage
* @snippet modules/gapi/samples/dynamic_graph.cpp GRunArgsP usage
*
*/
inline GRunArgsP& operator += (GRunArgsP &lhs, const GRunArgsP &rhs)
@@ -235,8 +235,39 @@ inline GRunArgsP& operator += (GRunArgsP &lhs, const GRunArgsP &rhs)
namespace gapi
{
GAPI_EXPORTS cv::GRunArgsP bind(cv::GRunArgs &results);
GAPI_EXPORTS cv::GRunArg bind(cv::GRunArgP &out); // FIXME: think more about it
/**
* \addtogroup gapi_serialization
* @{
*
* @brief G-API functions and classes for serialization and deserialization.
*/
/** @brief Wraps deserialized output GRunArgs to GRunArgsP which can be used by GCompiled.
*
* Since it's impossible to get modifiable output arguments from deserialization
* it needs to be wrapped by this function.
*
* Example of usage:
* @snippet modules/gapi/samples/api_ref_snippets.cpp bind after deserialization
*
* @param out_args deserialized GRunArgs.
* @return the same GRunArgs wrapped in GRunArgsP.
* @see deserialize
*/
GAPI_EXPORTS cv::GRunArgsP bind(cv::GRunArgs &out_args);
/** @brief Wraps output GRunArgsP available during graph execution to GRunArgs which can be serialized.
*
* GRunArgsP is pointer-to-value, so to be serialized they need to be binded to real values
* which this function does.
*
* Example of usage:
* @snippet modules/gapi/samples/api_ref_snippets.cpp bind before serialization
*
* @param out output GRunArgsP available during graph execution.
* @return the same GRunArgsP wrapped in serializable GRunArgs.
* @see serialize
*/
GAPI_EXPORTS cv::GRunArg bind(cv::GRunArgP &out); // FIXME: think more about it
/** @} */
}
template<typename... Ts> inline GRunArgs gin(const Ts&... args)
+1 -1
View File
@@ -71,7 +71,7 @@ public:
* It's an ordinary overload of addition assignment operator.
*
* Example of usage:
* @snippet dynamic_graph.cpp GIOProtoArgs usage
* @snippet modules/gapi/samples/dynamic_graph.cpp GIOProtoArgs usage
*
*/
template<typename Tg>
+143 -40
View File
@@ -17,65 +17,135 @@
namespace cv {
namespace gapi {
/**
* \addtogroup gapi_serialization
* @{
*/
namespace detail {
GAPI_EXPORTS cv::GComputation getGraph(const std::vector<char> &p);
GAPI_EXPORTS cv::GComputation getGraph(const std::vector<char> &bytes);
GAPI_EXPORTS cv::GMetaArgs getMetaArgs(const std::vector<char> &p);
GAPI_EXPORTS cv::GMetaArgs getMetaArgs(const std::vector<char> &bytes);
GAPI_EXPORTS cv::GRunArgs getRunArgs(const std::vector<char> &p);
GAPI_EXPORTS cv::GRunArgs getRunArgs(const std::vector<char> &bytes);
GAPI_EXPORTS std::vector<std::string> getVectorOfStrings(const std::vector<char> &p);
GAPI_EXPORTS std::vector<std::string> getVectorOfStrings(const std::vector<char> &bytes);
template<typename... Types>
cv::GCompileArgs getCompileArgs(const std::vector<char> &p);
cv::GCompileArgs getCompileArgs(const std::vector<char> &bytes);
template<typename RMatAdapterType>
cv::GRunArgs getRunArgsWithRMats(const std::vector<char> &p);
cv::GRunArgs getRunArgsWithRMats(const std::vector<char> &bytes);
} // namespace detail
/** @brief Serialize a graph represented by GComputation into an array of bytes.
*
* Check different overloads for more examples.
* @param c GComputation to serialize.
* @return serialized vector of bytes.
*/
GAPI_EXPORTS std::vector<char> serialize(const cv::GComputation &c);
//namespace{
/** @overload
* @param ca GCompileArgs to serialize.
*/
GAPI_EXPORTS std::vector<char> serialize(const cv::GCompileArgs& ca);
/** @overload
* @param ma GMetaArgs to serialize.
*/
GAPI_EXPORTS std::vector<char> serialize(const cv::GMetaArgs& ma);
/** @overload
* @param ra GRunArgs to serialize.
*/
GAPI_EXPORTS std::vector<char> serialize(const cv::GRunArgs& ra);
/** @overload
* @param vs std::vector<std::string> to serialize.
*/
GAPI_EXPORTS std::vector<char> serialize(const std::vector<std::string>& vs);
/**
* @private
*/
template<typename T> static inline
T deserialize(const std::vector<char> &p);
//} //ananymous namespace
GAPI_EXPORTS std::vector<char> serialize(const cv::GCompileArgs&);
GAPI_EXPORTS std::vector<char> serialize(const cv::GMetaArgs&);
GAPI_EXPORTS std::vector<char> serialize(const cv::GRunArgs&);
GAPI_EXPORTS std::vector<char> serialize(const std::vector<std::string>&);
T deserialize(const std::vector<char> &bytes);
/** @brief Deserialize GComputation from a byte array.
*
* Check different overloads for more examples.
* @param bytes serialized vector of bytes.
* @return deserialized GComputation object.
*/
template<> inline
cv::GComputation deserialize(const std::vector<char> &p) {
return detail::getGraph(p);
cv::GComputation deserialize(const std::vector<char> &bytes) {
return detail::getGraph(bytes);
}
/** @brief Deserialize GMetaArgs from a byte array.
*
* Check different overloads for more examples.
* @param bytes serialized vector of bytes.
* @return deserialized GMetaArgs object.
*/
template<> inline
cv::GMetaArgs deserialize(const std::vector<char> &p) {
return detail::getMetaArgs(p);
cv::GMetaArgs deserialize(const std::vector<char> &bytes) {
return detail::getMetaArgs(bytes);
}
/** @brief Deserialize GRunArgs from a byte array.
*
* Check different overloads for more examples.
* @param bytes serialized vector of bytes.
* @return deserialized GRunArgs object.
*/
template<> inline
cv::GRunArgs deserialize(const std::vector<char> &p) {
return detail::getRunArgs(p);
cv::GRunArgs deserialize(const std::vector<char> &bytes) {
return detail::getRunArgs(bytes);
}
/** @brief Deserialize std::vector<std::string> from a byte array.
*
* Check different overloads for more examples.
* @param bytes serialized vector of bytes.
* @return deserialized std::vector<std::string> object.
*/
template<> inline
std::vector<std::string> deserialize(const std::vector<char> &p) {
return detail::getVectorOfStrings(p);
std::vector<std::string> deserialize(const std::vector<char> &bytes) {
return detail::getVectorOfStrings(bytes);
}
/**
* @brief Deserialize GCompileArgs which types were specified in the template from a byte array.
*
* @note cv::gapi::s11n::detail::S11N template specialization must be provided to make a custom type
* in GCompileArgs deserializable.
*
* @param bytes vector of bytes to deserialize GCompileArgs object from.
* @return GCompileArgs object.
* @see GCompileArgs cv::gapi::s11n::detail::S11N
*/
template<typename T, typename... Types> inline
typename std::enable_if<std::is_same<T, GCompileArgs>::value, GCompileArgs>::
type deserialize(const std::vector<char> &p) {
return detail::getCompileArgs<Types...>(p);
type deserialize(const std::vector<char> &bytes) {
return detail::getCompileArgs<Types...>(bytes);
}
/**
* @brief Deserialize GRunArgs including RMat objects if any from a byte array.
*
* RMat adapter type is specified in the template.
* @note To be used properly specified adapter type must overload its serialize() and
* deserialize() methods.
* @param bytes vector of bytes to deserialize GRunArgs object from.
* @return GRunArgs including RMat objects if any.
* @see RMat
*/
template<typename T, typename RMatAdapterType> inline
typename std::enable_if<std::is_same<T, GRunArgs>::value, GRunArgs>::
type deserialize(const std::vector<char> &p) {
return detail::getRunArgsWithRMats<RMatAdapterType>(p);
type deserialize(const std::vector<char> &bytes) {
return detail::getRunArgsWithRMats<RMatAdapterType>(bytes);
}
} // namespace gapi
} // namespace cv
@@ -83,6 +153,17 @@ type deserialize(const std::vector<char> &p) {
namespace cv {
namespace gapi {
namespace s11n {
/** @brief This structure is an interface for serialization routines.
*
* It's main purpose is to provide multiple overloads for operator<<()
* with basic C++ in addition to OpenCV/G-API types.
*
* This sctructure can be inherited and further extended with additional types.
*
* For example, it is utilized in cv::gapi::s11n::detail::S11N as input parameter
* in serialize() method.
*/
struct GAPI_EXPORTS IOStream {
virtual ~IOStream() = default;
// Define the native support for basic C++ types at the API level:
@@ -99,6 +180,16 @@ struct GAPI_EXPORTS IOStream {
virtual IOStream& operator<< (const std::string&) = 0;
};
/** @brief This structure is an interface for deserialization routines.
*
* It's main purpose is to provide multiple overloads for operator>>()
* with basic C++ in addition to OpenCV/G-API types.
*
* This structure can be inherited and further extended with additional types.
*
* For example, it is utilized in cv::gapi::s11n::detail::S11N as input parameter
* in deserialize() method.
*/
struct GAPI_EXPORTS IIStream {
virtual ~IIStream() = default;
virtual IIStream& operator>> (bool &) = 0;
@@ -116,7 +207,7 @@ struct GAPI_EXPORTS IIStream {
};
namespace detail {
GAPI_EXPORTS std::unique_ptr<IIStream> getInStream(const std::vector<char> &p);
GAPI_EXPORTS std::unique_ptr<IIStream> getInStream(const std::vector<char> &bytes);
} // namespace detail
////////////////////////////////////////////////////////////////////////////////
@@ -146,24 +237,26 @@ GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::Mat &m);
// FIXME: for GRunArgs serailization
#if !defined(GAPI_STANDALONE)
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::UMat &);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::UMat &);
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::UMat & um);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::UMat & um);
#endif // !defined(GAPI_STANDALONE)
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::RMat &r);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::RMat &r);
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::IStreamSource::Ptr &);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::IStreamSource::Ptr &);
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::IStreamSource::Ptr &issptr);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::IStreamSource::Ptr &issptr);
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::detail::VectorRef &);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::VectorRef &);
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::detail::VectorRef &vr);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::VectorRef &vr);
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::detail::OpaqueRef &);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::OpaqueRef &);
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::detail::OpaqueRef &opr);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::OpaqueRef &opr);
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::MediaFrame &);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::MediaFrame &);
/// @private -- Exclude this function from OpenCV documentation
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::MediaFrame &mf);
/// @private -- Exclude this function from OpenCV documentation
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::MediaFrame &mf);
// Generic STL types ////////////////////////////////////////////////////////////////
template<typename K, typename V>
@@ -186,6 +279,7 @@ IIStream& operator>> (IIStream& is, std::map<K, V> &m) {
}
return is;
}
template<typename K, typename V>
IOStream& operator<< (IOStream& os, const std::unordered_map<K, V> &m) {
const uint32_t sz = static_cast<uint32_t>(m.size());
@@ -206,6 +300,7 @@ IIStream& operator>> (IIStream& is, std::unordered_map<K, V> &m) {
}
return is;
}
template<typename T>
IOStream& operator<< (IOStream& os, const std::vector<T> &ts) {
const uint32_t sz = static_cast<uint32_t>(ts.size());
@@ -233,16 +328,19 @@ template<typename V>
IOStream& put_v(IOStream&, const V&, std::size_t) {
GAPI_Assert(false && "variant>>: requested index is invalid");
};
template<typename V, typename X, typename... Xs>
IOStream& put_v(IOStream& os, const V& v, std::size_t x) {
return (x == 0u)
? os << cv::util::get<X>(v)
: put_v<V, Xs...>(os, v, x-1);
}
template<typename V>
IIStream& get_v(IIStream&, V&, std::size_t, std::size_t) {
GAPI_Assert(false && "variant<<: requested index is invalid");
}
template<typename V, typename X, typename... Xs>
IIStream& get_v(IIStream& is, V& v, std::size_t i, std::size_t gi) {
if (i == gi) {
@@ -254,11 +352,13 @@ IIStream& get_v(IIStream& is, V& v, std::size_t i, std::size_t gi) {
}
} // namespace detail
//! @overload
template<typename... Ts>
IOStream& operator<< (IOStream& os, const cv::util::variant<Ts...> &v) {
os << static_cast<uint32_t>(v.index());
return detail::put_v<cv::util::variant<Ts...>, Ts...>(os, v, v.index());
}
//! @overload
template<typename... Ts>
IIStream& operator>> (IIStream& is, cv::util::variant<Ts...> &v) {
int idx = -1;
@@ -268,6 +368,7 @@ IIStream& operator>> (IIStream& is, cv::util::variant<Ts...> &v) {
}
// FIXME: consider a better solution
/// @private -- Exclude this function from OpenCV documentation
template<typename... Ts>
void getRunArgByIdx (IIStream& is, cv::util::variant<Ts...> &v, uint32_t idx) {
is = detail::get_v<cv::util::variant<Ts...>, Ts...>(is, v, 0u, idx);
@@ -351,8 +452,8 @@ cv::GCompileArgs getCompileArgs(const std::vector<char> &sArgs) {
}
template<typename RMatAdapterType>
cv::GRunArgs getRunArgsWithRMats(const std::vector<char> &p) {
std::unique_ptr<cv::gapi::s11n::IIStream> pIs = cv::gapi::s11n::detail::getInStream(p);
cv::GRunArgs getRunArgsWithRMats(const std::vector<char> &bytes) {
std::unique_ptr<cv::gapi::s11n::IIStream> pIs = cv::gapi::s11n::detail::getInStream(bytes);
cv::gapi::s11n::IIStream& is = *pIs;
cv::GRunArgs args;
@@ -367,6 +468,8 @@ cv::GRunArgs getRunArgsWithRMats(const std::vector<char> &p) {
return args;
}
} // namespace detail
/** @} */
} // namespace gapi
} // namespace cv
@@ -2,7 +2,7 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2020 Intel Corporation
// Copyright (C) 2020-2021 Intel Corporation
#ifndef OPENCV_GAPI_S11N_BASE_HPP
#define OPENCV_GAPI_S11N_BASE_HPP
@@ -23,25 +23,54 @@ struct IIStream;
namespace detail {
//! @addtogroup gapi_serialization
//! @{
struct NotImplemented {
};
// The default S11N for custom types is NotImplemented
// Don't! sublass from NotImplemented if you actually implement S11N.
/** @brief This structure allows to implement serialization routines for custom types.
*
* The default S11N for custom types is not implemented.
*
* @note When providing an overloaded implementation for S11N with your type
* don't inherit it from NotImplemented structure.
*
* @note There are lots of overloaded >> and << operators for basic and OpenCV/G-API types
* which can be utilized when serializing a custom type.
*
* Example of usage:
* @snippet modules/gapi/samples/api_ref_snippets.cpp S11N usage
*
*/
template<typename T>
struct S11N: public NotImplemented {
/**
* @brief This function allows user to serialize their custom type.
*
* @note The default overload throws an exception if called. User need to
* properly overload the function to use it.
*/
static void serialize(IOStream &, const T &) {
GAPI_Assert(false && "No serialization routine is provided!");
}
/**
* @brief This function allows user to deserialize their custom type.
*
* @note The default overload throws an exception if called. User need to
* properly overload the function to use it.
*/
static T deserialize(IIStream &) {
GAPI_Assert(false && "No deserialization routine is provided!");
}
};
/// @private -- Exclude this struct from OpenCV documentation
template<typename T> struct has_S11N_spec {
static constexpr bool value = !std::is_base_of<NotImplemented,
S11N<typename std::decay<T>::type>>::value;
};
//! @} gapi_serialization
} // namespace detail
} // namespace s11n