github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/opencv4/include/opencv2/gapi/gcomputation.hpp (about)

     1  // This file is part of OpenCV project.
     2  // It is subject to the license terms in the LICENSE file found in the top-level directory
     3  // of this distribution and at http://opencv.org/license.html.
     4  //
     5  // Copyright (C) 2018 Intel Corporation
     6  
     7  
     8  #ifndef OPENCV_GAPI_GCOMPUTATION_HPP
     9  #define OPENCV_GAPI_GCOMPUTATION_HPP
    10  
    11  #include <functional>
    12  
    13  #include <opencv2/gapi/util/util.hpp>
    14  #include <opencv2/gapi/gcommon.hpp>
    15  #include <opencv2/gapi/gproto.hpp>
    16  #include <opencv2/gapi/garg.hpp>
    17  #include <opencv2/gapi/gcompiled.hpp>
    18  #include <opencv2/gapi/gstreaming.hpp>
    19  
    20  namespace cv {
    21  
    22  namespace detail
    23  {
    24      // FIXME: move to algorithm, cover with separate tests
    25      // FIXME: replace with O(1) version (both memory and compilation time)
    26      template<typename...>
    27      struct last_type;
    28  
    29      template<typename T>
    30      struct last_type<T> { using type = T;};
    31  
    32      template<typename T, typename... Ts>
    33      struct last_type<T, Ts...> { using type = typename last_type<Ts...>::type; };
    34  
    35      template<typename... Ts>
    36      using last_type_t = typename last_type<Ts...>::type;
    37  }
    38  
    39  // Forward-declare the serialization objects
    40  namespace gapi {
    41  namespace s11n {
    42      struct IIStream;
    43      struct IOStream;
    44  } // namespace s11n
    45  } // namespace gapi
    46  
    47  /**
    48   * \addtogroup gapi_main_classes
    49   * @{
    50   *
    51   * @brief G-API classes for constructed and compiled graphs.
    52   */
    53  /**
    54   * @brief GComputation class represents a captured computation
    55   * graph. GComputation objects form boundaries for expression code
    56   * user writes with G-API, allowing to compile and execute it.
    57   *
    58   * G-API computations are defined with input/output data
    59   * objects. G-API will track automatically which operations connect
    60   * specified outputs to the inputs, forming up a call graph to be
    61   * executed. The below example expresses calculation of Sobel operator
    62   * for edge detection (\f$G = \sqrt{G_x^2 + G_y^2}\f$):
    63   *
    64   * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_def
    65   *
    66   * Full pipeline can be now captured with this object declaration:
    67   *
    68   * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_cap_full
    69   *
    70   * Input/output data objects on which a call graph should be
    71   * reconstructed are passed using special wrappers cv::GIn and
    72   * cv::GOut. G-API will track automatically which operations form a
    73   * path from inputs to outputs and build the execution graph appropriately.
    74   *
    75   * Note that cv::GComputation doesn't take ownership on data objects
    76   * it is defined. Moreover, multiple GComputation objects may be
    77   * defined on the same expressions, e.g. a smaller pipeline which
    78   * expects that image gradients are already pre-calculated may be
    79   * defined like this:
    80   *
    81   * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_cap_sub
    82   *
    83   * The resulting graph would expect two inputs and produce one
    84   * output. In this case, it doesn't matter if gx/gy data objects are
    85   * results of cv::gapi::Sobel operators -- G-API will stop unrolling
    86   * expressions and building the underlying graph one reaching this
    87   * data objects.
    88   *
    89   * The way how GComputation is defined is important as its definition
    90   * specifies graph _protocol_ -- the way how the graph should be
    91   * used. Protocol is defined by number of inputs, number of outputs,
    92   * and shapes of inputs and outputs.
    93   *
    94   * In the above example, sobelEdge expects one Mat on input and
    95   * produces one Mat; while sobelEdgeSub expects two Mats on input and
    96   * produces one Mat. GComputation's protocol defines how other
    97   * computation methods should be used -- cv::GComputation::compile() and
    98   * cv::GComputation::apply(). For example, if a graph is defined on
    99   * two GMat inputs, two cv::Mat objects have to be passed to apply()
   100   * for execution. GComputation checks protocol correctness in runtime
   101   * so passing a different number of objects in apply() or passing
   102   * cv::Scalar instead of cv::Mat there would compile well as a C++
   103   * source but raise an exception in run-time. G-API also comes with a
   104   * typed wrapper cv::GComputationT<> which introduces this type-checking in
   105   * compile-time.
   106   *
   107   * cv::GComputation itself is a thin object which just captures what
   108   * the graph is. The compiled graph (which actually process data) is
   109   * represented by class GCompiled. Use compile() method to generate a
   110   * compiled graph with given compile options. cv::GComputation can
   111   * also be used to process data with implicit graph compilation
   112   * on-the-fly, see apply() for details.
   113   *
   114   * GComputation is a reference-counted object -- once defined, all its
   115   * copies will refer to the same instance.
   116   *
   117   * @sa GCompiled
   118   */
   119  class GAPI_EXPORTS_W GComputation
   120  {
   121  public:
   122      class Priv;
   123      typedef std::function<GComputation()> Generator;
   124  
   125      // Various constructors enable different ways to define a computation: /////
   126      // 1. Generic constructors
   127      /**
   128       * @brief Define a computation using a generator function.
   129       *
   130       * Graph can be defined in-place directly at the moment of its
   131       * construction with a lambda:
   132       *
   133       * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_gen
   134       *
   135       * This may be useful since all temporary objects (cv::GMats) and
   136       * namespaces can be localized to scope of lambda, without
   137       * contaminating the parent scope with probably unnecessary objects
   138       * and information.
   139       *
   140       * @param gen generator function which returns a cv::GComputation,
   141       * see Generator.
   142       */
   143      GComputation(const Generator& gen);                // Generator
   144                                                         // overload
   145  
   146      /**
   147       * @brief Generic GComputation constructor.
   148       *
   149       * Constructs a new graph with a given protocol, specified as a
   150       * flow of operations connecting input/output objects. Throws if
   151       * the passed boundaries are invalid, e.g. if there's no
   152       * functional dependency (path) between given outputs and inputs.
   153       *
   154       * @param ins Input data vector.
   155       * @param outs Output data vector.
   156       *
   157       * @note Don't construct GProtoInputArgs/GProtoOutputArgs objects
   158       * directly, use cv::GIn()/cv::GOut() wrapper functions instead.
   159       *
   160       * @sa @ref gapi_data_objects
   161       */
   162      GAPI_WRAP GComputation(GProtoInputArgs &&ins,
   163                             GProtoOutputArgs &&outs);             // Arg-to-arg overload
   164  
   165      // 2. Syntax sugar and compatibility overloads
   166      /**
   167       * @brief Defines an unary (one input -- one output) computation
   168       *
   169       * @overload
   170       * @param in input GMat of the defined unary computation
   171       * @param out output GMat of the defined unary computation
   172       */
   173      GAPI_WRAP GComputation(GMat in, GMat out);  // Unary overload
   174  
   175      /**
   176       * @brief Defines an unary (one input -- one output) computation
   177       *
   178       * @overload
   179       * @param in input GMat of the defined unary computation
   180       * @param out output GScalar of the defined unary computation
   181       */
   182      GAPI_WRAP GComputation(GMat in, GScalar out);      // Unary overload (scalar)
   183  
   184      /**
   185       * @brief Defines a binary (two inputs -- one output) computation
   186       *
   187       * @overload
   188       * @param in1 first input GMat of the defined binary computation
   189       * @param in2 second input GMat of the defined binary computation
   190       * @param out output GMat of the defined binary computation
   191       */
   192      GAPI_WRAP GComputation(GMat in1, GMat in2, GMat out);        // Binary overload
   193  
   194      /**
   195       * @brief Defines a binary (two inputs -- one output) computation
   196       *
   197       * @overload
   198       * @param in1 first input GMat of the defined binary computation
   199       * @param in2 second input GMat of the defined binary computation
   200       * @param out output GScalar of the defined binary computation
   201       */
   202      GComputation(GMat in1, GMat in2, GScalar out);     // Binary
   203                                                         // overload
   204                                                         // (scalar)
   205  
   206      /**
   207       * @brief Defines a computation with arbitrary input/output number.
   208       *
   209       * @overload
   210       * @param ins vector of inputs GMats for this computation
   211       * @param outs vector of outputs GMats for this computation
   212       *
   213       * Use this overload for cases when number of computation
   214       * inputs/outputs is not known in compile-time -- e.g. when graph
   215       * is programmatically generated to build an image pyramid with
   216       * the given number of levels, etc.
   217       */
   218      GComputation(const std::vector<GMat> &ins,         // Compatibility overload
   219                   const std::vector<GMat> &outs);
   220  
   221      // Various versions of apply(): ////////////////////////////////////////////
   222      // 1. Generic apply()
   223      /**
   224       * @brief Compile graph on-the-fly and immediately execute it on
   225       * the inputs data vectors.
   226       *
   227       * Number of input/output data objects must match GComputation's
   228       * protocol, also types of host data objects (cv::Mat, cv::Scalar)
   229       * must match the shapes of data objects from protocol (cv::GMat,
   230       * cv::GScalar). If there's a mismatch, a run-time exception will
   231       * be generated.
   232       *
   233       * Internally, a cv::GCompiled object is created for the given
   234       * input format configuration, which then is executed on the input
   235       * data immediately. cv::GComputation caches compiled objects
   236       * produced within apply() -- if this method would be called next
   237       * time with the same input parameters (image formats, image
   238       * resolution, etc), the underlying compiled graph will be reused
   239       * without recompilation. If new metadata doesn't match the cached
   240       * one, the underlying compiled graph is regenerated.
   241       *
   242       * @note compile() always triggers a compilation process and
   243       * produces a new GCompiled object regardless if a similar one has
   244       * been cached via apply() or not.
   245       *
   246       * @param ins vector of input data to process. Don't create
   247       * GRunArgs object manually, use cv::gin() wrapper instead.
   248       * @param outs vector of output data to fill results in. cv::Mat
   249       * objects may be empty in this vector, G-API will automatically
   250       * initialize it with the required format & dimensions. Don't
   251       * create GRunArgsP object manually, use cv::gout() wrapper instead.
   252       * @param args a list of compilation arguments to pass to the
   253       * underlying compilation process. Don't create GCompileArgs
   254       * object manually, use cv::compile_args() wrapper instead.
   255       *
   256       * @sa @ref gapi_data_objects, @ref gapi_compile_args
   257       */
   258      void apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args = {});       // Arg-to-arg overload
   259  
   260      /// @private -- Exclude this function from OpenCV documentation
   261      GAPI_WRAP GRunArgs apply(const cv::detail::ExtractArgsCallback  &callback,
   262                                     GCompileArgs                    &&args = {});
   263  
   264      /// @private -- Exclude this function from OpenCV documentation
   265      void apply(const std::vector<cv::Mat>& ins,                                   // Compatibility overload
   266                 const std::vector<cv::Mat>& outs,
   267                 GCompileArgs &&args = {});
   268  
   269      // 2. Syntax sugar and compatibility overloads
   270  #if !defined(GAPI_STANDALONE)
   271      /**
   272       * @brief Execute an unary computation (with compilation on the fly)
   273       *
   274       * @overload
   275       * @param in input cv::Mat for unary computation
   276       * @param out output cv::Mat for unary computation
   277       * @param args compilation arguments for underlying compilation
   278       * process.
   279       */
   280      void apply(cv::Mat in, cv::Mat &out, GCompileArgs &&args = {}); // Unary overload
   281  
   282      /**
   283       * @brief Execute an unary computation (with compilation on the fly)
   284       *
   285       * @overload
   286       * @param in input cv::Mat for unary computation
   287       * @param out output cv::Scalar for unary computation
   288       * @param args compilation arguments for underlying compilation
   289       * process.
   290       */
   291      void apply(cv::Mat in, cv::Scalar &out, GCompileArgs &&args = {}); // Unary overload (scalar)
   292  
   293      /**
   294       * @brief Execute a binary computation (with compilation on the fly)
   295       *
   296       * @overload
   297       * @param in1 first input cv::Mat for binary computation
   298       * @param in2 second input cv::Mat for binary computation
   299       * @param out output cv::Mat for binary computation
   300       * @param args compilation arguments for underlying compilation
   301       * process.
   302       */
   303      void apply(cv::Mat in1, cv::Mat in2, cv::Mat &out, GCompileArgs &&args = {}); // Binary overload
   304  
   305      /**
   306       * @brief Execute an binary computation (with compilation on the fly)
   307       *
   308       * @overload
   309       * @param in1 first input cv::Mat for binary computation
   310       * @param in2 second input cv::Mat for binary computation
   311       * @param out output cv::Scalar for binary computation
   312       * @param args compilation arguments for underlying compilation
   313       * process.
   314       */
   315      void apply(cv::Mat in1, cv::Mat in2, cv::Scalar &out, GCompileArgs &&args = {}); // Binary overload (scalar)
   316  
   317      /**
   318       * @brief Execute a computation with arbitrary number of
   319       * inputs/outputs (with compilation on-the-fly).
   320       *
   321       * @overload
   322       * @param ins vector of input cv::Mat objects to process by the
   323       * computation.
   324       * @param outs vector of output cv::Mat objects to produce by the
   325       * computation.
   326       * @param args compilation arguments for underlying compilation
   327       * process.
   328       *
   329       * Numbers of elements in ins/outs vectors must match numbers of
   330       * inputs/outputs which were used to define this GComputation.
   331       */
   332      void apply(const std::vector<cv::Mat>& ins,         // Compatibility overload
   333                       std::vector<cv::Mat>& outs,
   334                 GCompileArgs &&args = {});
   335  #endif // !defined(GAPI_STANDALONE)
   336      // Various versions of compile(): //////////////////////////////////////////
   337      // 1. Generic compile() - requires metas to be passed as vector
   338      /**
   339       * @brief Compile the computation for specific input format(s).
   340       *
   341       * This method triggers compilation process and produces a new
   342       * GCompiled object which then can process data of the given
   343       * format. Passing data with different format to the compiled
   344       * computation will generate a run-time exception.
   345       *
   346       * @param in_metas vector of input metadata configuration. Grab
   347       * metadata from real data objects (like cv::Mat or cv::Scalar)
   348       * using cv::descr_of(), or create it on your own.
   349       * @param args compilation arguments for this compilation
   350       * process. Compilation arguments directly affect what kind of
   351       * executable object would be produced, e.g. which kernels (and
   352       * thus, devices) would be used to execute computation.
   353       *
   354       * @return GCompiled, an executable computation compiled
   355       * specifically for the given input parameters.
   356       *
   357       * @sa @ref gapi_compile_args
   358       */
   359      GCompiled compile(GMetaArgs &&in_metas, GCompileArgs &&args = {});
   360  
   361      // 2. Syntax sugar - variadic list of metas, no extra compile args
   362      // FIXME: SFINAE looks ugly in the generated documentation
   363      /**
   364       * @overload
   365       *
   366       * Takes a variadic parameter pack with metadata
   367       * descriptors for which a compiled object needs to be produced.
   368       *
   369       * @return GCompiled, an executable computation compiled
   370       * specifically for the given input parameters.
   371       */
   372      template<typename... Ts>
   373      auto compile(const Ts&... metas) ->
   374          typename std::enable_if<detail::are_meta_descrs<Ts...>::value, GCompiled>::type
   375      {
   376          return compile(GMetaArgs{GMetaArg(metas)...}, GCompileArgs());
   377      }
   378  
   379      // 3. Syntax sugar - variadic list of metas, extra compile args
   380      // (seems optional parameters don't work well when there's an variadic template
   381      // comes first)
   382      //
   383      // Ideally it should look like:
   384      //
   385      //     template<typename... Ts>
   386      //     GCompiled compile(const Ts&... metas, GCompileArgs &&args)
   387      //
   388      // But not all compilers can handle this (and seems they shouldn't be able to).
   389      // FIXME: SFINAE looks ugly in the generated documentation
   390      /**
   391       * @overload
   392       *
   393       * Takes a  variadic parameter pack with metadata
   394       * descriptors for which a compiled object needs to be produced,
   395       * followed by GCompileArgs object representing compilation
   396       * arguments for this process.
   397       *
   398       * @return GCompiled, an executable computation compiled
   399       * specifically for the given input parameters.
   400       */
   401      template<typename... Ts>
   402      auto compile(const Ts&... meta_and_compile_args) ->
   403          typename std::enable_if<detail::are_meta_descrs_but_last<Ts...>::value
   404                                  && std::is_same<GCompileArgs, detail::last_type_t<Ts...> >::value,
   405                                  GCompiled>::type
   406      {
   407          //FIXME: wrapping meta_and_compile_args into a tuple to unwrap them inside a helper function is the overkill
   408          return compile(std::make_tuple(meta_and_compile_args...),
   409                         typename detail::MkSeq<sizeof...(Ts)-1>::type());
   410      }
   411  
   412  
   413      // FIXME: Document properly in the Doxygen format
   414      // Video-oriented pipeline compilation:
   415      // 1. A generic version
   416      /**
   417       * @brief Compile the computation for streaming mode.
   418       *
   419       * This method triggers compilation process and produces a new
   420       * GStreamingCompiled object which then can process video stream
   421       * data of the given format. Passing a stream in a different
   422       * format to the compiled computation will generate a run-time
   423       * exception.
   424       *
   425       * @param in_metas vector of input metadata configuration. Grab
   426       * metadata from real data objects (like cv::Mat or cv::Scalar)
   427       * using cv::descr_of(), or create it on your own.
   428       *
   429       * @param args compilation arguments for this compilation
   430       * process. Compilation arguments directly affect what kind of
   431       * executable object would be produced, e.g. which kernels (and
   432       * thus, devices) would be used to execute computation.
   433       *
   434       * @return GStreamingCompiled, a streaming-oriented executable
   435       * computation compiled specifically for the given input
   436       * parameters.
   437       *
   438       * @sa @ref gapi_compile_args
   439       */
   440      GStreamingCompiled compileStreaming(GMetaArgs &&in_metas, GCompileArgs &&args = {});
   441  
   442      /// @private -- Exclude this function from OpenCV documentation
   443      GAPI_WRAP GStreamingCompiled compileStreaming(const cv::detail::ExtractMetaCallback &callback,
   444                                                          GCompileArgs                   &&args = {});
   445  
   446      /**
   447       * @brief Compile the computation for streaming mode.
   448       *
   449       * This method triggers compilation process and produces a new
   450       * GStreamingCompiled object which then can process video stream
   451       * data in any format. Underlying mechanisms will be adjusted to
   452       * every new input video stream automatically, but please note that
   453       * _not all_ existing backends support this (see reshape()).
   454       *
   455       * @param args compilation arguments for this compilation
   456       * process. Compilation arguments directly affect what kind of
   457       * executable object would be produced, e.g. which kernels (and
   458       * thus, devices) would be used to execute computation.
   459       *
   460       * @return GStreamingCompiled, a streaming-oriented executable
   461       * computation compiled for any input image format.
   462       *
   463       * @sa @ref gapi_compile_args
   464       */
   465      GAPI_WRAP GStreamingCompiled compileStreaming(GCompileArgs &&args = {});
   466  
   467      // 2. Direct metadata version
   468      /**
   469       * @overload
   470       *
   471       * Takes a variadic parameter pack with metadata
   472       * descriptors for which a compiled object needs to be produced.
   473       *
   474       * @return GStreamingCompiled, a streaming-oriented executable
   475       * computation compiled specifically for the given input
   476       * parameters.
   477       */
   478      template<typename... Ts>
   479      auto compileStreaming(const Ts&... metas) ->
   480          typename std::enable_if<detail::are_meta_descrs<Ts...>::value, GStreamingCompiled>::type
   481      {
   482          return compileStreaming(GMetaArgs{GMetaArg(metas)...}, GCompileArgs());
   483      }
   484  
   485      // 2. Direct metadata + compile arguments version
   486      /**
   487       * @overload
   488       *
   489       * Takes a  variadic parameter pack with metadata
   490       * descriptors for which a compiled object needs to be produced,
   491       * followed by GCompileArgs object representing compilation
   492       * arguments for this process.
   493       *
   494       * @return GStreamingCompiled, a streaming-oriented executable
   495       * computation compiled specifically for the given input
   496       * parameters.
   497       */
   498      template<typename... Ts>
   499      auto compileStreaming(const Ts&... meta_and_compile_args) ->
   500          typename std::enable_if<detail::are_meta_descrs_but_last<Ts...>::value
   501                                  && std::is_same<GCompileArgs, detail::last_type_t<Ts...> >::value,
   502                                  GStreamingCompiled>::type
   503      {
   504          //FIXME: wrapping meta_and_compile_args into a tuple to unwrap them inside a helper function is the overkill
   505          return compileStreaming(std::make_tuple(meta_and_compile_args...),
   506                                  typename detail::MkSeq<sizeof...(Ts)-1>::type());
   507      }
   508  
   509      // Internal use only
   510      /// @private
   511      Priv& priv();
   512      /// @private
   513      const Priv& priv() const;
   514      /// @private
   515      explicit GComputation(cv::gapi::s11n::IIStream &);
   516      /// @private
   517      void serialize(cv::gapi::s11n::IOStream &) const;
   518  
   519  protected:
   520  
   521      // 4. Helper methods for (3)
   522      /// @private
   523      template<typename... Ts, int... IIs>
   524      GCompiled compile(const std::tuple<Ts...> &meta_and_compile_args, detail::Seq<IIs...>)
   525      {
   526          GMetaArgs meta_args = {GMetaArg(std::get<IIs>(meta_and_compile_args))...};
   527          GCompileArgs comp_args = std::get<sizeof...(Ts)-1>(meta_and_compile_args);
   528          return compile(std::move(meta_args), std::move(comp_args));
   529      }
   530      template<typename... Ts, int... IIs>
   531      GStreamingCompiled compileStreaming(const std::tuple<Ts...> &meta_and_compile_args, detail::Seq<IIs...>)
   532      {
   533          GMetaArgs meta_args = {GMetaArg(std::get<IIs>(meta_and_compile_args))...};
   534          GCompileArgs comp_args = std::get<sizeof...(Ts)-1>(meta_and_compile_args);
   535          return compileStreaming(std::move(meta_args), std::move(comp_args));
   536      }
   537      void recompile(GMetaArgs&& in_metas, GCompileArgs &&args);
   538      /// @private
   539      std::shared_ptr<Priv> m_priv;
   540  };
   541  /** @} */
   542  
   543  namespace gapi
   544  {
   545      // FIXME: all these standalone functions need to be added to some
   546      // common documentation section
   547      /**
   548       * @brief Define an tagged island (subgraph) within a computation.
   549       *
   550       * Declare an Island tagged with `name` and defined from `ins` to `outs`
   551       * (exclusively, as ins/outs are data objects, and regioning is done on
   552       * operations level).
   553       * Throws if any operation between `ins` and `outs` are already assigned
   554       * to another island.
   555       *
   556       * Islands allow to partition graph into subgraphs, fine-tuning
   557       * the way it is scheduled by the underlying executor.
   558       *
   559       * @param name name of the Island to create
   560       * @param ins vector of input data objects where the subgraph
   561       * begins
   562       * @param outs vector of output data objects where the subgraph
   563       * ends.
   564       *
   565       * The way how an island is defined is similar to how
   566       * cv::GComputation is defined on input/output data objects.
   567       * Same rules apply here as well -- if there's no functional
   568       * dependency between inputs and outputs or there's not enough
   569       * input data objects were specified to properly calculate all
   570       * outputs, an exception is thrown.
   571       *
   572       * Use cv::GIn() / cv::GOut() to specify input/output vectors.
   573       */
   574      void GAPI_EXPORTS island(const std::string &name,
   575                               GProtoInputArgs  &&ins,
   576                               GProtoOutputArgs &&outs);
   577  } // namespace gapi
   578  
   579  } // namespace cv
   580  #endif // OPENCV_GAPI_GCOMPUTATION_HPP