Merge pull request #13176 from dmatveev:gapi_doxygen
authorDmitry Matveev <me@dmitrymatveev.co.uk>
Fri, 16 Nov 2018 20:38:10 +0000 (23:38 +0300)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Fri, 16 Nov 2018 20:38:10 +0000 (23:38 +0300)
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

12 files changed:
modules/gapi/include/opencv2/gapi.hpp
modules/gapi/include/opencv2/gapi/cpu/gcpukernel.hpp
modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp
modules/gapi/include/opencv2/gapi/garray.hpp
modules/gapi/include/opencv2/gapi/gcommon.hpp
modules/gapi/include/opencv2/gapi/gcompiled.hpp
modules/gapi/include/opencv2/gapi/gcomputation.hpp
modules/gapi/include/opencv2/gapi/gkernel.hpp
modules/gapi/include/opencv2/gapi/gmat.hpp
modules/gapi/include/opencv2/gapi/gpu/ggpukernel.hpp
modules/gapi/include/opencv2/gapi/gscalar.hpp
modules/gapi/samples/api_ref_snippets.cpp [new file with mode: 0644]

index 8e5bb06..a043a83 100644 (file)
 
 #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/garray.hpp"
 #include "opencv2/gapi/gcomputation.hpp"
index 02e0612..facaab6 100644 (file)
@@ -33,7 +33,37 @@ namespace gapi
 {
 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();
+    /** @} */
 } // namespace cpu
 } // namespace gapi
 
index fbe0436..c71c5aa 100644 (file)
@@ -28,10 +28,21 @@ namespace gapi
 {
 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();
+    /** @} */
 } // namespace flud
 } // namespace gapi
 
+
 class GAPI_EXPORTS GFluidKernel
 {
 public:
index 33d9b58..87d0015 100644 (file)
@@ -29,6 +29,10 @@ struct GOrigin;
 
 template<typename T> class GArray;
 
+/**
+ * \addtogroup gapi_meta_args
+ * @{
+ */
 struct GArrayDesc
 {
     // FIXME: Body
@@ -36,7 +40,9 @@ struct GArrayDesc
     bool operator== (const GArrayDesc&) const { return true; }
 };
 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);
 
 namespace detail
@@ -218,6 +224,10 @@ namespace detail
     };
 } // namespace detail
 
+/** \addtogroup gapi_data_objects
+ * @{
+ */
+
 template<typename T> class GArray
 {
 public:
@@ -234,6 +244,8 @@ private:
     detail::GArrayU m_ref;
 };
 
+/** @} */
+
 } // namespace cv
 
 #endif // OPENCV_GAPI_GARRAY_HPP
index e84c82c..6a3f51f 100644 (file)
@@ -53,6 +53,41 @@ 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: 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
 {
 public:
@@ -82,15 +117,28 @@ private:
 
 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)
 {
     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
 {
     std::string m_dump_path;
 };
+/** @} */
 
 namespace detail
 {
index 70011a8..ad491b7 100644 (file)
@@ -27,35 +27,190 @@ namespace cv {
 // 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).
 
+/**
+ * \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
 {
 public:
+    /// @private
     class GAPI_EXPORTS Priv;
 
+    /**
+     * @brief Constructs an empty object
+     */
     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
 #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
+
+    /**
+     * @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)
+
+    /**
+     * @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
+
+    /**
+     * @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)
+
+    /**
+     * @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
                      const std::vector<cv::Mat> &outs);
 #endif  // !defined(GAPI_STANDALONE)
+    /// @private
     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& 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:
+    /// @private
     std::shared_ptr<Priv> m_priv;
 };
+/** @} */
 
 }
 
index 4457cfa..e89b9ae 100644 (file)
@@ -35,6 +35,76 @@ namespace detail
     using last_type_t = typename last_type<Ts...>::type;
 }
 
+/**
+ * \addtogroup gapi_main_classes
+ * @{
+ */
+/**
+ * @brief GComputation class represents a captured computation
+ * graph. GComputation objects form boundaries for expression code
+ * user writes with G-API, allowing to compile and execute it.
+ *
+ * G-API computations are defined with input/output data
+ * objects. G-API will track automatically which operations connect
+ * specified outputs to the inputs, forming up a call graph to be
+ * executed. The below example expresses calculation of Sobel operator
+ * for edge detection (\f$G = \sqrt{G_x^2 + G_y^2}\f$):
+ *
+ * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_def
+ *
+ * Full pipeline can be now captured with this object declaration:
+ *
+ * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_cap_full
+ *
+ * Input/output data objects on which a call graph should be
+ * reconstructed are passed using special wrappers cv::GIn and
+ * cv::GOut. G-API will track automatically which operations form a
+ * path from inputs to outputs and build the execution graph appropriately.
+ *
+ * Note that cv::GComputation doesn't take ownership on data objects
+ * it is defined. Moreover, multiple GComputation objects may be
+ * defined on the same expressions, e.g. a smaller pipeline which
+ * expects that image gradients are already pre-calculated may be
+ * defined like this:
+ *
+ * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_cap_sub
+ *
+ * The resulting graph would expect two inputs and produce one
+ * output. In this case, it doesn't matter if gx/gy data objects are
+ * results of cv::gapi::Sobel operators -- G-API will stop unrolling
+ * expressions and building the underlying graph one reaching this
+ * data objects.
+ *
+ * The way how GComputation is defined is important as its definition
+ * specifies graph _protocol_ -- the way how the graph should be
+ * used. Protocol is defined by number of inputs, number of outputs,
+ * and shapes of inputs and outputs.
+ *
+ * In the above example, sobelEdge expects one Mat on input and
+ * produces one Mat; while sobelEdgeSub expects two Mats on input and
+ * produces one Mat. GComputation's protocol defines how other
+ * computaion methods should be used -- cv::GComputation::compile() and
+ * cv::GComputation::apply(). For example, if a graph is defined on
+ * two GMat inputs, two cv::Mat objects have to be passed to apply()
+ * for execution. GComputation checks protocol correctness in runtime
+ * so passing a different number of objects in apply() or passing
+ * cv::Scalar instead of cv::Mat there would compile well as a C++
+ * source but raise an exception in run-time. G-API also comes with a
+ * typed wrapper cv::GComputationT<> which introduces this type-checking in
+ * compile-time.
+ *
+ * cv::GComputation itself is a thin object which just captures what
+ * the graph is. The compiled graph (which actually process data) is
+ * represented by class GCompiled. Use compile() method to generate a
+ * compiled graph with given compile options. cv::GComputation can
+ * also be used to process data with implicit graph compilation
+ * on-the-fly, see apply() for details.
+ *
+ * GComputation is a reference-counted object -- once defined, all its
+ * copies will refer to the same instance.
+ *
+ * @sa GCompiled
+ */
 class GAPI_EXPORTS GComputation
 {
 public:
@@ -43,40 +113,247 @@ public:
 
     // Various constructors enable different ways to define a computation: /////
     // 1. Generic constructors
-    GComputation(const Generator& gen);                // Generator overload
+    /**
+     * @brief Define a computation using a generator function.
+     *
+     * Graph can be defined in-place directly at the moment of its
+     * construction with a lambda:
+     *
+     * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_gen
+     *
+     * This may be useful since all temporary objects (cv::GMats) and
+     * namespaces can be localized to scope of lambda, without
+     * contaminating the parent scope with probably unecessary objects
+     * and information.
+     *
+     * @param gen generator function which returns a cv::GComputation,
+     * see Generator.
+     */
+    GComputation(const Generator& gen);                // Generator
+                                                       // overload
+
+    /**
+     * @brief Generic GComputation constructor.
+     *
+     * Constructs a new graph with a given protocol, specified as a
+     * flow of operations connecting input/output objects. Throws if
+     * the passed boundaries are invalid, e.g. if there's no
+     * functional dependency (path) between given outputs and inputs.
+     *
+     * @param ins Input data vector.
+     * @param outs Output data vector.
+     *
+     * @note Don't construct GProtoInputArgs/GProtoOutputArgs objects
+     * directly, use cv::GIn()/cv::GOut() wrapper functions instead.
+     *
+     * @sa @ref gapi_data_objects
+     */
     GComputation(GProtoInputArgs &&ins,
                  GProtoOutputArgs &&outs);             // Arg-to-arg overload
 
     // 2. Syntax sugar and compatibility overloads
+    /**
+     * @brief Defines an unary (one input -- one output) computation
+     *
+     * @overload
+     * @param in input GMat of the defined unary computation
+     * @param out output GMat of the defined unary computation
+     */
     GComputation(GMat in, GMat out);                   // Unary overload
+
+    /**
+     * @brief Defines an unary (one input -- one output) computation
+     *
+     * @overload
+     * @param in input GMat of the defined unary computation
+     * @param out output GScalar of the defined unary computation
+     */
     GComputation(GMat in, GScalar out);                // Unary overload (scalar)
+
+    /**
+     * @brief Defines a binary (two inputs -- one output) computation
+     *
+     * @overload
+     * @param in1 first input GMat of the defined binary computation
+     * @param in2 second input GMat of the defined binary computation
+     * @param out output GMat of the defined binary computation
+     */
     GComputation(GMat in1, GMat in2, GMat out);        // Binary overload
-    GComputation(GMat in1, GMat in2, GScalar out);     // Binary overload (scalar)
+
+    /**
+     * @brief Defines a binary (two inputs -- one output) computation
+     *
+     * @overload
+     * @param in1 first input GMat of the defined binary computation
+     * @param in2 second input GMat of the defined binary computation
+     * @param out output GScalar of the defined binary computation
+     */
+    GComputation(GMat in1, GMat in2, GScalar out);     // Binary
+                                                       // overload
+                                                       // (scalar)
+
+    /**
+     * @brief Defines a computation with arbitrary input/output number.
+     *
+     * @overload
+     * @param ins vector of inputs GMats for this computation
+     * @param outs vector of outputs GMats for this computation
+     *
+     * Use this overload for cases when number of computation
+     * inputs/outputs is not known in compile-time -- e.g. when graph
+     * is programmatically generated to build an image pyramid with
+     * the given number of levels, etc.
+     */
     GComputation(const std::vector<GMat> &ins,         // Compatibility overload
                  const std::vector<GMat> &outs);
 
     // Various versions of apply(): ////////////////////////////////////////////
     // 1. Generic apply()
+    /**
+     * @brief Compile graph on-the-fly and immediately execute it on
+     * the inputs data vectors.
+     *
+     * Number of input/output data objects must match GComputation's
+     * protocol, also types of host data objects (cv::Mat, cv::Scalar)
+     * must match the shapes of data objects from protocol (cv::GMat,
+     * cv::GScalar). If there's a mismatch, a run-time exception will
+     * be generated.
+     *
+     * Internally, a cv::GCompiled object is created for the given
+     * input format configuration, which then is executed on the input
+     * data immediately. cv::GComputation caches compiled objects
+     * produced within apply() -- if this method would be called next
+     * time with the same input parameters (image formats, image
+     * resolution, etc), the underlying compiled graph will be reused
+     * without recompilation. If new metadata doesn't match the cached
+     * one, the underlying compiled graph is regenerated.
+     *
+     * @note compile() always triggers a compilation process and
+     * produces a new GCompiled object regardless if a similar one has
+     * been cached via apply() or not.
+     *
+     * @param ins vector of input data to process. Don't create
+     * GRunArgs object manually, use cv::gin() wrapper instead.
+     * @param outs vector of output data to fill results in. cv::Mat
+     * objects may be empty in this vector, G-API will automatically
+     * initialize it with the required format & dimensions. Don't
+     * create GRunArgsP object manually, use cv::gout() wrapper instead.
+     * @param args a list of compilation arguments to pass to the
+     * underlying compilation process. Don't create GCompileArgs
+     * object manually, use cv::compile_args() wrapper instead.
+     *
+     * @sa @ref gapi_data_objects, @ref gapi_compile_args
+     */
     void apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args = {});       // Arg-to-arg overload
+
+    /// @private -- Exclude this function from OpenCV documentation
     void apply(const std::vector<cv::gapi::own::Mat>& ins,                        // Compatibility overload
                const std::vector<cv::gapi::own::Mat>& outs,
                GCompileArgs &&args = {});
 
     // 2. Syntax sugar and compatibility overloads
 #if !defined(GAPI_STANDALONE)
+    /**
+     * @brief Execute an unary computation (with compilation on the fly)
+     *
+     * @overload
+     * @param in input cv::Mat for unary computation
+     * @param out output cv::Mat for unary computation
+     * @param args compilation arguments for underlying compilation
+     * process.
+     */
     void apply(cv::Mat in, cv::Mat &out, GCompileArgs &&args = {});               // Unary overload
+
+    /**
+     * @brief Execute an unary computation (with compilation on the fly)
+     *
+     * @overload
+     * @param in input cv::Mat for unary computation
+     * @param out output cv::Scalar for unary computation
+     * @param args compilation arguments for underlying compilation
+     * process.
+     */
     void apply(cv::Mat in, cv::Scalar &out, GCompileArgs &&args = {});            // Unary overload (scalar)
+
+    /**
+     * @brief Execute a binary computation (with compilation on the fly)
+     *
+     * @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
+     * @param args compilation arguments for underlying compilation
+     * process.
+     */
     void apply(cv::Mat in1, cv::Mat in2, cv::Mat &out, GCompileArgs &&args = {}); // Binary overload
+
+    /**
+     * @brief Execute an binary computation (with compilation on the fly)
+     *
+     * @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
+     * @param args compilation arguments for underlying compilation
+     * process.
+     */
     void apply(cv::Mat in1, cv::Mat in2, cv::Scalar &out, GCompileArgs &&args = {}); // Binary overload (scalar)
+
+    /**
+     * @brief Execute a computation with arbitrary number of
+     * inputs/outputs (with compilation on-the-fly).
+     *
+     * @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.
+     * @param args compilation arguments for underlying compilation
+     * process.
+     *
+     * Numbers of elements in ins/outs vectos must match numbers of
+     * inputs/outputs which were used to define this GComputation.
+     */
     void apply(const std::vector<cv::Mat>& ins,         // Compatibility overload
                const std::vector<cv::Mat>& outs,
                GCompileArgs &&args = {});
 #endif // !defined(GAPI_STANDALONE)
     // Various versions of compile(): //////////////////////////////////////////
     // 1. Generic compile() - requires metas to be passed as vector
+    /**
+     * @brief Compile the computation for specific input format(s).
+     *
+     * This method triggers compilation process and produces a new
+     * GCompiled object which then can process data of the given
+     * format. Passing data with different format to the compiled
+     * computation will generate a run-time exception.
+     *
+     * @param in_metas vector of input metadata configuration. Grab
+     * metadata from real data objects (like cv::Mat or cv::Scalar)
+     * using cv::descr_of(), or create it on your own.
+     * @param args compilation arguments for this compilation
+     * process. Compilation arguments directly affect what kind of
+     * executable object would be produced, e.g. which kernels (and
+     * thus, devices) would be used to execute computation.
+     *
+     * @return GCompiled, an executable computation compiled
+     * specifically for the given input parameters.
+     *
+     * @sa @ref gapi_compile_args
+     */
     GCompiled compile(GMetaArgs &&in_metas, GCompileArgs &&args = {});
 
     // 2. Syntax sugar - variadic list of metas, no extra compile args
+    // FIXME: SFINAE looks ugly in the generated documentation
+    /**
+     * @overload
+     *
+     * Takes a variadic parameter pack with metadata
+     * descriptors for which a compiled object needs to be produced.
+     *
+     * @return GCompiled, an executable computation compiled
+     * specifically for the given input parameters.
+     */
     template<typename... Ts>
     auto compile(const Ts&... metas) ->
         typename std::enable_if<detail::are_meta_descrs<Ts...>::value, GCompiled>::type
@@ -94,6 +371,18 @@ public:
     //     GCompiled compile(const Ts&... metas, GCompileArgs &&args)
     //
     // But not all compilers can hande this (and seems they shouldn't be able to).
+    // FIXME: SFINAE looks ugly in the generated documentation
+    /**
+     * @overload
+     *
+     * Takes a  variadic parameter pack with metadata
+     * descriptors for which a compiled object needs to be produced,
+     * followed by GCompileArgs object representing compilation
+     * arguments for this process.
+     *
+     * @return GCompiled, an executable computation compiled
+     * specifically for the given input parameters.
+     */
     template<typename... Ts>
     auto compile(const Ts&... meta_and_compile_args) ->
         typename std::enable_if<detail::are_meta_descrs_but_last<Ts...>::value
@@ -106,12 +395,15 @@ public:
     }
 
     // Internal use only
+    /// @private
     Priv& priv();
+    /// @private
     const Priv& priv() const;
 
 protected:
 
     // 4. Helper method for (3)
+    /// @private
     template<typename... Ts, int... IIs>
     GCompiled compile(const std::tuple<Ts...> &meta_and_compile_args, detail::Seq<IIs...>)
     {
@@ -119,20 +411,45 @@ protected:
         GCompileArgs comp_args = std::get<sizeof...(Ts)-1>(meta_and_compile_args);
         return compile(std::move(meta_args), std::move(comp_args));
     }
-
+    /// @private
     std::shared_ptr<Priv> m_priv;
 };
+/** @} */
 
 namespace gapi
 {
-    // Declare an Island tagged with `name` and defined from `ins` to `outs`
-    // (exclusively, as ins/outs are data objects, and regioning is done on
-    // operations level).
-    // Throws if any operation between `ins` and `outs` are already assigned
-    // to another island.
+    // FIXME: all these standalone functions need to be added to some
+    // common documentation section
+    /**
+     * @brief Define an tagged island (subgraph) within a computation.
+     *
+     * Declare an Island tagged with `name` and defined from `ins` to `outs`
+     * (exclusively, as ins/outs are data objects, and regioning is done on
+     * operations level).
+     * Throws if any operation between `ins` and `outs` are already assigned
+     * to another island.
+     *
+     * Islands allow to partition graph into subgraphs, fine-tuning
+     * the way it is scheduled by the underlying executor.
+     *
+     * @param name name of the Island to create
+     * @param ins vector of input data objects where the subgraph
+     * begins
+     * @param outs vector of output data objects where the subgraph
+     * ends.
+     *
+     * The way how an island is defined is similar to how
+     * cv::GComputation is defined on input/output data objects.
+     * Same rules apply here as well -- if there's no functional
+     * dependency between inputs and outputs or there's not enough
+     * input data objects were specified to properly calculate all
+     * outputs, an exception is thrown.
+     *
+     * Use cv::GIn() / cv::GOut() to specify input/output vectors.
+     */
     void GAPI_EXPORTS island(const std::string &name,
-                           GProtoInputArgs  &&ins,
-                           GProtoOutputArgs &&outs);
+                             GProtoInputArgs  &&ins,
+                             GProtoOutputArgs &&outs);
 } // namespace gapi
 
 } // namespace cv
index 0b6c690..adc7da3 100644 (file)
@@ -294,34 +294,102 @@ namespace std
 
 namespace cv {
 namespace gapi {
+    /** \addtogroup gapi_compile_args
+     * @{
+     */
+
     // 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>;
+    /**
+     * @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)
     {
         return GLookupOrder(std::move(list));
     }
 
     // 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
     {
+        /// @private
         using S = std::unordered_map<std::string, GKernelImpl>;
+
+        /// @private
         using M = std::unordered_map<GBackend, S>;
+
+        /// @private
         M m_backend_kernels;
 
     protected:
+        /// @private
         // Check if package contains ANY implementation of a kernel API
         // by API textual id.
         bool includesAPI(const std::string &id) const;
 
+        /// @private
         // Remove ALL implementations of the given API (identified by ID)
         void removeAPI(const std::string &id);
 
     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;
 
-        // 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>
         bool includes() const
         {
@@ -331,40 +399,71 @@ namespace gapi {
                 : 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);
 
+        /**
+         * @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>
         void remove()
         {
             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
         //     statically?
+        /**
+         * Check if package contains ANY implementation of a kernel API
+         * by API type.
+         */
         template<typename KAPI>
         bool includesAPI() const
         {
             return includesAPI(KAPI::id());
         }
 
-        // Lookup a kernel, given the look-up order. Returns Backend which
-        // hosts kernel implementation. Throws if nothing found.
-        //
-        // If order is empty(), returns first suitable implementation.
+        /**
+         * @brief Find a kernel (by its API), given the look-up order.
+         *
+         * 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>
         GBackend lookup(const GLookupOrder &order = {}) const
         {
             return lookup(KAPI::id(), order).first;
         }
 
+        /// @private
         std::pair<cv::gapi::GBackend, cv::GKernelImpl>
         lookup(const std::string &id, const GLookupOrder &order = {}) const;
 
-        // Put a new kernel implementation into package
         // 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>
         void include(const cv::unite_policy up = cv::unite_policy::KEEP)
         {
@@ -378,14 +477,53 @@ namespace gapi {
             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;
 
-        friend GAPI_EXPORTS GKernelPackage combine(const GKernelPackage  &,
-                                                   const GKernelPackage  &,
-                                                   const cv::unite_policy);
+        // TODO: Doxygen bug -- it wants me to place this comment
+        // here, not below.
+        /**
+         * @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()
     {
         GKernelPackage pkg;
@@ -402,8 +540,8 @@ namespace gapi {
         return pkg;
     };
 
-    // Return a new package based on `lhs` and `rhs`,
-    // with unity policy defined by `policy`.
+    /** @} */
+
     GAPI_EXPORTS GKernelPackage combine(const GKernelPackage  &lhs,
                                         const GKernelPackage  &rhs,
                                         const cv::unite_policy policy);
index c8b3eb7..0fa5342 100644 (file)
@@ -26,6 +26,13 @@ namespace cv
 class GNode;
 struct GOrigin;
 
+/** \addtogroup gapi_data_objects
+ * @{
+ *
+ * @brief Data-representing objects which can be used to build G-API
+ * expressions.
+ */
+
 class GAPI_EXPORTS GMat
 {
 public:
@@ -39,6 +46,12 @@ private:
     std::shared_ptr<GOrigin> m_priv;
 };
 
+/** @} */
+
+/**
+ * \addtogroup gapi_meta_args
+ * @{
+ */
 struct GAPI_EXPORTS GMatDesc
 {
     // FIXME: Default initializers in C++14
@@ -122,6 +135,8 @@ GAPI_EXPORTS GMatDesc descr_of(const cv::Mat &mat);
 GAPI_EXPORTS GMatDesc descr_of(const cv::UMat &mat);
 #endif // !defined(GAPI_STANDALONE)
 
+/** @} */
+
 namespace gapi { namespace own {
     class Mat;
     GAPI_EXPORTS GMatDesc descr_of(const Mat &mat);
index dfae71a..e5a6215 100644 (file)
@@ -31,10 +31,24 @@ namespace gapi
 {
 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();
+    /** @} */
 } // namespace gpu
 } // namespace gapi
 
+
 // Represents arguments which are passed to a wrapped GPU function
 // FIXME: put into detail?
 class GAPI_EXPORTS GGPUContext
index 944f179..dd1205b 100644 (file)
@@ -1,4 +1,5 @@
 // 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.
 //
@@ -22,6 +23,10 @@ namespace cv
 class GNode;
 struct GOrigin;
 
+/** \addtogroup gapi_data_objects
+ * @{
+ */
+
 class GAPI_EXPORTS GScalar
 {
 public:
@@ -41,6 +46,12 @@ private:
     std::shared_ptr<GOrigin> m_priv;
 };
 
+/** @} */
+
+/**
+ * \addtogroup gapi_meta_args
+ * @{
+ */
 struct GScalarDesc
 {
     // NB.: right now it is empty
@@ -58,11 +69,12 @@ struct GScalarDesc
 
 static inline GScalarDesc empty_scalar_desc() { return GScalarDesc(); }
 
-GAPI_EXPORTS GScalarDesc descr_of(const cv::gapi::own::Scalar &scalar);
-
 #if !defined(GAPI_STANDALONE)
 GAPI_EXPORTS GScalarDesc descr_of(const cv::Scalar            &scalar);
 #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);
 
diff --git a/modules/gapi/samples/api_ref_snippets.cpp b/modules/gapi/samples/api_ref_snippets.cpp
new file mode 100644 (file)
index 0000000..5e8859d
--- /dev/null
@@ -0,0 +1,82 @@
+#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;
+}