Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

move semantics and cv::Mat

Opencv's documentation on cv::Mat seems to indicate that there are no move constructors at the moment, so something like cv::Mat A=std::move(some_other_cv_mat) doesn't make much sense. My current (and naïve) solution to this problem is to derive a class from cv::Mat, for which I implement a move constructor as follows:

namespace cv
{
    //matrix object derived from cv::Mat
    class Mvbl_Mat final: public Mat 
    {
        public:
          //constructors
          Mvbl_Mat(){};
          Mvbl_Mat(int rows, int cols, int type, const Scalar   &s):Mat(rows, cols, type, s){}
         //destructor
         ~Mvbl_Mat(){};

          //move constructor
          Mvbl_Mat(Mvbl_Mat && other) noexcept
          {   
              this->data=other.data;
              other.data=nullptr;
           } 
          //move assignment operator
          Mvbl_Mat & operator=(Mvbl_Mat && other)
          {   
              this->data=other.data;
              other.data=nullptr;
              return *this; 
          }   
     };

}

While this works for the limited problems that I face at the moment, there are obviously many limitations and the solution is far from ideal. So, what is the best way to emulate move semantics for cv::Mat?

like image 484
Ash Avatar asked May 24 '18 13:05

Ash


2 Answers

There is no need to do this. cv::Mat's copy constructor doesn't actually copy the data. It basically makes a reference and all objects share the same data.

cv::Mat::Mat(const Mat & m)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Parameters

m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied by these constructors. Instead, the header pointing to m data or its sub-array is constructed and associated with it. The reference counter, if any, is incremented. So, when you modify the matrix formed using such a constructor, you also modify the corresponding elements of m . If you want to have an independent copy of the sub-array, use Mat::clone()

like image 182
NathanOliver Avatar answered Oct 21 '22 09:10

NathanOliver


As of 4.x OpenCV provides Mat (Mat &&m) and Mat & operator= (Mat &&m).

If you are working on a version prior to 4.x, I'd suggest to take a look at the cv::Mat move constructor and move assignment operator implementations defined in modules/core/include/opencv2/core/mat.inl.hpp, as it's a little more complicated that just copying the .data member.

like image 31
Sdra Avatar answered Oct 21 '22 10:10

Sdra