github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/opencv4/include/opencv2/gapi/garray.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-2020 Intel Corporation
     6  
     7  
     8  #ifndef OPENCV_GAPI_GARRAY_HPP
     9  #define OPENCV_GAPI_GARRAY_HPP
    10  
    11  #include <functional>
    12  #include <ostream>
    13  #include <vector>
    14  #include <memory>
    15  
    16  #include <opencv2/gapi/own/exports.hpp>
    17  #include <opencv2/gapi/opencv_includes.hpp>
    18  
    19  #include <opencv2/gapi/util/variant.hpp>
    20  #include <opencv2/gapi/util/throw.hpp>
    21  #include <opencv2/gapi/own/assert.hpp>
    22  
    23  #include <opencv2/gapi/gmat.hpp>    // flatten_g only!
    24  #include <opencv2/gapi/gscalar.hpp> // flatten_g only!
    25  
    26  namespace cv
    27  {
    28  // Forward declaration; GNode and GOrigin are an internal
    29  // (user-inaccessible) classes.
    30  class GNode;
    31  struct GOrigin;
    32  template<typename T> class GArray;
    33  
    34  /**
    35   * \addtogroup gapi_meta_args
    36   * @{
    37   */
    38  struct GAPI_EXPORTS_W_SIMPLE GArrayDesc
    39  {
    40      // FIXME: Body
    41      // FIXME: Also implement proper operator== then
    42      bool operator== (const GArrayDesc&) const { return true; }
    43  };
    44  template<typename U> GArrayDesc descr_of(const std::vector<U> &) { return {};}
    45  GAPI_EXPORTS_W inline GArrayDesc empty_array_desc() {return {}; }
    46  /** @} */
    47  
    48  std::ostream& operator<<(std::ostream& os, const cv::GArrayDesc &desc);
    49  
    50  namespace detail
    51  {
    52      // ConstructVec is a callback which stores information about T and is used by
    53      // G-API runtime to construct arrays in host memory (T remains opaque for G-API).
    54      // ConstructVec is carried into G-API internals by GArrayU.
    55      // Currently it is suitable for Host (CPU) plugins only, real offload may require
    56      // more information for manual memory allocation on-device.
    57      class VectorRef;
    58      using ConstructVec = std::function<void(VectorRef&)>;
    59  
    60      // This is the base struct for GArrayU type holder
    61      struct TypeHintBase{virtual ~TypeHintBase() = default;};
    62  
    63      // This class holds type of initial GArray to be checked from GArrayU
    64      template <typename T>
    65      struct TypeHint final : public TypeHintBase{};
    66  
    67      // This class strips type information from GArray<T> and makes it usable
    68      // in the G-API graph compiler (expression unrolling, graph generation, etc).
    69      // Part of GProtoArg.
    70      class GAPI_EXPORTS GArrayU
    71      {
    72      public:
    73          GArrayU(const GNode &n, std::size_t out); // Operation result constructor
    74  
    75          template <typename T>
    76          bool holds() const;                       // Check if was created from GArray<T>
    77  
    78          GOrigin& priv();                          // Internal use only
    79          const GOrigin& priv() const;              // Internal use only
    80  
    81      protected:
    82          GArrayU();                                // Default constructor
    83          GArrayU(const detail::VectorRef& vref);   // Constant value constructor
    84          template<class> friend class cv::GArray;  //  (available to GArray<T> only)
    85  
    86          void setConstructFcn(ConstructVec &&cv);  // Store T-aware constructor
    87  
    88          template <typename T>
    89          void specifyType();                       // Store type of initial GArray<T>
    90  
    91          template <typename T>
    92          void storeKind();
    93  
    94          void setKind(cv::detail::OpaqueKind);
    95  
    96          std::shared_ptr<GOrigin> m_priv;
    97          std::shared_ptr<TypeHintBase> m_hint;
    98      };
    99  
   100      template <typename T>
   101      bool GArrayU::holds() const{
   102          GAPI_Assert(m_hint != nullptr);
   103          using U = typename std::decay<T>::type;
   104          return dynamic_cast<TypeHint<U>*>(m_hint.get()) != nullptr;
   105      };
   106  
   107      template <typename T>
   108      void GArrayU::specifyType(){
   109          m_hint.reset(new TypeHint<typename std::decay<T>::type>);
   110      };
   111  
   112      template <typename T>
   113      void GArrayU::storeKind(){
   114          setKind(cv::detail::GOpaqueTraits<T>::kind);
   115      };
   116  
   117      // This class represents a typed STL vector reference.
   118      // Depending on origins, this reference may be either "just a" reference to
   119      // an object created externally, OR actually own the underlying object
   120      // (be value holder).
   121      class BasicVectorRef
   122      {
   123      public:
   124          // These fields are set by the derived class(es)
   125          std::size_t    m_elemSize = 0ul;
   126          cv::GArrayDesc m_desc;
   127          virtual ~BasicVectorRef() {}
   128  
   129          virtual void mov(BasicVectorRef &ref) = 0;
   130          virtual const void* ptr() const = 0;
   131          virtual std::size_t size() const = 0;
   132      };
   133  
   134      template<typename T> class VectorRefT final: public BasicVectorRef
   135      {
   136          using empty_t  = util::monostate;
   137          using ro_ext_t = const std::vector<T> *;
   138          using rw_ext_t =       std::vector<T> *;
   139          using rw_own_t =       std::vector<T>  ;
   140          util::variant<empty_t, ro_ext_t, rw_ext_t, rw_own_t> m_ref;
   141  
   142          inline bool isEmpty() const { return util::holds_alternative<empty_t>(m_ref);  }
   143          inline bool isROExt() const { return util::holds_alternative<ro_ext_t>(m_ref); }
   144          inline bool isRWExt() const { return util::holds_alternative<rw_ext_t>(m_ref); }
   145          inline bool isRWOwn() const { return util::holds_alternative<rw_own_t>(m_ref); }
   146  
   147          void init(const std::vector<T>* vec = nullptr)
   148          {
   149              m_elemSize = sizeof(T);
   150              if (vec) m_desc = cv::descr_of(*vec);
   151          }
   152  
   153      public:
   154          VectorRefT() { init(); }
   155          virtual ~VectorRefT() {}
   156  
   157          explicit VectorRefT(const std::vector<T>& vec) : m_ref(&vec)      { init(&vec); }
   158          explicit VectorRefT(std::vector<T>& vec)  : m_ref(&vec)           { init(&vec); }
   159          explicit VectorRefT(std::vector<T>&& vec) : m_ref(std::move(vec)) { init(&vec); }
   160  
   161          // Reset a VectorRefT. Called only for objects instantiated
   162          // internally in G-API (e.g. temporary GArray<T>'s within a
   163          // computation).  Reset here means both initialization
   164          // (creating an object) and reset (discarding its existing
   165          // content before the next execution).  Must never be called
   166          // for external VectorRefTs.
   167          void reset()
   168          {
   169              if (isEmpty())
   170              {
   171                  std::vector<T> empty_vector;
   172                  m_desc = cv::descr_of(empty_vector);
   173                  m_ref  = std::move(empty_vector);
   174                  GAPI_Assert(isRWOwn());
   175              }
   176              else if (isRWOwn())
   177              {
   178                  util::get<rw_own_t>(m_ref).clear();
   179              }
   180              else GAPI_Assert(false); // shouldn't be called in *EXT modes
   181          }
   182  
   183          // Obtain a WRITE reference to underlying object
   184          // Used by CPU kernel API wrappers when a kernel execution frame
   185          // is created
   186          std::vector<T>& wref()
   187          {
   188              GAPI_Assert(isRWExt() || isRWOwn());
   189              if (isRWExt()) return *util::get<rw_ext_t>(m_ref);
   190              if (isRWOwn()) return  util::get<rw_own_t>(m_ref);
   191              util::throw_error(std::logic_error("Impossible happened"));
   192          }
   193  
   194          // Obtain a READ reference to underlying object
   195          // Used by CPU kernel API wrappers when a kernel execution frame
   196          // is created
   197          const std::vector<T>& rref() const
   198          {
   199              // ANY vector can be accessed for reading, even if it declared for
   200              // output. Example -- a GComputation from [in] to [out1,out2]
   201              // where [out2] is a result of operation applied to [out1]:
   202              //
   203              //            GComputation boundary
   204              //            . . . . . . .
   205              //            .           .
   206              //     [in] ----> foo() ----> [out1]
   207              //            .           .    :
   208              //            .           . . .:. . .
   209              //            .                V    .
   210              //            .              bar() ---> [out2]
   211              //            . . . . . . . . . . . .
   212              //
   213              if (isROExt()) return *util::get<ro_ext_t>(m_ref);
   214              if (isRWExt()) return *util::get<rw_ext_t>(m_ref);
   215              if (isRWOwn()) return  util::get<rw_own_t>(m_ref);
   216              util::throw_error(std::logic_error("Impossible happened"));
   217          }
   218  
   219          virtual void mov(BasicVectorRef &v) override {
   220              VectorRefT<T> *tv = dynamic_cast<VectorRefT<T>*>(&v);
   221              GAPI_Assert(tv != nullptr);
   222              wref() = std::move(tv->wref());
   223          }
   224  
   225          virtual const void* ptr() const override { return &rref(); }
   226          virtual std::size_t size() const override { return rref().size(); }
   227      };
   228  
   229      // This class strips type information from VectorRefT<> and makes it usable
   230      // in the G-API executables (carrying run-time data/information to kernels).
   231      // Part of GRunArg.
   232      // Its methods are typed proxies to VectorRefT<T>.
   233      // VectorRef maintains "reference" semantics so two copies of VectoRef refer
   234      // to the same underlying object.
   235      // FIXME: Put a good explanation on why cv::OutputArray doesn't fit this role
   236      class VectorRef
   237      {
   238          std::shared_ptr<BasicVectorRef> m_ref;
   239          cv::detail::OpaqueKind m_kind;
   240  
   241          template<typename T> inline void check() const
   242          {
   243              GAPI_DbgAssert(dynamic_cast<VectorRefT<T>*>(m_ref.get()) != nullptr);
   244              GAPI_Assert(sizeof(T) == m_ref->m_elemSize);
   245          }
   246  
   247      public:
   248          VectorRef() = default;
   249          template<typename T> explicit VectorRef(const std::vector<T>& vec)
   250              : m_ref(new VectorRefT<T>(vec))
   251              , m_kind(GOpaqueTraits<T>::kind)
   252          {}
   253          template<typename T> explicit VectorRef(std::vector<T>& vec)
   254              : m_ref(new VectorRefT<T>(vec))
   255              , m_kind(GOpaqueTraits<T>::kind)
   256          {}
   257          template<typename T> explicit VectorRef(std::vector<T>&& vec)
   258              : m_ref(new VectorRefT<T>(std::move(vec)))
   259              , m_kind(GOpaqueTraits<T>::kind)
   260          {}
   261  
   262          cv::detail::OpaqueKind getKind() const
   263          {
   264              return m_kind;
   265          }
   266  
   267          template<typename T> void reset()
   268          {
   269              if (!m_ref) m_ref.reset(new VectorRefT<T>());
   270              check<T>();
   271              storeKind<T>();
   272              static_cast<VectorRefT<T>&>(*m_ref).reset();
   273          }
   274  
   275          template <typename T>
   276          void storeKind()
   277          {
   278              m_kind = cv::detail::GOpaqueTraits<T>::kind;
   279          }
   280  
   281          template<typename T> std::vector<T>& wref()
   282          {
   283              check<T>();
   284              return static_cast<VectorRefT<T>&>(*m_ref).wref();
   285          }
   286  
   287          template<typename T> const std::vector<T>& rref() const
   288          {
   289              check<T>();
   290              return static_cast<VectorRefT<T>&>(*m_ref).rref();
   291          }
   292  
   293          // Check if was created for/from std::vector<T>
   294          template <typename T> bool holds() const
   295          {
   296              if (!m_ref) return false;
   297              using U = typename std::decay<T>::type;
   298              return dynamic_cast<VectorRefT<U>*>(m_ref.get()) != nullptr;
   299          }
   300  
   301          void mov(VectorRef &v)
   302          {
   303              m_ref->mov(*v.m_ref);
   304          }
   305  
   306          cv::GArrayDesc descr_of() const
   307          {
   308              return m_ref->m_desc;
   309          }
   310  
   311          std::size_t size() const
   312          {
   313              return m_ref->size();
   314          }
   315  
   316          // May be used to uniquely identify this object internally
   317          const void *ptr() const { return m_ref->ptr(); }
   318      };
   319  
   320      // Helper (FIXME: work-around?)
   321      // stripping G types to their host types
   322      // like cv::GArray<GMat> would still map to std::vector<cv::Mat>
   323      // but not to std::vector<cv::GMat>
   324  #if defined(GAPI_STANDALONE)
   325  #  define FLATTEN_NS cv::gapi::own
   326  #else
   327  #  define FLATTEN_NS cv
   328  #endif
   329      template<class T> struct flatten_g;
   330      template<> struct flatten_g<cv::GMat>         { using type = FLATTEN_NS::Mat; };
   331      template<> struct flatten_g<cv::GScalar>      { using type = FLATTEN_NS::Scalar; };
   332      template<class T> struct flatten_g<GArray<T>> { using type = std::vector<T>; };
   333      template<class T> struct flatten_g            { using type = T; };
   334  #undef FLATTEN_NS
   335      // FIXME: the above mainly duplicates "ProtoToParam" thing from gtyped.hpp
   336      // but I decided not to include gtyped here - probably worth moving that stuff
   337      // to some common place? (DM)
   338  } // namespace detail
   339  
   340  /** \addtogroup gapi_data_objects
   341   * @{
   342   */
   343  /**
   344   * @brief `cv::GArray<T>` template class represents a list of objects
   345   * of class `T` in the graph.
   346   *
   347   * `cv::GArray<T>` describes a functional relationship between
   348   * operations consuming and producing arrays of objects of class
   349   * `T`. The primary purpose of `cv::GArray<T>` is to represent a
   350   * dynamic list of objects -- where the size of the list is not known
   351   * at the graph construction or compile time. Examples include: corner
   352   * and feature detectors (`cv::GArray<cv::Point>`), object detection
   353   * and tracking  results (`cv::GArray<cv::Rect>`). Programmers can use
   354   * their own types with `cv::GArray<T>` in the custom operations.
   355   *
   356   * Similar to `cv::GScalar`, `cv::GArray<T>` may be value-initialized
   357   * -- in this case a graph-constant value is associated with the object.
   358   *
   359   * `GArray<T>` is a virtual counterpart of `std::vector<T>`, which is
   360   * usually used to represent the `GArray<T>` data in G-API during the
   361   * execution.
   362   *
   363   * @sa `cv::GOpaque<T>`
   364   */
   365  template<typename T> class GArray
   366  {
   367  public:
   368      // Host type (or Flat type) - the type this GArray is actually
   369      // specified to.
   370      /// @private
   371      using HT = typename detail::flatten_g<typename std::decay<T>::type>::type;
   372  
   373      /**
   374       * @brief Constructs a value-initialized `cv::GArray<T>`
   375       *
   376       * `cv::GArray<T>` objects  may have their values
   377       * be associated at graph construction time. It is useful when
   378       * some operation has a `cv::GArray<T>` input which doesn't change during
   379       * the program execution, and is set only once. In this case,
   380       * there is no need to declare such `cv::GArray<T>` as a graph input.
   381       *
   382       * @note The value of `cv::GArray<T>` may be overwritten by assigning some
   383       * other `cv::GArray<T>` to the object using `operator=` -- on the
   384       * assigment, the old association or value is discarded.
   385       *
   386       * @param v a std::vector<T> to associate with this
   387       * `cv::GArray<T>` object. Vector data is copied into the
   388       * `cv::GArray<T>` (no reference to the passed data is held).
   389       */
   390      explicit GArray(const std::vector<HT>& v) // Constant value constructor
   391          : m_ref(detail::GArrayU(detail::VectorRef(v))) { putDetails(); }
   392  
   393      /**
   394       * @overload
   395       * @brief Constructs a value-initialized `cv::GArray<T>`
   396       *
   397       * @param v a std::vector<T> to associate with this
   398       * `cv::GArray<T>` object. Vector data is moved into the `cv::GArray<T>`.
   399       */
   400      explicit GArray(std::vector<HT>&& v)      // Move-constructor
   401          : m_ref(detail::GArrayU(detail::VectorRef(std::move(v)))) { putDetails(); }
   402  
   403      /**
   404       * @brief Constructs an empty `cv::GArray<T>`
   405       *
   406       * Normally, empty G-API data objects denote a starting point of
   407       * the graph. When an empty `cv::GArray<T>` is assigned to a result
   408       * of some operation, it obtains a functional link to this
   409       * operation (and is not empty anymore).
   410       */
   411      GArray() { putDetails(); }                // Empty constructor
   412  
   413      /// @private
   414      explicit GArray(detail::GArrayU &&ref)    // GArrayU-based constructor
   415          : m_ref(ref) { putDetails(); }        //   (used by GCall, not for users)
   416  
   417      /// @private
   418      detail::GArrayU strip() const {
   419          return m_ref;
   420      }
   421      /// @private
   422      static void VCtor(detail::VectorRef& vref) {
   423          vref.reset<HT>();
   424      }
   425  
   426  private:
   427      void putDetails() {
   428          m_ref.setConstructFcn(&VCtor);
   429          m_ref.specifyType<HT>();  // FIXME: to unify those 2 to avoid excessive dynamic_cast
   430          m_ref.storeKind<HT>();    //
   431      }
   432  
   433      detail::GArrayU m_ref;
   434  };
   435  
   436  /** @} */
   437  
   438  } // namespace cv
   439  
   440  #endif // OPENCV_GAPI_GARRAY_HPP