如何在不复制数据的情况下将cv :: Mat转换为2d std :: vector

时间:2019-10-03 10:40:14

标签: c++ opencv

在OpenCV中,我有cv :: Mat对象。

  1. 这是一个通道,格式为CV_8UC1 =无符号字符。

  2. 它是连续,这意味着数据存储在一个地方,并逐行存储。

  3. 我知道cv :: Mat对象的行数和列数。

  4. 我有2D std :: vector大小 vector vec1(行,vector(img.cols));

我如何将cv :: Mat对象的数据分配给std :: vector 而无需复制

对于复制,创建一个for循环很容易,或者可以使用带有迭代器的vector :: assign。

cv :: Mat和2D-std :: vector之间的数据存储相同。两者都有一个指向数据的内部指针(vector :: data和Mat :: ptr),但不能将vector :: data设置为Mat :: ptr的值。

当前,我具有用于复制数据的代码:

cv::Mat img = cv::imread("test.tif");
cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);

vector< vector<double> > vec1(img.rows, vector<double>(img.cols));

for(int i=0; i < img.rows; ++i)
    for(int j=0; j < img.cols; ++j)
        vec1.at(i).at(j) = img.at<double>(i, j);

感谢。

1 个答案:

答案 0 :(得分:0)

简短的答案是,您不应该尝试在std::vectorcv::Mat之间共享数据,因为两者都拥有数据所有权,而cv::Mat可以与其他cv::Mat共享数据对象,并且很快就会变得难以处理。

但是cv::Mat可以与另一个cv::Mat共享数据,您可以提取一个或多个行(或列),并与另一个cv::Mat共享部分共享数据,如下所示:

    cv::Mat img;
    //.. read the img

    //first row
    cv::Mat row0 = img(cv::Range(0,1), cv::Range(0,img.cols));

    //the 4'th column is shared
    cv::Mat column3 = img(cv::Range(0,img.rows), cv::Range(3,4));
    //you can set new data into column3/row0 and you'll see it's shared:
    //row0.setTo(0);
    //column3.setTo(0);

现在,您可以创建一个std::vector<cv::Mat>,其中每个Mat将在原始图像中排成一行(并且它将与原始图像共享数据),或以您需要的任何方式使用它。