From b2b6f52d14c94b1cc26c3cd78dbd4b2f49199431 Mon Sep 17 00:00:00 2001 From: Dmitry Matveev Date: Fri, 6 Dec 2019 15:36:02 +0300 Subject: [PATCH] Merge pull request #16050 from dmatveev:dm/ocv42_gapi_doc_fixup * G-API: Addressed various documentation issues - Fixed various typos and missing references; - Added brief documentaion on G_TYPED_KERNEL and G_COMPOUND_KERNEL macros; - Briefly described GComputationT<>; - Briefly described G-API data objects (in a group section). * G-API: Some clean-ups in doxygen, also a chapter on Render API * G-API: Expose more graph compilation arguments in the documentation * G-API: Address documentation review comments --- .../porting_anisotropic_segmentation.markdown | 2 +- modules/gapi/doc/00-root.markdown | 2 +- modules/gapi/doc/10-hld-overview.md | 15 +-- modules/gapi/doc/20-kernel-api.markdown | 10 +- modules/gapi/doc/30-implementation.markdown | 26 +++-- modules/gapi/doc/pics/render_example.png | Bin 0 -> 4392 bytes modules/gapi/include/opencv2/gapi.hpp | 4 +- modules/gapi/include/opencv2/gapi/core.hpp | 4 +- .../opencv2/gapi/fluid/gfluidkernel.hpp | 33 +++++- modules/gapi/include/opencv2/gapi/gcommon.hpp | 8 +- .../include/opencv2/gapi/gcompoundkernel.hpp | 13 ++- .../include/opencv2/gapi/gcomputation.hpp | 2 + modules/gapi/include/opencv2/gapi/gkernel.hpp | 19 ++++ modules/gapi/include/opencv2/gapi/gmat.hpp | 20 +++- modules/gapi/include/opencv2/gapi/gtyped.hpp | 40 +++++++ modules/gapi/include/opencv2/gapi/imgproc.hpp | 2 +- modules/gapi/include/opencv2/gapi/infer.hpp | 4 + .../include/opencv2/gapi/ocl/goclkernel.hpp | 2 +- .../include/opencv2/gapi/plaidml/plaidml.hpp | 12 +- modules/gapi/include/opencv2/gapi/render.hpp | 14 +++ .../include/opencv2/gapi/render/render.hpp | 105 ++++++++++++++++-- modules/gapi/samples/api_ref_snippets.cpp | 41 +++++++ modules/gapi/samples/draw_example.cpp | 56 ++++++++++ modules/gapi/src/api/render.cpp | 24 +--- modules/gapi/src/backends/ie/util.hpp | 3 +- 25 files changed, 386 insertions(+), 75 deletions(-) create mode 100644 modules/gapi/doc/pics/render_example.png create mode 100644 modules/gapi/include/opencv2/gapi/render.hpp create mode 100644 modules/gapi/samples/draw_example.cpp diff --git a/doc/tutorials/gapi/anisotropic_segmentation/porting_anisotropic_segmentation.markdown b/doc/tutorials/gapi/anisotropic_segmentation/porting_anisotropic_segmentation.markdown index cb76af6677..a3f03c986f 100644 --- a/doc/tutorials/gapi/anisotropic_segmentation/porting_anisotropic_segmentation.markdown +++ b/doc/tutorials/gapi/anisotropic_segmentation/porting_anisotropic_segmentation.markdown @@ -157,7 +157,7 @@ Now this file can be visalized with a `dot` command like this: $ dot segm.dot -Tpng -o segm.png -or viewed instantly with `xdot` command (please refer to your +or viewed interactively with `xdot` (please refer to your distribution/operating system documentation on how to install these packages). diff --git a/modules/gapi/doc/00-root.markdown b/modules/gapi/doc/00-root.markdown index bbc90ab44f..2be1e7f8f0 100644 --- a/modules/gapi/doc/00-root.markdown +++ b/modules/gapi/doc/00-root.markdown @@ -64,7 +64,7 @@ included explicitly. The first four lines of `main()` create and initialize OpenCV's standard video capture object, which fetches video frames from either an attached camera or a specified file. -G-API pipelie is constructed next. In fact, it is a series of G-API +G-API pipeline is constructed next. In fact, it is a series of G-API operation calls on cv::GMat data. The important aspect of G-API is that this code block is just a declaration of actions, but not the actions themselves. No processing happens at this point, G-API only diff --git a/modules/gapi/doc/10-hld-overview.md b/modules/gapi/doc/10-hld-overview.md index 1dc5b505d2..557bf08b12 100644 --- a/modules/gapi/doc/10-hld-overview.md +++ b/modules/gapi/doc/10-hld-overview.md @@ -1,11 +1,12 @@ # High-level design overview {#gapi_hld} -# G-API High-level design overview - [TOC] -G-API is a heterogeneous framework and provides single API to program -image processing pipelines with a number of supported backends. +# G-API High-level design overview + +G-API is a heterogeneous framework and provides an unified API to +program image processing pipelines with a number of supported +backends. The key design idea is to keep pipeline code itself platform-neutral while specifying which kernels to use and which devices to utilize @@ -54,7 +55,7 @@ their own kernels easily using a special macro G_TYPED_KERNEL(). API layer is also responsible for marshalling and storing operation parameters on pipeline creation. In addition to the aforementioned G-API dynamic objects, operations may also accept arbitrary -parameters (more on this [below](@ref gapi_detail_params)), so API +parameters (more on this [here](@ref gapi_detail_params)), so API layer captures its values and stores internally upon the moment of execution. @@ -143,7 +144,7 @@ Both methods are polimorphic and take a variadic number of arguments, with validity checks performed in runtime. If a number, shapes, and formats of passed data objects differ from expected, a run-time exception is thrown. G-API also provides _typed_ wrappers to move -these checks to the compile time -- see cv::GComputationT<>. +these checks to the compile time -- see `cv::GComputationT<>`. G-API graph execution is declared stateless -- it means that a compiled functor (cv::GCompiled) acts like a pure C++ function and @@ -154,6 +155,6 @@ number of inputs, and \f$M\f$ is a number of outputs on which a cv::GComputation is defined. Note that while G-API types (cv::GMat, etc) are used in definition, the execution methods accept OpenCV's traditional data types (like cv::Mat) which hold actual data -- see -table in [parameter marshalling](@#gapi_detail_params). +table in [parameter marshalling](@ref gapi_detail_params). @sa @ref gapi_impl, @ref gapi_kernel_api diff --git a/modules/gapi/doc/20-kernel-api.markdown b/modules/gapi/doc/20-kernel-api.markdown index 93b852f6aa..3a94651eaf 100644 --- a/modules/gapi/doc/20-kernel-api.markdown +++ b/modules/gapi/doc/20-kernel-api.markdown @@ -54,10 +54,10 @@ handled in a special way. All other types are opaque to G-API and passed to kernel in `outMeta()` or in execution callbacks as-is. Kernel's return value can _only_ be of G-API dynamic type -- cv::GMat, -cv::GScalar, or cv::GArray. If an operation has more than one output, -it should be wrapped into an `std::tuple<>` (which can contain only -mentioned G-API types). Arbitrary-output-number operations are not -supported. +cv::GScalar, or `cv::GArray`. If an operation has more than one +output, it should be wrapped into an `std::tuple<>` (which can contain +only mentioned G-API types). Arbitrary-output-number operations are +not supported. Once a kernel is defined, it can be used in pipelines with special, G-API-supplied method "::on()". This method has the same signature as @@ -141,7 +141,7 @@ just follow the signature conventions defined by the plugin. G-API will call this method during execution and supply all the necessary information (and forward the original opaque data as-is). -# Compound kernels +# Compound kernels {#gapi_kernel_compound} Sometimes kernel is a single thing only on API level. It is convenient for users, but on a particular implementation side it would be better to diff --git a/modules/gapi/doc/30-implementation.markdown b/modules/gapi/doc/30-implementation.markdown index b1ad3bae93..7ce4b8012e 100644 --- a/modules/gapi/doc/30-implementation.markdown +++ b/modules/gapi/doc/30-implementation.markdown @@ -2,26 +2,28 @@ [TOC] -# G-API Implementation details {#gapi_impl_header} +# G-API Implementation details -## Api layer details {#gapi_detail_api} +Note -- this section is still in progress. -### Expression unrolling {#gapi_detail_expr} +# API layer {#gapi_detail_api} -### Parameter marshalling {#gapi_detail_params} +## Expression unrolling {#gapi_detail_expr} -### Operations representation {#gapi_detail_operations} +## Parameter marshalling {#gapi_detail_params} -## Graph compiler details {#gapi_detail_compiler} +## Operations representation {#gapi_detail_operations} -### ADE basics {#gapi_detail_ade} +# Graph compiler {#gapi_detail_compiler} -### Graph model representation {#gapi_detail_gmodel} +## ADE basics {#gapi_detail_ade} -### G-API metadata and passes {#gapi_detail_meta} +## Graph model representation {#gapi_detail_gmodel} -## Backends details {#gapi_detail_backends} +## G-API metadata and passes {#gapi_detail_meta} -### Backend scope of work {#gapi_backend_scope} +# Backends {#gapi_detail_backends} -### Graph transformation {#gapi_backend_pass} +## Backend scope of work {#gapi_backend_scope} + +## Graph transformation {#gapi_backend_pass} diff --git a/modules/gapi/doc/pics/render_example.png b/modules/gapi/doc/pics/render_example.png new file mode 100644 index 0000000000000000000000000000000000000000..b2675988b3da13bf447fd30c1aced7721ff9c98f GIT binary patch literal 4392 zcmeHLYfw{X8m8;4m?G7NU1^cR3WOxcZABJQFiYf?K)D1hP*^NQxrl&(Q>C;p?!-&R z1&V|KE_Y1Z-L)#P6=K=J24>MffyHsXfKV=}WweGyT49ZGpD*Wxg~Fem*&o}P{y3bI z^L^j@KJWWH@B4iRNkmwX`HNOBnwXfF3xfScCMGX@iRbz?Kf~X+Dvp(j$$E{z-*5NP z7ry!2FVo_8!|(j#{Y|HaS_14R>&td}Z0_~^eBYW=uih4J&V0yonzfz(v?e0JW@dac zVY8E5D*Bg2xk$);CJ}PwQoTQ32n!qWLe7iCi=n!Y@nSlBH(t!Lf8^7(Ubjmo54Y8#XsXTIvWWdQkg$u?*-!*i`}@5{)B;?K{vY3trJUsc$N@KxmxdrHTWG57^Z zOyNj@^}PKXU027r$cHxNo1Ri$Dh7`?w)n5X3$NQnar(}i?lWx?)xk|zK9=N_>D^+r zT5l6s$#Ftrs^SCgrdV6MCmF!krZ zyOh|nu`M1(u2`1e;a8r5S)ZrbQv+|V+vxaNb}#EMiS_vlOAw2`om$fIw&&Ve7pK3>ctN@%kUx{%^~uo7YN5X_Zd7$I-| ze)8I$PfnVb-D}@}0!!)^mNa9@0cwfI`4h+V{xqjl<|%Tz3Vu(jR7Xp4pL@BXvv z#P!UPEdxLtYD8QCw$kIMy!aq59>%=Hx4=mT<>WD(^e;F`<`o})iyCM}jJ5yY1KQ5- zCxdON&|A6@dZ01%6bzWsIT^-)z%VdWC$>}#GZQ$^%kiKPTMBv1f(TW!I7#(O7AM!C z!!K`_(oEfmLA$5f=T=diR-qbZ9Sq8u4&^s>I5tF%x-~==v$m>kvZ^D5%3&$bdE8W; z!SLX+nO16lep4Ta-%iWx&Kq674X5PY@32*sjv3Ez#qgWrqm|xj+Y0xSS~g2p-{F$D zlf11CPLHmNTHsXO`l86JVvR0(AMvyAK z1qe?ut63bVXcPx>c@EZCWoUi=p&$5c*+L`bhzLPezfp z0JEGMA}??nB30|~?Aj1X10hxd)BdYeMDm-YmN0r&95{cE+0VTQtf!e)a@;H!MJ?A> z6#rpRkx(|s$wJCVUXb6)i z@QbqGymG}E8Ig$VM1(s8;9WWsrOJmCy=8b<2M5)`a~C-p0IWfn6k=E59L5JZklX%J zbe{}bsVSao4?EIIRf=HF+rTAQDrWVa>j+W?AcQuM-gnMA|7!Gc&Qy_p%xDpUz zNl{vY+y}9gmIu)CT&eC|BZv{Ep>T)__N_uY9zUstD~@GF)SzFbflPI7`O-wJ!sd`A@Jagp4A;0Xblk$_04 zg+b$Xc!cAEFHjL@=&dacxpP|5pw5ctr6>--6QVvW!NCq(gn~ty2Wj_dh7{slRn{5z zlf?7}s^+xmh^3s4<#m*Q^pf%)GHA#^%@AM_(-6NQCO9UU!>u1q6)4IQs&VOFVmyX? zpjkrJ3_q^~0x+ipkarJlI)-Y~be}Wi2>lr8A|jy89-&AfEr@s{lRymdln)%Fy&egs zBz79VHRRN={0Lxdntjo=WqMr77SaAvm!%+Y2&?rHYi&jcBZb{nVk$mR1H+JIjM?2nS8V*Xc?D6B6PxgOm2gt=P z&<5k04Jg*?RwCh+vW@gNky{T-QkI$v< zwsm8%6OVeMWplde;)SD9dj3x{f6CJTN+DCFh1V^@owEmgLq>8!=yRk<^{KD+TIZC6 zEo;AD%gR*9>7yA}eb**$YOl82B4i|YfY~-OR7QVTG<71z z7vAL{oB0Z#Z@ZaKMq0aF+US!mR~|oXU!n`CJ^HpJ|55COEY46z9QonNW2SmmxKDGp z?-S?jUKd~L+wRJ@S64kh!>)~)sLhwPt7Rw$$$BC8{i9zVTN(hq`gSY>&z0+HmI0TF z^kK_D #include -/** \defgroup gapi_core G-API core (basic) functionality +/** \defgroup gapi_core G-API Core functionality @{ @defgroup gapi_math Graph API: Math operations @defgroup gapi_pixelwise Graph API: Pixelwise operations @defgroup gapi_matrixop Graph API: Operations on matrices - @defgroup gapi_transform Graph API: Geometric, depth and LUT-like image transformations + @defgroup gapi_transform Graph API: Image and channel composition functions @} */ namespace cv { namespace gapi { diff --git a/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp b/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp index 443b40599c..4c6b913561 100644 --- a/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp +++ b/modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp @@ -29,7 +29,7 @@ namespace gapi namespace fluid { /** - * \addtogroup gapi_std_backends G-API Standard backends + * \addtogroup gapi_std_backends G-API Standard Backends * @{ */ /** @@ -97,16 +97,46 @@ public: // FIXME!!! // This is the temporary and experimental API // which should be replaced by runtime roi-based scheduling +/** \addtogroup gapi_compile_args + * @{ + */ +/** + * @brief This structure allows to control the output image region + * which Fluid backend will produce in the graph. + * + * This feature is useful for external tiling and parallelism, but + * will be deprecated in the future releases. + */ struct GFluidOutputRois { std::vector rois; }; +/** + * @brief This structure forces Fluid backend to generate multiple + * parallel output regions in the graph. These regions execute in parallel. + * + * This feature may be deprecated in the future releases. + */ struct GFluidParallelOutputRois { std::vector parallel_rois; }; +/** + * @brief This structure allows to customize the way how Fluid executes + * parallel regions. + * + * For example, user can utilize his own threading runtime via this parameter. + * The `parallel_for` member functor is called by the Fluid runtime with the + * following arguments: + * + * @param size Size of the parallel range to process + * @param f A function which should be called for every integer index + * in this range by the specified parallel_for implementation. + * + * This feature may be deprecated in the future releases. + */ struct GFluidParallelFor { //this function accepts: @@ -114,6 +144,7 @@ struct GFluidParallelFor // - and a function to be called on the range items, designated by item index std::function)> parallel_for; }; +/** @} gapi_compile_args */ namespace detail { diff --git a/modules/gapi/include/opencv2/gapi/gcommon.hpp b/modules/gapi/include/opencv2/gapi/gcommon.hpp index dac640a2f7..40c6d36af0 100644 --- a/modules/gapi/include/opencv2/gapi/gcommon.hpp +++ b/modules/gapi/include/opencv2/gapi/gcommon.hpp @@ -25,10 +25,6 @@ namespace detail // This is a trait-like structure to mark backend-specific compile arguments // with tags template struct CompileArgTag; - template struct CompileArgTag - { - static const char* tag() { return ""; }; - }; // These structures are tags which separate kernels and transformations struct KernelTag @@ -62,8 +58,8 @@ namespace detail { /** \addtogroup gapi_compile_args * @{ * - * @brief Compilation arguments: a set of data structures which can be - * passed to control compilation process + * @brief Compilation arguments: data structures controlling the + * compilation process * * G-API comes with a number of graph compilation options which can be * passed to cv::GComputation::apply() or diff --git a/modules/gapi/include/opencv2/gapi/gcompoundkernel.hpp b/modules/gapi/include/opencv2/gapi/gcompoundkernel.hpp index 7d960cd6fa..84b8780251 100644 --- a/modules/gapi/include/opencv2/gapi/gcompoundkernel.hpp +++ b/modules/gapi/include/opencv2/gapi/gcompoundkernel.hpp @@ -101,7 +101,18 @@ public: }; } // namespace detail -#define GAPI_COMPOUND_KERNEL(Name, API) struct Name: public cv::detail::GCompoundKernelImpl + + +/** + * Declares a new compound kernel. See this + * [documentation chapter](@ref gapi_kernel_compound) + * on compound kernels for more details. + * + * @param Name type name for new kernel + * @param API the interface this kernel implements + */ +#define GAPI_COMPOUND_KERNEL(Name, API) \ + struct Name: public cv::detail::GCompoundKernelImpl } // namespace cv diff --git a/modules/gapi/include/opencv2/gapi/gcomputation.hpp b/modules/gapi/include/opencv2/gapi/gcomputation.hpp index 1f0f6b52bd..678b22d47c 100644 --- a/modules/gapi/include/opencv2/gapi/gcomputation.hpp +++ b/modules/gapi/include/opencv2/gapi/gcomputation.hpp @@ -39,6 +39,8 @@ namespace detail /** * \addtogroup gapi_main_classes * @{ + * + * @brief G-API classes for constructed and compiled graphs. */ /** * @brief GComputation class represents a captured computation diff --git a/modules/gapi/include/opencv2/gapi/gkernel.hpp b/modules/gapi/include/opencv2/gapi/gkernel.hpp index 35ce8d5bb5..222356ac23 100644 --- a/modules/gapi/include/opencv2/gapi/gkernel.hpp +++ b/modules/gapi/include/opencv2/gapi/gkernel.hpp @@ -239,12 +239,31 @@ public: static constexpr const char * id() {return Id;} \ }; \ //! @endcond + +/** + * Declares a new G-API Operation. See [Kernel API](@ref gapi_kernel_api) + * for more details. + * + * @param Class type name for this operation. + * @param API an `std::function<>`-like signature for the operation; + * return type is a single value. + * @param Id string identifier for the operation. Must be unique. + */ #define G_TYPED_KERNEL(Class, API, Id) \ G_ID_HELPER_BODY(Class, Id) \ struct Class final: public cv::GKernelType, \ public G_ID_HELPER_CLASS(Class) // {body} is to be defined by user +/** + * Declares a new G-API Operation. See [Kernel API](@ref gapi_kernel_api) + * for more details. + * + * @param Class type name for this operation. + * @param API an `std::function<>`-like signature for the operation; + * return type is a tuple of multiple values. + * @param Id string identifier for the operation. Must be unique. + */ #define G_TYPED_KERNEL_M(Class, API, Id) \ G_ID_HELPER_BODY(Class, Id) \ struct Class final: public cv::GKernelTypeM, \ diff --git a/modules/gapi/include/opencv2/gapi/gmat.hpp b/modules/gapi/include/opencv2/gapi/gmat.hpp index 440c433ff6..4f67126a90 100644 --- a/modules/gapi/include/opencv2/gapi/gmat.hpp +++ b/modules/gapi/include/opencv2/gapi/gmat.hpp @@ -29,10 +29,24 @@ struct GOrigin; /** \addtogroup gapi_data_objects * @{ * - * @brief Data-representing objects which can be used to build G-API - * expressions. + * @brief G-API data objects used to build G-API expressions. + * + * These objects do not own any particular data (except compile-time + * associated values like with cv::GScalar) and are used to construct + * graphs. + * + * Every graph in G-API starts and ends with data objects. + * + * Once constructed and compiled, G-API operates with regular host-side + * data instead. Refer to the below table to find the mapping between + * G-API and regular data types. + * + * G-API data type | I/O data type + * ------------------ | ------------- + * cv::GMat | cv::Mat + * cv::GScalar | cv::Scalar + * `cv::GArray` | std::vector */ - class GAPI_EXPORTS GMat { public: diff --git a/modules/gapi/include/opencv2/gapi/gtyped.hpp b/modules/gapi/include/opencv2/gapi/gtyped.hpp index 8e48e91bd3..5b941c7bb6 100644 --- a/modules/gapi/include/opencv2/gapi/gtyped.hpp +++ b/modules/gapi/include/opencv2/gapi/gtyped.hpp @@ -39,6 +39,46 @@ namespace detail auto make_default()->decltype(T{}) {return {};} }; // detail +/** + * @brief This class is a typed wrapper over a regular GComputation. + * + * `std::function<>`-like template parameter specifies the graph + * signature so methods so the object's constructor, methods like + * `apply()` and the derived `GCompiledT::operator()` also become + * typed. + * + * There is no need to use cv::gin() or cv::gout() modifiers with + * objects of this class. Instead, all input arguments are followed + * by all output arguments in the order from the template argument + * signature. + * + * Refer to the following example. Regular (untyped) code is written this way: + * + * @snippet modules/gapi/samples/api_ref_snippets.cpp Untyped_Example + * + * Here: + * + * - cv::GComputation object is created with a lambda constructor + * where it is defined as a two-input, one-output graph. + * + * - Its method `apply()` in fact takes arbitrary number of arguments + * (as vectors) so user can pass wrong number of inputs/outputs + * here. C++ compiler wouldn't notice that since the cv::GComputation + * API is polymorphic, and only a run-time error will be generated. + * + * Now the same code written with typed API: + * + * @snippet modules/gapi/samples/api_ref_snippets.cpp Typed_Example + * + * The key difference is: + * + * - Now the constructor lambda *must take* parameters and *must + * return* values as defined in the `GComputationT<>` signature. + * - Its method `apply()` does not require any extra specifiers to + * separate input arguments from the output ones + * - A `GCompiledT` (compilation product) takes input/output + * arguments with no extra specifiers as well. + */ template class GComputationT; // Single return value implementation diff --git a/modules/gapi/include/opencv2/gapi/imgproc.hpp b/modules/gapi/include/opencv2/gapi/imgproc.hpp index ad3f7c10ed..e1a3aa5eca 100644 --- a/modules/gapi/include/opencv2/gapi/imgproc.hpp +++ b/modules/gapi/include/opencv2/gapi/imgproc.hpp @@ -17,7 +17,7 @@ #include -/** \defgroup gapi_imgproc G-API image processing functionality +/** \defgroup gapi_imgproc G-API Image processing functionality @{ @defgroup gapi_filters Graph API: Image filters @defgroup gapi_colorconvert Graph API: Converting image from one color space to another diff --git a/modules/gapi/include/opencv2/gapi/infer.hpp b/modules/gapi/include/opencv2/gapi/infer.hpp index cc352a9062..a6ffb7a9ff 100644 --- a/modules/gapi/include/opencv2/gapi/infer.hpp +++ b/modules/gapi/include/opencv2/gapi/infer.hpp @@ -192,6 +192,9 @@ struct GAPI_EXPORTS GNetParam { util::any params; // Backend-interpreted parameter structure }; +/** \addtogroup gapi_compile_args + * @{ + */ /** * @brief A container class for network configurations. Similar to * GKernelPackage.Use cv::gapi::networks() to construct this object. @@ -204,6 +207,7 @@ struct GAPI_EXPORTS GNetPackage { std::vector backends() const; std::vector networks; }; +/** @} gapi_compile_args */ } // namespace gapi namespace detail { diff --git a/modules/gapi/include/opencv2/gapi/ocl/goclkernel.hpp b/modules/gapi/include/opencv2/gapi/ocl/goclkernel.hpp index 4a490aaa89..a51fa8ff5d 100644 --- a/modules/gapi/include/opencv2/gapi/ocl/goclkernel.hpp +++ b/modules/gapi/include/opencv2/gapi/ocl/goclkernel.hpp @@ -32,7 +32,7 @@ namespace gapi namespace ocl { /** - * \addtogroup gapi_std_backends G-API Standard backends + * \addtogroup gapi_std_backends G-API Standard Backends * @{ */ /** diff --git a/modules/gapi/include/opencv2/gapi/plaidml/plaidml.hpp b/modules/gapi/include/opencv2/gapi/plaidml/plaidml.hpp index f35f591676..bd12d25832 100644 --- a/modules/gapi/include/opencv2/gapi/plaidml/plaidml.hpp +++ b/modules/gapi/include/opencv2/gapi/plaidml/plaidml.hpp @@ -18,11 +18,19 @@ namespace gapi namespace plaidml { +/** \addtogroup gapi_compile_args + * @{ + */ +/** + * @brief This structure represents the basic parameters for the experimental + * PlaidML backend. + */ struct config { - std::string dev_id; - std::string trg_id; + std::string dev_id; //!< Device ID. Refer to PlaidML documentation for details. + std::string trg_id; //!< Target ID. Refer to PlaidML documentation for details. }; +/** @} gapi_compile_args */ } // namespace plaidml } // namespace gapi diff --git a/modules/gapi/include/opencv2/gapi/render.hpp b/modules/gapi/include/opencv2/gapi/render.hpp new file mode 100644 index 0000000000..52e55b0d80 --- /dev/null +++ b/modules/gapi/include/opencv2/gapi/render.hpp @@ -0,0 +1,14 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2019 Intel Corporation + +#ifndef OPENCV_GAPI_RENDER_ROOT_HPP +#define OPENCV_GAPI_RENDER_ROOT_HPP + +// This file is just a shortcut to render/render.hpp + +#include + +#endif // OPENCV_GAPI_RENDER_ROOT_HPP diff --git a/modules/gapi/include/opencv2/gapi/render/render.hpp b/modules/gapi/include/opencv2/gapi/render/render.hpp index 845c1dbd6a..15cbacfc7b 100644 --- a/modules/gapi/include/opencv2/gapi/render/render.hpp +++ b/modules/gapi/include/opencv2/gapi/render/render.hpp @@ -18,6 +18,56 @@ #include #include + +/** \defgroup gapi_draw G-API Drawing and composition functionality + * @{ + * + * @brief Functions for in-graph drawing. + * + * @note This is a Work in Progress functionality and APIs may + * change in the future releases. + * + * G-API can do some in-graph drawing with a generic operations and a + * set of [rendering primitives](@ref gapi_draw_prims). + * In contrast with traditional OpenCV, in G-API user need to form a + * *rendering list* of primitives to draw. This list can be built + * manually or generated within a graph. This list is passed to + * [special operations or functions](@ref gapi_draw_api) where all + * primitives are interpreted and applied to the image. + * + * For example, in a complex pipeline a list of detected objects + * can be translated in-graph to a list of cv::gapi::wip::draw::Rect + * primitives to highlight those with bounding boxes, or a list of + * detected faces can be translated in-graph to a list of + * cv::gapi::wip::draw::Mosaic primitives to hide sensitive content + * or protect privacy. + * + * Like any other operations, rendering in G-API can be reimplemented + * by different backends. Currently only an OpenCV-based backend is + * available. + * + * In addition to the graph-level operations, there are also regular + * (immediate) OpenCV-like functions are available -- see + * cv::gapi::wip::draw::render(). These functions are just wrappers + * over regular G-API and build the rendering graphs on the fly, so + * take compilation arguments as parameters. + * + * Currently this API is more machine-oriented than human-oriented. + * The main purpose is to translate a set of domain-specific objects + * to a list of primitives to draw. For example, in order to generate + * a picture like this: + * + * ![](modules/gapi/doc/pics/render_example.png) + * + * Rendering list needs to be generated as follows: + * + * @include modules/gapi/samples/draw_example.cpp + * + * @defgroup gapi_draw_prims Drawing primitives + * @defgroup gapi_draw_api Drawing operations and functions + * @} + */ + namespace cv { namespace gapi @@ -28,17 +78,21 @@ namespace draw { /** - * A structure allows using freetype library for text rendering + * @brief This structure specifies which FreeType font to use by FText primitives. */ struct freetype_font { /*@{*/ - std::string path; //!< The path to font file (.ttf) + std::string path; //!< The path to the font file (.ttf) /*@{*/ }; +//! @addtogroup gapi_draw_prims +//! @{ /** - * A structure to represent parameters for drawing a text string. + * @brief This structure represents a text string to draw. + * + * Parameters match cv::putText(). */ struct Text { @@ -55,7 +109,11 @@ struct Text }; /** - * A structure to represent parameters for drawing a text string using FreeType library + * @brief This structure represents a text string to draw using + * FreeType renderer. + * + * If OpenCV is built without FreeType support, this primitive will + * fail at the execution stage. */ struct FText { @@ -68,7 +126,9 @@ struct FText }; /** - * A structure to represent parameters for drawing a rectangle + * @brief This structure represents a rectangle to draw. + * + * Parameters match cv::rectangle(). */ struct Rect { @@ -80,7 +140,9 @@ struct Rect }; /** - * A structure to represent parameters for drawing a circle + * @brief This structure represents a circle to draw. + * + * Parameters match cv::circle(). */ struct Circle { @@ -93,7 +155,9 @@ struct Circle }; /** - * A structure to represent parameters for drawing a line + * @brief This structure represents a line to draw. + * + * Parameters match cv::line(). */ struct Line { @@ -106,17 +170,21 @@ struct Line }; /** - * A structure to represent parameters for drawing a mosaic + * @brief This structure represents a mosaicing operation. + * + * Mosaicing is a very basic method to obfuscate regions in the image. */ struct Mosaic { cv::Rect mos; //!< Coordinates of the mosaic - int cellSz; //!< Cell size (same for X, Y). Note: mos size must be multiple of cell size + int cellSz; //!< Cell size (same for X, Y). Note: mosaic size must be a multiple of cell size int decim; //!< Decimation (0 stands for no decimation) }; /** - * A structure to represent parameters for drawing an image + * @brief This structure represents an image to draw. + * + * Image is blended on a frame using the specified mask. */ struct Image { @@ -126,7 +194,7 @@ struct Image }; /** - * A structure to represent parameters for drawing a polygon + * @brief This structure represents a polygon to draw. */ struct Poly { @@ -149,9 +217,14 @@ using Prim = util::variant >; using Prims = std::vector; +//! @} gapi_draw_prims + using GMat2 = std::tuple; using GMatDesc2 = std::tuple; + +//! @addtogroup gapi_draw_api +//! @{ /** @brief The function renders on the input image passed drawing primitivies @param bgr input image: 8-bit unsigned 3-channel image @ref CV_8UC3. @@ -211,6 +284,7 @@ uv image must be 8-bit unsigned planar 2-channel image @ref CV_8UC2 GAPI_EXPORTS GMat2 renderNV12(const GMat& y, const GMat& uv, const GArray& prims); +//! @} gapi_draw_api } // namespace draw } // namespace wip @@ -224,6 +298,15 @@ namespace ocv } // namespace ocv } // namespace render } // namespace gapi + +namespace detail +{ + template<> struct CompileArgTag + { + static const char* tag() { return "gapi.freetype_font"; } + }; +} // namespace detail + } // namespace cv #endif // OPENCV_GAPI_RENDER_HPP diff --git a/modules/gapi/samples/api_ref_snippets.cpp b/modules/gapi/samples/api_ref_snippets.cpp index 2793aee98e..9c3e73a17c 100644 --- a/modules/gapi/samples/api_ref_snippets.cpp +++ b/modules/gapi/samples/api_ref_snippets.cpp @@ -9,6 +9,44 @@ #include #include +static void typed_example() +{ + const cv::Size sz(32, 32); + cv::Mat + in_mat1 (sz, CV_8UC1), + in_mat2 (sz, CV_8UC1), + out_mat_untyped(sz, CV_8UC1), + out_mat_typed1 (sz, CV_8UC1), + out_mat_typed2 (sz, CV_8UC1); + cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255)); + cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255)); + + //! [Untyped_Example] + // Untyped G-API /////////////////////////////////////////////////////////// + cv::GComputation cvtU([]() + { + cv::GMat in1, in2; + cv::GMat out = cv::gapi::add(in1, in2); + return cv::GComputation({in1, in2}, {out}); + }); + std::vector u_ins = {in_mat1, in_mat2}; + std::vector u_outs = {out_mat_untyped}; + cvtU.apply(u_ins, u_outs); + //! [Untyped_Example] + + //! [Typed_Example] + // Typed G-API ///////////////////////////////////////////////////////////// + cv::GComputationT cvtT([](cv::GMat m1, cv::GMat m2) + { + return m1+m2; + }); + cvtT.apply(in_mat1, in_mat2, out_mat_typed1); + + auto cvtTC = cvtT.compile(cv::descr_of(in_mat1), cv::descr_of(in_mat2)); + cvtTC(in_mat1, in_mat2, out_mat_typed2); + //! [Typed_Example] +} + G_TYPED_KERNEL(IAdd, , "test.custom.add") { static cv::GMatDesc outMeta(const cv::GMatDesc &in) { return in; } }; @@ -77,5 +115,8 @@ int main(int argc, char *argv[]) , CustomRGB2YUV >(); //! [kernels_snippet] + + // Just call typed example with no input/output + typed_example(); return 0; } diff --git a/modules/gapi/samples/draw_example.cpp b/modules/gapi/samples/draw_example.cpp new file mode 100644 index 0000000000..9826da6a7b --- /dev/null +++ b/modules/gapi/samples/draw_example.cpp @@ -0,0 +1,56 @@ +#include // cv::FONT*, cv::LINE*, cv::FILLED +#include // imwrite + +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc < 2) { + std::cerr << "Filename requried" << std::endl; + return 1; + } + + const auto font = cv::FONT_HERSHEY_DUPLEX; + const auto blue = cv::Scalar{ 255, 0, 0}; // B/G/R + const auto green = cv::Scalar{ 0, 255, 0}; + const auto coral = cv::Scalar{0x81,0x81,0xF1}; + const auto white = cv::Scalar{ 255, 255, 255}; + cv::Mat test(cv::Size(480, 160), CV_8UC3, white); + + namespace draw = cv::gapi::wip::draw; + std::vector prims; + prims.emplace_back(draw::Circle{ // CIRCLE primitive + {400,72}, // Position (a cv::Point) + 32, // Radius + coral, // Color + cv::FILLED, // Thickness/fill type + cv::LINE_8, // Line type + 0 // Shift + }); + prims.emplace_back(draw::Text{ // TEXT primitive + "Hello from G-API!", // Text + {64,96}, // Position (a cv::Point) + font, // Font + 1.0, // Scale (size) + blue, // Color + 2, // Thickness + cv::LINE_8, // Line type + false // Bottom left origin flag + }); + prims.emplace_back(draw::Rect{ // RECTANGLE primitive + {16,48,400,72}, // Geometry (a cv::Rect) + green, // Color + 2, // Thickness + cv::LINE_8, // Line type + 0 // Shift + }); + prims.emplace_back(draw::Mosaic{ // MOSAIC primitive + {320,96,128,32}, // Geometry (a cv::Rect) + 16, // Cell size + 0 // Decimation + }); + draw::render(test, prims); + cv::imwrite(argv[1], test); + return 0; +} diff --git a/modules/gapi/src/api/render.cpp b/modules/gapi/src/api/render.cpp index 9f4c18ffed..a145e0a941 100644 --- a/modules/gapi/src/api/render.cpp +++ b/modules/gapi/src/api/render.cpp @@ -57,28 +57,16 @@ void cv::gapi::wip::draw::cvtNV12ToYUV(const cv::Mat& y, cv::merge(std::vector{y, upsample_uv}, yuv); } -namespace cv -{ -namespace detail -{ - template<> struct CompileArgTag - { - static const char* tag() { return "gapi.freetype_font"; } - }; - -} // namespace detail - -GMat cv::gapi::wip::draw::render3ch(const GMat& src, - const GArray& prims) +cv::GMat cv::gapi::wip::draw::render3ch(const cv::GMat& src, + const cv::GArray& prims) { return cv::gapi::wip::draw::GRenderBGR::on(src, prims); } -std::tuple cv::gapi::wip::draw::renderNV12(const GMat& y, - const GMat& uv, - const GArray& prims) +std::tuple +cv::gapi::wip::draw::renderNV12(const cv::GMat& y, + const cv::GMat& uv, + const cv::GArray& prims) { return cv::gapi::wip::draw::GRenderNV12::on(y, uv, prims); } - -} // namespace cv diff --git a/modules/gapi/src/backends/ie/util.hpp b/modules/gapi/src/backends/ie/util.hpp index 1b6534e2af..b16ccbe0ce 100644 --- a/modules/gapi/src/backends/ie/util.hpp +++ b/modules/gapi/src/backends/ie/util.hpp @@ -23,8 +23,9 @@ namespace gapi { namespace ie { namespace util { +// NB: These functions are EXPORTed to make them accessible by the +// test suite only. GAPI_EXPORTS std::vector to_ocv(const InferenceEngine::SizeVector &dims); - GAPI_EXPORTS cv::Mat to_ocv(InferenceEngine::Blob::Ptr blob); GAPI_EXPORTS InferenceEngine::Blob::Ptr to_ie(cv::Mat &blob);