github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/opencv4/include/opencv2/gapi/own/mat.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_OWN_MAT_HPP
     9  #define OPENCV_GAPI_OWN_MAT_HPP
    10  
    11  #include <opencv2/gapi/opencv_includes.hpp>
    12  #include <opencv2/gapi/own/types.hpp>
    13  #include <opencv2/gapi/own/scalar.hpp>
    14  #include <opencv2/gapi/own/saturate.hpp>
    15  #include <opencv2/gapi/own/assert.hpp>
    16  
    17  #include <memory>                   //std::shared_ptr
    18  #include <cstring>                  //std::memcpy
    19  #include <numeric>                  //std::accumulate
    20  #include <vector>
    21  #include <opencv2/gapi/util/throw.hpp>
    22  
    23  namespace cv { namespace gapi { namespace own {
    24      namespace detail {
    25          template <typename T, unsigned char channels>
    26          void assign_row(void* ptr, int cols, Scalar const& s)
    27          {
    28              auto p = static_cast<T*>(ptr);
    29              for (int c = 0; c < cols; c++)
    30              {
    31                  for (int ch = 0; ch < channels; ch++)
    32                  {
    33                      p[c * channels + ch] = saturate<T>(s[ch], roundd);
    34                  }
    35              }
    36          }
    37  
    38          inline size_t default_step(int type, int cols)
    39          {
    40              return CV_ELEM_SIZE(type) * cols;
    41          }
    42          //Matrix header, i.e. fields that are unique to each Mat object.
    43          //Devoted class is needed to implement custom behavior on move (erasing state of moved from object)
    44          struct MatHeader{
    45              enum { AUTO_STEP = 0};
    46              enum { TYPE_MASK = 0x00000FFF  };
    47  
    48              MatHeader() = default;
    49  
    50              MatHeader(int _rows, int _cols, int type, void* _data, size_t _step)
    51              : flags((type & TYPE_MASK)), rows(_rows), cols(_cols), data((uchar*)_data), step(_step == AUTO_STEP ? detail::default_step(type, _cols) : _step)
    52              {}
    53  
    54              MatHeader(const std::vector<int> &_dims, int type, void* _data)
    55              : flags((type & TYPE_MASK)), data((uchar*)_data), step(0), dims(_dims)
    56              {}
    57  
    58              MatHeader(const MatHeader& ) = default;
    59              MatHeader(MatHeader&& src) : MatHeader(src) // reuse copy constructor here
    60              {
    61                  MatHeader empty; //give it a name to call copy(not move) assignment below
    62                  src = empty;
    63              }
    64              MatHeader& operator=(const MatHeader& ) = default;
    65              MatHeader& operator=(MatHeader&& src)
    66              {
    67                  *this = src; //calling a copy assignment here, not move one
    68                  MatHeader empty; //give it a name to call copy(not move) assignment below
    69                  src = empty;
    70                  return *this;
    71              }
    72              /*! includes several bit-fields:
    73                   - depth
    74                   - number of channels
    75               */
    76              int flags = 0;
    77  
    78              //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
    79              int rows = 0, cols = 0;
    80              //! pointer to the data
    81              uchar* data = nullptr;
    82              size_t step = 0;
    83              //! dimensions (ND-case)
    84              std::vector<int> dims;
    85          };
    86      } // namespace detail
    87      //concise version of cv::Mat suitable for GAPI needs (used when no dependence on OpenCV is required)
    88      class Mat : public detail::MatHeader{
    89      public:
    90  
    91          Mat() = default;
    92  
    93          /** @overload
    94          @param _rows Number of rows in a 2D array.
    95          @param _cols Number of columns in a 2D array.
    96          @param _type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
    97          CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
    98          @param _data Pointer to the user data. Matrix constructors that take data and step parameters do not
    99          allocate matrix data. Instead, they just initialize the matrix header that points to the specified
   100          data, which means that no data is copied. This operation is very efficient and can be used to
   101          process external data using OpenCV functions. The external data is not automatically deallocated, so
   102          you should take care of it.
   103          @param _step Number of bytes each matrix row occupies. The value should include the padding bytes at
   104          the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed
   105          and the actual step is calculated as cols*elemSize(). See Mat::elemSize.
   106          */
   107          Mat(int _rows, int _cols, int _type, void* _data, size_t _step = AUTO_STEP)
   108          : MatHeader (_rows, _cols, _type, _data, _step)
   109          {}
   110  
   111          Mat(const std::vector<int> &_dims, int _type, void* _data)
   112          : MatHeader (_dims, _type, _data)
   113          {}
   114  
   115          Mat(std::vector<int> &&_dims, int _type, void* _data)
   116          : MatHeader (std::move(_dims), _type, _data)
   117          {}
   118  
   119          Mat(Mat const& src, const Rect& roi )
   120          : Mat(src)
   121          {
   122             rows = roi.height;
   123             cols = roi.width;
   124             data = ptr(roi.y, roi.x);
   125          }
   126  
   127          Mat(Mat const& ) = default;
   128          Mat(Mat&& ) = default;
   129  
   130          Mat& operator=(Mat const& ) = default;
   131          Mat& operator=(Mat&& ) = default;
   132  
   133          /** @brief Sets all or some of the array elements to the specified value.
   134          @param s Assigned scalar converted to the actual array type.
   135          */
   136          Mat& operator = (const Scalar& s)
   137          {
   138              constexpr unsigned max_channels = 4; //Scalar can't fit more than 4
   139              using func_p_t = void (*)(void*, int, Scalar const&);
   140              using detail::assign_row;
   141              #define TABLE_ENTRY(type)  {assign_row<type, 1>, assign_row<type, 2>, assign_row<type, 3>, assign_row<type, 4>}
   142              static constexpr func_p_t func_tbl[][max_channels] = {
   143                      TABLE_ENTRY(uchar),
   144                      TABLE_ENTRY(schar),
   145                      TABLE_ENTRY(ushort),
   146                      TABLE_ENTRY(short),
   147                      TABLE_ENTRY(int),
   148                      TABLE_ENTRY(float),
   149                      TABLE_ENTRY(double)
   150              };
   151              #undef TABLE_ENTRY
   152  
   153              static_assert(CV_8U == 0 && CV_8S == 1  && CV_16U == 2 && CV_16S == 3
   154                         && CV_32S == 4 && CV_32F == 5 && CV_64F == 6,
   155                         "OCV type ids used as indexes to array, thus exact numbers are important!"
   156              );
   157  
   158              const auto depth = static_cast<unsigned int>(this->depth());
   159              GAPI_Assert(depth < sizeof(func_tbl)/sizeof(func_tbl[0]));
   160  
   161              if (dims.empty())
   162              {
   163                  const auto channels = static_cast<unsigned int>(this->channels());
   164                  GAPI_Assert(channels <= max_channels);
   165  
   166                  auto* f = func_tbl[depth][channels - 1];
   167                  for (int r = 0; r < rows; ++r)
   168                  {
   169                      (*f)(static_cast<void *>(ptr(r)), cols, s );
   170                  }
   171              }
   172              else
   173              {
   174                  auto* f = func_tbl[depth][0];
   175                  // FIXME: better to refactor assign_row to use std::size_t by default
   176                  (*f)(static_cast<void *>(data), static_cast<int>(total()), s);
   177              }
   178              return *this;
   179          }
   180  
   181          /** @brief Returns the matrix element size in bytes.
   182  
   183          The method returns the matrix element size in bytes. For example, if the matrix type is CV_16SC3 ,
   184          the method returns 3\*sizeof(short) or 6.
   185           */
   186          size_t elemSize() const
   187          {
   188              return CV_ELEM_SIZE(type());
   189          }
   190          /** @brief Returns the type of a matrix element.
   191  
   192          The method returns a matrix element type. This is an identifier compatible with the CvMat type
   193          system, like CV_16SC3 or 16-bit signed 3-channel array, and so on.
   194           */
   195          int type() const            {return CV_MAT_TYPE(flags);}
   196  
   197          /** @brief Returns the depth of a matrix element.
   198  
   199          The method returns the identifier of the matrix element depth (the type of each individual channel).
   200          For example, for a 16-bit signed element array, the method returns CV_16S . A complete list of
   201          matrix types contains the following values:
   202          -   CV_8U - 8-bit unsigned integers ( 0..255 )
   203          -   CV_8S - 8-bit signed integers ( -128..127 )
   204          -   CV_16U - 16-bit unsigned integers ( 0..65535 )
   205          -   CV_16S - 16-bit signed integers ( -32768..32767 )
   206          -   CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
   207          -   CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
   208          -   CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
   209           */
   210          int depth() const           {return CV_MAT_DEPTH(flags);}
   211  
   212          /** @brief Returns the number of matrix channels.
   213  
   214          The method returns the number of matrix channels.
   215          If matrix is N-dimensional, -1 is returned.
   216           */
   217          int channels() const        {return dims.empty() ? CV_MAT_CN(flags) : -1;}
   218  
   219          /**
   220          @param _rows New number of rows.
   221          @param _cols New number of columns.
   222          @param _type New matrix type.
   223           */
   224          void create(int _rows, int _cols, int _type)
   225          {
   226              create(Size{_cols, _rows}, _type);
   227          }
   228          /** @overload
   229          @param _size Alternative new matrix size specification: Size(cols, rows)
   230          @param _type New matrix type.
   231          */
   232          void create(Size _size, int _type)
   233          {
   234              GAPI_Assert(_size.height >= 0 && _size.width >= 0);
   235              if (_size != Size{cols, rows} )
   236              {
   237                  Mat tmp{_size.height, _size.width, _type, nullptr};
   238                  tmp.memory.reset(new uchar[ tmp.step * tmp.rows], [](uchar * p){delete[] p;});
   239                  tmp.data = tmp.memory.get();
   240  
   241                  *this = std::move(tmp);
   242              }
   243          }
   244  
   245          void create(const std::vector<int> &_dims, int _type)
   246          {
   247              // FIXME: make a proper reallocation-on-demands
   248              // WARNING: no tensor views, so no strides
   249              Mat tmp{_dims, _type, nullptr};
   250              // FIXME: this accumulate duplicates a lot
   251              const auto sz = std::accumulate(_dims.begin(), _dims.end(), 1, std::multiplies<int>());
   252              tmp.memory.reset(new uchar[CV_ELEM_SIZE(_type)*sz], [](uchar * p){delete[] p;});
   253              tmp.data = tmp.memory.get();
   254              *this = std::move(tmp);
   255          }
   256  
   257          /** @brief Creates a full copy of the matrix and the underlying data.
   258  
   259          The method creates a full copy of the matrix. The original step[] is not taken into account.
   260          So, the copy has a continuous buffer occupying total() * elemSize() bytes.
   261           */
   262          Mat clone() const
   263          {
   264              Mat m;
   265              copyTo(m);
   266              return m;
   267          }
   268  
   269          /** @brief Copies the matrix to another one.
   270  
   271          The method copies the matrix data to another matrix. Before copying the data, the method invokes :
   272          @code
   273              m.create(this->size(), this->type());
   274          @endcode
   275          so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the
   276          function does not handle the case of a partial overlap between the source and the destination
   277          matrices.
   278           */
   279          void copyTo(Mat& dst) const
   280          {
   281              if (dims.empty())
   282              {
   283                  dst.create(rows, cols, type());
   284                  for (int r = 0; r < rows; ++r)
   285                  {
   286                      std::copy_n(ptr(r), detail::default_step(type(),cols), dst.ptr(r));
   287                  }
   288              }
   289              else
   290              {
   291                  dst.create(dims, depth());
   292                  std::copy_n(data, total()*elemSize(), data);
   293              }
   294          }
   295  
   296          /** @brief Returns true if the array has no elements.
   297  
   298          The method returns true if Mat::total() is 0 or if Mat::data is NULL. Because of pop_back() and
   299          resize() methods `M.total() == 0` does not imply that `M.data == NULL`.
   300           */
   301          bool empty() const
   302          {
   303              return data == 0 || total() == 0;
   304          }
   305  
   306          /** @brief Returns the total number of array elements.
   307  
   308          The method returns the number of array elements (a number of pixels if the array represents an
   309          image).
   310           */
   311          size_t total() const
   312          {
   313              return dims.empty()
   314                   ? (static_cast<std::size_t>(rows) * cols)
   315                   : std::accumulate(dims.begin(), dims.end(), static_cast<std::size_t>(1), std::multiplies<size_t>());
   316          }
   317  
   318          /** @overload
   319          @param roi Extracted submatrix specified as a rectangle.
   320          */
   321          Mat operator()( const Rect& roi ) const
   322          {
   323              return Mat{*this, roi};
   324          }
   325  
   326  
   327          /** @brief Returns a pointer to the specified matrix row.
   328  
   329          The methods return `uchar*` or typed pointer to the specified matrix row. See the sample in
   330          Mat::isContinuous to know how to use these methods.
   331          @param row Index along the dimension 0
   332          @param col Index along the dimension 1
   333          */
   334          uchar* ptr(int row, int col = 0)
   335          {
   336              return const_cast<uchar*>(const_cast<const Mat*>(this)->ptr(row,col));
   337          }
   338          /** @overload */
   339          const uchar* ptr(int row, int col = 0) const
   340          {
   341              return data + step * row + CV_ELEM_SIZE(type()) * col;
   342          }
   343  
   344  
   345      private:
   346          //actual memory allocated for storage, or nullptr if object is non owning view to over memory
   347          std::shared_ptr<uchar> memory;
   348      };
   349  
   350  } //namespace own
   351  } //namespace gapi
   352  } //namespace cv
   353  
   354  #endif /* OPENCV_GAPI_OWN_MAT_HPP */