Commit d7540c9a authored by Dmitry Matveev's avatar Dmitry Matveev Committed by Alexander Alekhin

Merge pull request #13176 from dmatveev:gapi_doxygen

G-API: Doxygen class reference

* G-API Doxygen documentation: covered cv::GComputation

* G-API Doxygen documentation: added sections on compile arguments

* G-API Doxygen documentation: restructuring & more text

* Added new sections (organized API reference into it);
* Documented GCompiled, compile args, backends, etc.

* G-API Doxygen documentation: documented GKernelPackage and added group for meta
parent bea312bd
...@@ -10,6 +10,18 @@ ...@@ -10,6 +10,18 @@
#include <memory> #include <memory>
/** \defgroup gapi G-API framework
@{
@defgroup gapi_main_classes G-API Main Classes
@defgroup gapi_data_objects G-API Data Objects
@{
@defgroup gapi_meta_args G-API Metadata Descriptors
@}
@defgroup gapi_std_backends G-API Standard backends
@defgroup gapi_compile_args G-API Graph Compilation Arguments
@}
*/
#include "opencv2/gapi/gmat.hpp" #include "opencv2/gapi/gmat.hpp"
#include "opencv2/gapi/garray.hpp" #include "opencv2/gapi/garray.hpp"
#include "opencv2/gapi/gcomputation.hpp" #include "opencv2/gapi/gcomputation.hpp"
......
...@@ -33,7 +33,37 @@ namespace gapi ...@@ -33,7 +33,37 @@ namespace gapi
{ {
namespace cpu namespace cpu
{ {
/**
* \addtogroup gapi_std_backends
* @{
*
* @brief G-API backends available in this OpenCV version
*
* G-API backends play a corner stone role in G-API execution
* stack. Every backend is hardware-oriented and thus can run its
* kernels efficiently on the target platform.
*
* Backends are usually "back boxes" for G-API users -- on the API
* side, all backends are represented as different objects of the
* same class cv::gapi::GBackend. User can manipulate with backends
* mainly by specifying which kernels to use or where to look up
* for kernels first.
*
* @sa @ref gapi_hld, cv::gapi::lookup_order()
*/
/**
* @brief Get a reference to CPU (OpenCV) backend.
*
* This is the default backend in G-API at the moment, providing
* broader functional coverage but losing some graph model
* advantages. Provided mostly for reference and prototyping
* purposes.
*
* @sa gapi_std_backends
*/
GAPI_EXPORTS cv::gapi::GBackend backend(); GAPI_EXPORTS cv::gapi::GBackend backend();
/** @} */
} // namespace cpu } // namespace cpu
} // namespace gapi } // namespace gapi
......
...@@ -28,10 +28,21 @@ namespace gapi ...@@ -28,10 +28,21 @@ namespace gapi
{ {
namespace fluid namespace fluid
{ {
/**
* \addtogroup gapi_std_backends G-API Standard backends
* @{
*/
/**
* @brief Get a reference to Fluid backend.
*
* @sa gapi_std_backends
*/
GAPI_EXPORTS cv::gapi::GBackend backend(); GAPI_EXPORTS cv::gapi::GBackend backend();
/** @} */
} // namespace flud } // namespace flud
} // namespace gapi } // namespace gapi
class GAPI_EXPORTS GFluidKernel class GAPI_EXPORTS GFluidKernel
{ {
public: public:
......
...@@ -29,6 +29,10 @@ struct GOrigin; ...@@ -29,6 +29,10 @@ struct GOrigin;
template<typename T> class GArray; template<typename T> class GArray;
/**
* \addtogroup gapi_meta_args
* @{
*/
struct GArrayDesc struct GArrayDesc
{ {
// FIXME: Body // FIXME: Body
...@@ -36,7 +40,9 @@ struct GArrayDesc ...@@ -36,7 +40,9 @@ struct GArrayDesc
bool operator== (const GArrayDesc&) const { return true; } bool operator== (const GArrayDesc&) const { return true; }
}; };
template<typename U> GArrayDesc descr_of(const std::vector<U> &) { return {};} template<typename U> GArrayDesc descr_of(const std::vector<U> &) { return {};}
inline GArrayDesc empty_array_desc() {return {}; } static inline GArrayDesc empty_array_desc() {return {}; }
/** @} */
std::ostream& operator<<(std::ostream& os, const cv::GArrayDesc &desc); std::ostream& operator<<(std::ostream& os, const cv::GArrayDesc &desc);
namespace detail namespace detail
...@@ -218,6 +224,10 @@ namespace detail ...@@ -218,6 +224,10 @@ namespace detail
}; };
} // namespace detail } // namespace detail
/** \addtogroup gapi_data_objects
* @{
*/
template<typename T> class GArray template<typename T> class GArray
{ {
public: public:
...@@ -234,6 +244,8 @@ private: ...@@ -234,6 +244,8 @@ private:
detail::GArrayU m_ref; detail::GArrayU m_ref;
}; };
/** @} */
} // namespace cv } // namespace cv
#endif // OPENCV_GAPI_GARRAY_HPP #endif // OPENCV_GAPI_GARRAY_HPP
...@@ -53,6 +53,41 @@ namespace detail { ...@@ -53,6 +53,41 @@ namespace detail {
// CompileArg is an unified interface over backend-specific compilation // CompileArg is an unified interface over backend-specific compilation
// information // information
// FIXME: Move to a separate file? // FIXME: Move to a separate file?
/** \addtogroup gapi_compile_args
* @{
*
* @brief Compilation arguments: a set of data structures which can be
* passed to control 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 modules/gapi/samples/api_ref_snippets.cpp graph_decl_apply
*
* Extra parameter specifying which kernels to compile with can be
* passed like this:
*
* @snippet modules/gapi/samples/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 GAPI_EXPORTS GCompileArg struct GAPI_EXPORTS GCompileArg
{ {
public: public:
...@@ -82,15 +117,28 @@ private: ...@@ -82,15 +117,28 @@ private:
using GCompileArgs = std::vector<GCompileArg>; using GCompileArgs = std::vector<GCompileArg>;
/**
* Wraps a list of arguments (a parameter pack) into a vector of
* compilation arguments (cv::GCompileArg).
*/
template<typename... Ts> GCompileArgs compile_args(Ts&&... args) template<typename... Ts> GCompileArgs compile_args(Ts&&... args)
{ {
return GCompileArgs{ GCompileArg(args)... }; return GCompileArgs{ GCompileArg(args)... };
} }
/**
* @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 struct graph_dump_path
{ {
std::string m_dump_path; std::string m_dump_path;
}; };
/** @} */
namespace detail namespace detail
{ {
......
...@@ -27,35 +27,190 @@ namespace cv { ...@@ -27,35 +27,190 @@ namespace cv {
// FIXME: In future, there should be a way to name I/O objects and specify it // FIXME: In future, there should be a way to name I/O objects and specify it
// to GCompiled externally (for example, when it is loaded on the target system). // to GCompiled externally (for example, when it is loaded on the target system).
/**
* \addtogroup gapi_main_classes
* @{
*/
/**
* @brief Represents a compiled computation (graph). Can only be used
* with image / data formats & resolutions it was compiled for, with
* some exceptions.
*
* This class represents a product of graph compilation (calling
* cv::GComputation::compile()). Objects of this class actually do
* data processing, and graph execution is incapsulated into objects
* of this class. Execution model itself depends on kernels and
* backends which were using during the compilation, see @ref
* gapi_compile_args for details.
*
* In a general case, GCompiled objects can be applied to data only in
* that formats/resolutions they were compiled for (see @ref
* gapi_meta_args). However, if the underlying backends allow, a
* compiled object can be _reshaped_ to handle data (images) of
* different resolution, though formats and types must remain the same.
*
* GCompiled is very similar to `std::function<>` in its semantics --
* running it looks like a function call in the user code.
*
* At the moment, GCompiled objects are not reentrant -- generally,
* the objects are stateful since graph execution itself is a stateful
* process and this state is now maintained in GCompiled's own memory
* (not on the process stack).
*
* At the same time, two different GCompiled objects produced from the
* single cv::GComputation are completely independent and can be used
* concurrently.
*/
class GAPI_EXPORTS GCompiled class GAPI_EXPORTS GCompiled
{ {
public: public:
/// @private
class GAPI_EXPORTS Priv; class GAPI_EXPORTS Priv;
/**
* @brief Constructs an empty object
*/
GCompiled(); GCompiled();
/**
* @brief Run the compiled computation, a generic version.
*
* @param ins vector of inputs to process.
* @param outs vector of outputs to produce.
*
* Input/output vectors must have the same number of elements as
* defined in the cv::GComputation protocol (at the moment of its
* construction). Shapes of elements also must conform to protocol
* (e.g. cv::Mat needs to be passed where cv::GMat has been
* declared as input, and so on). Run-time exception is generated
* otherwise.
*
* Objects in output vector may remain empty (like cv::Mat) --
* G-API will automatically initialize output objects to proper formats.
*
* @note Don't construct GRunArgs/GRunArgsP objects manually, use
* cv::gin()/cv::gout() wrappers instead.
*/
void operator() (GRunArgs &&ins, GRunArgsP &&outs); // Generic arg-to-arg void operator() (GRunArgs &&ins, GRunArgsP &&outs); // Generic arg-to-arg
#if !defined(GAPI_STANDALONE) #if !defined(GAPI_STANDALONE)
/**
* @brief Execute an unary computation
*
* @overload
* @param in input cv::Mat for unary computation
* @param out output cv::Mat for unary computation
* process.
*/
void operator() (cv::Mat in, cv::Mat &out); // Unary overload void operator() (cv::Mat in, cv::Mat &out); // Unary overload
/**
* @brief Execute an unary computation
*
* @overload
* @param in input cv::Mat for unary computation
* @param out output cv::Scalar for unary computation
* process.
*/
void operator() (cv::Mat in, cv::Scalar &out); // Unary overload (scalar) void operator() (cv::Mat in, cv::Scalar &out); // Unary overload (scalar)
/**
* @brief Execute a binary computation
*
* @overload
* @param in1 first input cv::Mat for binary computation
* @param in2 second input cv::Mat for binary computation
* @param out output cv::Mat for binary computation
* process.
*/
void operator() (cv::Mat in1, cv::Mat in2, cv::Mat &out); // Binary overload void operator() (cv::Mat in1, cv::Mat in2, cv::Mat &out); // Binary overload
/**
* @brief Execute an binary computation
*
* @overload
* @param in1 first input cv::Mat for binary computation
* @param in2 second input cv::Mat for binary computation
* @param out output cv::Scalar for binary computation
* process.
*/
void operator() (cv::Mat in1, cv::Mat in2, cv::Scalar &out); // Binary overload (scalar) void operator() (cv::Mat in1, cv::Mat in2, cv::Scalar &out); // Binary overload (scalar)
/**
* @brief Execute a computation with arbitrary number of
* inputs/outputs.
*
* @overload
* @param ins vector of input cv::Mat objects to process by the
* computation.
* @param outs vector of output cv::Mat objects to produce by the
* computation.
*
* Numbers of elements in ins/outs vectos must match numbers of
* inputs/outputs which were used to define the source GComputation.
*/
void operator() (const std::vector<cv::Mat> &ins, // Compatibility overload void operator() (const std::vector<cv::Mat> &ins, // Compatibility overload
const std::vector<cv::Mat> &outs); const std::vector<cv::Mat> &outs);
#endif // !defined(GAPI_STANDALONE) #endif // !defined(GAPI_STANDALONE)
/// @private
Priv& priv(); Priv& priv();
explicit operator bool () const; // Check if GCompiled is runnable or empty /**
* @brief Check if compiled object is valid (non-empty)
*
* @return true if the object is runnable (valid), false otherwise
*/
explicit operator bool () const;
/**
* @brief Vector of metadata this graph was compiled for.
*
* @return Unless _reshape_ is not supported, return value is the
* same vector which was passed to cv::GComputation::compile() to
* produce this compiled object. Otherwise, it is the latest
* metadata vector passed to reshape() (if that call was
* successful).
*/
const GMetaArgs& metas() const; // Meta passed to compile() const GMetaArgs& metas() const; // Meta passed to compile()
const GMetaArgs& outMetas() const; // Inferred output metadata
bool canReshape() const; // is reshape mechanism supported by GCompiled /**
void reshape(const GMetaArgs& inMetas, const GCompileArgs& args); // run reshape procedure * @brief Vector of metadata descriptions of graph outputs
*
* @return vector with formats/resolutions of graph's output
* objects, auto-inferred from input metadata vector by
* operations which form this computation.
*
* @note GCompiled objects produced from the same
* cv::GComputiation graph with different input metas may return
* different values in this vector.
*/
const GMetaArgs& outMetas() const;
/**
* @brief Check if the underlying backends support reshape or not.
*
* @return true if supported, false otherwise.
*/
bool canReshape() const;
/**
* @brief Reshape a compiled graph to support new image
* resolutions.
*
* Throws an exception if an error occurs.
*
* @param inMetas new metadata to reshape on. Vector size and
* metadata shapes must match the computation's protocol.
* @param args compilation arguments to use.
*/
// FIXME: Why it requires compile args?
void reshape(const GMetaArgs& inMetas, const GCompileArgs& args);
protected: protected:
/// @private
std::shared_ptr<Priv> m_priv; std::shared_ptr<Priv> m_priv;
}; };
/** @} */
} }
......
...@@ -294,34 +294,102 @@ namespace std ...@@ -294,34 +294,102 @@ namespace std
namespace cv { namespace cv {
namespace gapi { namespace gapi {
/** \addtogroup gapi_compile_args
* @{
*/
// Lookup order is in fact a vector of Backends to traverse during look-up // Lookup order is in fact a vector of Backends to traverse during look-up
/**
* @brief Priority list of backends to use during kernel
* resolution process.
*
* Priority is descending -- the first backend in the list has the
* top priority, and the last one has the lowest priority.
*
* If there's multiple implementations available for a kernel at
* the moment of graph compilation, a kernel (and thus a backend)
* will be selected according to this order (if the parameter is passed).
*
* Default order is not specified (and by default, only
* CPU(OpenCV) backend is involved in graph compilation).
*/
using GLookupOrder = std::vector<GBackend>; using GLookupOrder = std::vector<GBackend>;
/**
* @brief Create a backend lookup order -- priority list of
* backends to use during graph compilation process.
*
* @sa GLookupOrder, @ref gapi_std_backends
*/
inline GLookupOrder lookup_order(std::initializer_list<GBackend> &&list) inline GLookupOrder lookup_order(std::initializer_list<GBackend> &&list)
{ {
return GLookupOrder(std::move(list)); return GLookupOrder(std::move(list));
} }
// FIXME: Hide implementation // FIXME: Hide implementation
/**
* @brief A container class for heterogeneous kernel
* implementation collections.
*
* GKernelPackage is a special container class which stores kernel
* _implementations_. Objects of this class are created and passed
* to cv::GComputation::compile() to specify which kernels to use
* in the compiled graph. GKernelPackage may contain kernels of
* different backends, e.g. be heterogeneous.
*
* The most easy way to create a kernel package is to use function
* cv::gapi::kernels(). This template functions takes kernel
* implementations in form of type list (variadic template) and
* generates a kernel package atop of that.
*
* Kernel packages can be also generated programatically, starting
* with an empty package (created with the default constructor)
* and then by populating it with kernels via call to
* GKernelPackage::include(). Note this method is also a template
* one since G-API kernel implementations are _types_, not objects.
*
* Finally, two kernel packages can be combined into a new one
* with function cv::gapi::combine(). There are different rules
* apply to this process, see also cv::gapi::unite_policy for
* details.
*/
class GAPI_EXPORTS GKernelPackage class GAPI_EXPORTS GKernelPackage
{ {
/// @private
using S = std::unordered_map<std::string, GKernelImpl>; using S = std::unordered_map<std::string, GKernelImpl>;
/// @private
using M = std::unordered_map<GBackend, S>; using M = std::unordered_map<GBackend, S>;
/// @private
M m_backend_kernels; M m_backend_kernels;
protected: protected:
/// @private
// Check if package contains ANY implementation of a kernel API // Check if package contains ANY implementation of a kernel API
// by API textual id. // by API textual id.
bool includesAPI(const std::string &id) const; bool includesAPI(const std::string &id) const;
/// @private
// Remove ALL implementations of the given API (identified by ID) // Remove ALL implementations of the given API (identified by ID)
void removeAPI(const std::string &id); void removeAPI(const std::string &id);
public: public:
// Return total number of kernels (accross all backends) /**
* @brief Returns total number of kernels in the package
* (accross all backends included)
*
* @return a number of kernels in the package
*/
std::size_t size() const; std::size_t size() const;
// Check if particular kernel implementation exist in the package. /**
// The key word here is _particular_ - i.e., from the specific backend. * @brief Test if a particular kernel _implementation_ KImpl is
* included in this kernel package.
*
* @sa includesAPI()
*
* @return true if there is such kernel, false otherwise.
*/
template<typename KImpl> template<typename KImpl>
bool includes() const bool includes() const
{ {
...@@ -331,40 +399,71 @@ namespace gapi { ...@@ -331,40 +399,71 @@ namespace gapi {
: false; : false;
} }
// Removes all the kernels related to the given backend /**
* @brief Remove all kernels associated with the given backend
* from the package.
*
* Does nothing if there's no kernels of this backend in the package.
*
* @param backend backend which kernels to remove
*/
void remove(const GBackend& backend); void remove(const GBackend& backend);
/**
* @brief Remove all kernels implementing the given API from
* the package.
*
* Does nothing if there's no kernels implementing the given interface.
*/
template<typename KAPI> template<typename KAPI>
void remove() void remove()
{ {
removeAPI(KAPI::id()); removeAPI(KAPI::id());
} }
// Check if package contains ANY implementation of a kernel API
// by API type.
// FIXME: Rename to includes() and distinguish API/impl case by // FIXME: Rename to includes() and distinguish API/impl case by
// statically? // statically?
/**
* Check if package contains ANY implementation of a kernel API
* by API type.
*/
template<typename KAPI> template<typename KAPI>
bool includesAPI() const bool includesAPI() const
{ {
return includesAPI(KAPI::id()); return includesAPI(KAPI::id());
} }
// Lookup a kernel, given the look-up order. Returns Backend which /**
// hosts kernel implementation. Throws if nothing found. * @brief Find a kernel (by its API), given the look-up order.
// *
// If order is empty(), returns first suitable implementation. * If order is empty, returns first suitable implementation.
* Throws if nothing found.
*
* @return Backend which hosts matching kernel implementation.
*
* @sa cv::gapi::lookup_order
*/
template<typename KAPI> template<typename KAPI>
GBackend lookup(const GLookupOrder &order = {}) const GBackend lookup(const GLookupOrder &order = {}) const
{ {
return lookup(KAPI::id(), order).first; return lookup(KAPI::id(), order).first;
} }
/// @private
std::pair<cv::gapi::GBackend, cv::GKernelImpl> std::pair<cv::gapi::GBackend, cv::GKernelImpl>
lookup(const std::string &id, const GLookupOrder &order = {}) const; lookup(const std::string &id, const GLookupOrder &order = {}) const;
// Put a new kernel implementation into package
// FIXME: No overwrites allowed? // FIXME: No overwrites allowed?
/**
* @brief Put a new kernel implementation KImpl into package.
*
* @param up unite policy to use. If the package has already
* implementation for this kernel (probably from another
* backend), and cv::unite_policy::KEEP is passed, the
* existing implementation remains in package; on
* cv::unite_policy::REPLACE all other existing
* implementations are first dropped from the package.
*/
template<typename KImpl> template<typename KImpl>
void include(const cv::unite_policy up = cv::unite_policy::KEEP) void include(const cv::unite_policy up = cv::unite_policy::KEEP)
{ {
...@@ -378,14 +477,53 @@ namespace gapi { ...@@ -378,14 +477,53 @@ namespace gapi {
m_backend_kernels[backend][kernel_id] = std::move(kernel_impl); m_backend_kernels[backend][kernel_id] = std::move(kernel_impl);
} }
// Lists all backends which are included into package /**
* @brief Lists all backends which are included into package
*
* @return vector of backends
*/
std::vector<GBackend> backends() const; std::vector<GBackend> backends() const;
friend GAPI_EXPORTS GKernelPackage combine(const GKernelPackage &, // TODO: Doxygen bug -- it wants me to place this comment
const GKernelPackage &, // here, not below.
const cv::unite_policy); /**
* @brief Create a new package based on `lhs` and `rhs`,
* with unity policy defined by `policy`.
*
* @param lhs "Left-hand-side" package in the process
* @param rhs "Right-hand-side" package in the process
* @param policy Unite policy which is used in case of conflicts
* -- when the same kernel API is implemented in both packages by
* different backends; cv::unite_policy::KEEP keeps both
* implementation in the resulting package, while
* cv::unite_policy::REPLACE gives precedence two kernels from
* "Right-hand-side".
*
* @return a new kernel package.
*/
friend GAPI_EXPORTS GKernelPackage combine(const GKernelPackage &lhs,
const GKernelPackage &rhs,
const cv::unite_policy policy);
}; };
/**
* @brief Create a kernel package object containing kernels
* specified in variadic template argument.
*
* In G-API, kernel implementations are _types_. Every backend has
* its own kernel API (like GAPI_OCV_KERNEL() and
* GAPI_FLUID_KERNEL()) but all of that APIs define a new type for
* each kernel implementation.
*
* Use this function to pass kernel implementations (defined in
* either way) to the system. Example:
*
* @snippet modules/gapi/samples/api_ref_snippets.cpp kernels_snippet
*
* Note that kernels() itself is a function returning object, not
* a type, so having `()` at the end is important -- it must be a
* function call.
*/
template<typename... KK> GKernelPackage kernels() template<typename... KK> GKernelPackage kernels()
{ {
GKernelPackage pkg; GKernelPackage pkg;
...@@ -402,8 +540,8 @@ namespace gapi { ...@@ -402,8 +540,8 @@ namespace gapi {
return pkg; return pkg;
}; };
// Return a new package based on `lhs` and `rhs`, /** @} */
// with unity policy defined by `policy`.
GAPI_EXPORTS GKernelPackage combine(const GKernelPackage &lhs, GAPI_EXPORTS GKernelPackage combine(const GKernelPackage &lhs,
const GKernelPackage &rhs, const GKernelPackage &rhs,
const cv::unite_policy policy); const cv::unite_policy policy);
......
...@@ -26,6 +26,13 @@ namespace cv ...@@ -26,6 +26,13 @@ namespace cv
class GNode; class GNode;
struct GOrigin; struct GOrigin;
/** \addtogroup gapi_data_objects
* @{
*
* @brief Data-representing objects which can be used to build G-API
* expressions.
*/
class GAPI_EXPORTS GMat class GAPI_EXPORTS GMat
{ {
public: public:
...@@ -39,6 +46,12 @@ private: ...@@ -39,6 +46,12 @@ private:
std::shared_ptr<GOrigin> m_priv; std::shared_ptr<GOrigin> m_priv;
}; };
/** @} */
/**
* \addtogroup gapi_meta_args
* @{
*/
struct GAPI_EXPORTS GMatDesc struct GAPI_EXPORTS GMatDesc
{ {
// FIXME: Default initializers in C++14 // FIXME: Default initializers in C++14
...@@ -122,6 +135,8 @@ GAPI_EXPORTS GMatDesc descr_of(const cv::Mat &mat); ...@@ -122,6 +135,8 @@ GAPI_EXPORTS GMatDesc descr_of(const cv::Mat &mat);
GAPI_EXPORTS GMatDesc descr_of(const cv::UMat &mat); GAPI_EXPORTS GMatDesc descr_of(const cv::UMat &mat);
#endif // !defined(GAPI_STANDALONE) #endif // !defined(GAPI_STANDALONE)
/** @} */
namespace gapi { namespace own { namespace gapi { namespace own {
class Mat; class Mat;
GAPI_EXPORTS GMatDesc descr_of(const Mat &mat); GAPI_EXPORTS GMatDesc descr_of(const Mat &mat);
......
...@@ -31,10 +31,24 @@ namespace gapi ...@@ -31,10 +31,24 @@ namespace gapi
{ {
namespace gpu namespace gpu
{ {
/**
* \addtogroup gapi_std_backends G-API Standard backends
* @{
*/
/**
* @brief Get a reference to GPU backend.
*
* At the moment, the GPU backend is built atop of OpenCV
* "Transparent API" (T-API), see cv::UMat for details.
*
* @sa gapi_std_backends
*/
GAPI_EXPORTS cv::gapi::GBackend backend(); GAPI_EXPORTS cv::gapi::GBackend backend();
/** @} */
} // namespace gpu } // namespace gpu
} // namespace gapi } // namespace gapi
// Represents arguments which are passed to a wrapped GPU function // Represents arguments which are passed to a wrapped GPU function
// FIXME: put into detail? // FIXME: put into detail?
class GAPI_EXPORTS GGPUContext class GAPI_EXPORTS GGPUContext
......
// This file is part of OpenCV project. // This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory // 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. // of this distribution and at http://opencv.org/license.html.
// //
...@@ -22,6 +23,10 @@ namespace cv ...@@ -22,6 +23,10 @@ namespace cv
class GNode; class GNode;
struct GOrigin; struct GOrigin;
/** \addtogroup gapi_data_objects
* @{
*/
class GAPI_EXPORTS GScalar class GAPI_EXPORTS GScalar
{ {
public: public:
...@@ -41,6 +46,12 @@ private: ...@@ -41,6 +46,12 @@ private:
std::shared_ptr<GOrigin> m_priv; std::shared_ptr<GOrigin> m_priv;
}; };
/** @} */
/**
* \addtogroup gapi_meta_args
* @{
*/
struct GScalarDesc struct GScalarDesc
{ {
// NB.: right now it is empty // NB.: right now it is empty
...@@ -58,11 +69,12 @@ struct GScalarDesc ...@@ -58,11 +69,12 @@ struct GScalarDesc
static inline GScalarDesc empty_scalar_desc() { return GScalarDesc(); } static inline GScalarDesc empty_scalar_desc() { return GScalarDesc(); }
GAPI_EXPORTS GScalarDesc descr_of(const cv::gapi::own::Scalar &scalar);
#if !defined(GAPI_STANDALONE) #if !defined(GAPI_STANDALONE)
GAPI_EXPORTS GScalarDesc descr_of(const cv::Scalar &scalar); GAPI_EXPORTS GScalarDesc descr_of(const cv::Scalar &scalar);
#endif // !defined(GAPI_STANDALONE) #endif // !defined(GAPI_STANDALONE)
/** @} */
GAPI_EXPORTS GScalarDesc descr_of(const cv::gapi::own::Scalar &scalar);
std::ostream& operator<<(std::ostream& os, const cv::GScalarDesc &desc); std::ostream& operator<<(std::ostream& os, const cv::GScalarDesc &desc);
......
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>
#include <opencv2/gapi/imgproc.hpp>
#include <opencv2/gapi/cpu/gcpukernel.hpp>
#include <opencv2/gapi/fluid/core.hpp>
#include <opencv2/gapi/fluid/imgproc.hpp>
G_TYPED_KERNEL(IAdd, <cv::GMat(cv::GMat)>, "test.custom.add") {
static cv::GMatDesc outMeta(const cv::GMatDesc &in) { return in; }
};
G_TYPED_KERNEL(IFilter2D, <cv::GMat(cv::GMat)>, "test.custom.filter2d") {
static cv::GMatDesc outMeta(const cv::GMatDesc &in) { return in; }
};
G_TYPED_KERNEL(IRGB2YUV, <cv::GMat(cv::GMat)>, "test.custom.add") {
static cv::GMatDesc outMeta(const cv::GMatDesc &in) { return in; }
};
GAPI_OCV_KERNEL(CustomAdd, IAdd) { static void run(cv::Mat, cv::Mat &) {} };
GAPI_OCV_KERNEL(CustomFilter2D, IFilter2D) { static void run(cv::Mat, cv::Mat &) {} };
GAPI_OCV_KERNEL(CustomRGB2YUV, IRGB2YUV) { static void run(cv::Mat, cv::Mat &) {} };
int main(int argc, char *argv[])
{
if (argc < 3)
return -1;
cv::Mat input = cv::imread(argv[1]);
cv::Mat output;
{
//! [graph_def]
cv::GMat in;
cv::GMat gx = cv::gapi::Sobel(in, CV_32F, 1, 0);
cv::GMat gy = cv::gapi::Sobel(in, CV_32F, 0, 1);
cv::GMat g = cv::gapi::sqrt(cv::gapi::mul(gx, gx) + cv::gapi::mul(gy, gy));
cv::GMat out = cv::gapi::convertTo(g, CV_8U);
//! [graph_def]
//! [graph_decl_apply]
//! [graph_cap_full]
cv::GComputation sobelEdge(cv::GIn(in), cv::GOut(out));
//! [graph_cap_full]
sobelEdge.apply(input, output);
//! [graph_decl_apply]
//! [apply_with_param]
cv::gapi::GKernelPackage kernels = cv::gapi::combine
(cv::gapi::core::fluid::kernels(),
cv::gapi::imgproc::fluid::kernels(),
cv::unite_policy::KEEP);
sobelEdge.apply(input, output, cv::compile_args(kernels));
//! [apply_with_param]
//! [graph_cap_sub]
cv::GComputation sobelEdgeSub(cv::GIn(gx, gy), cv::GOut(out));
//! [graph_cap_sub]
}
//! [graph_gen]
cv::GComputation sobelEdgeGen([](){
cv::GMat in;
cv::GMat gx = cv::gapi::Sobel(in, CV_32F, 1, 0);
cv::GMat gy = cv::gapi::Sobel(in, CV_32F, 0, 1);
cv::GMat g = cv::gapi::sqrt(cv::gapi::mul(gx, gx) + cv::gapi::mul(gy, gy));
cv::GMat out = cv::gapi::convertTo(g, CV_8U);
return cv::GComputation(in, out);
});
//! [graph_gen]
cv::imwrite(argv[2], output);
//! [kernels_snippet]
cv::gapi::GKernelPackage pkg = cv::gapi::kernels
< CustomAdd
, CustomFilter2D
, CustomRGB2YUV
>();
//! [kernels_snippet]
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment