移动语义和cv :: Mat

时间:2018-05-24 13:21:22

标签: c++ opencv c++11 computer-vision move-semantics

cv::Mat上的Opencv documentation似乎表明目前没有移动构造函数,所以像cv::Mat A=std::move(some_other_cv_mat)这样的东西没有多大意义。我对这个问题的当前(和天真)解决方案是从cv::Mat派生一个类,为此我实现了一个移动构造函数,如下所示:

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; 
          }   
     };

}

虽然这适用于我目前面临的有限问题,但显然存在许多限制,而且解决方案远非理想。那么,为cv::Mat模拟移动语义的最佳方法是什么?

2 个答案:

答案 0 :(得分:4)

没有必要这样做。 cv::Mat的复制构造函数实际上并未复制数据。它基本上是一个引用,所有对象共享相同的数据。

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

  

这是一个重载的成员函数,为方便起见而提供。它与上述函数的不同之处仅在于它接受的参数。

     

参数

     

m将(整体或部分)数组分配给构造的矩阵。这些构造函数不会复制任何数据。相反,构造指向m数据或其子数组的标题并将其与之关联。参考计数器(如果有)递增。因此,当您修改使用此类构造函数形成的矩阵时,还会修改m的相应元素。如果要拥有子数组的独立副本,请使用Mat :: clone()

答案 1 :(得分:3)

从4.x开始,OpenCV提供了Mat (Mat &&m)Mat & operator= (Mat &&m)

如果您使用的是4.x之前的版本,我建议您看一下modules/core/include/opencv2/core/mat.inl.hpp中定义的<html> <div> Test string 1. <br>Test string 2. <br>Test string 3. </div> </html> move构造函数和move赋值运算符实现,因为它有点仅复制import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, InputLayer, Dropout, Conv1D, Flatten, Reshape, MaxPooling1D, BatchNormalization from tensorflow.keras import regularizers from tensorflow.keras.optimizers import Adam # model architecture model = Sequential() model.add(InputLayer(input_shape=(X_train.shape[1], ), name='x_input')) model.add(Reshape((int(X_train.shape[1] / 13), 13), input_shape=(X_train.shape[1], ))) model.add(Conv1D(30, kernel_size=1, activation='relu',kernel_regularizer=regularizers.l2(0.001))) model.add(Dropout(0.5)) model.add(MaxPooling1D(pool_size=1, padding='same')) model.add(Conv1D(10, kernel_size=1, activation='relu',kernel_regularizer=regularizers.l2(0.001))) model.add(Dropout(0.5)) model.add(MaxPooling1D(pool_size=1, padding='same')) model.add(Flatten()) model.add(Dense(classes, activation='softmax', name='y_pred')) # this controls the learning rate opt = Adam(lr=0.005, beta_1=0.9, beta_2=0.999) #opt = Adadelta(learning_rate=1.0, rho=0.95) # train the neural network model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy']) model.fit(X_train, Y_train, batch_size=50, epochs=200, validation_data=(X_test, Y_test), verbose=2) 成员就更复杂了。