如何在不复制数据的情况下将 cv::Mat 转换为 2d std::vector
Posted
技术标签:
【中文标题】如何在不复制数据的情况下将 cv::Mat 转换为 2d std::vector【英文标题】:How to convert a cv::Mat to a 2d std::vector without copying data 【发布时间】:2019-10-03 10:40:14 【问题描述】:在 OpenCV 中,我有 cv::Mat 对象。
它是一个通道,格式为 CV_8UC1 = unsigned char。
连续,即数据存储在一个地方,逐行存储。
我知道 cv::Mat 对象的行数和列数。
我有大小为 2D std::vector 向量 vec1(行,向量(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);
谢谢。
【问题讨论】:
你不能用vector
。也许span
?
貌似cv::Mat
类中数据的指针是public
,也就是说可以通过img.data
直接访问。但是,你无法操作指向std::vector
中数据的指针,所以恐怕无法为所欲为。
这根本不可能。您不能将向量的数据设置到其他地方管理的某些内存中。
【参考方案1】:
简短的回答是你不应该尝试在 std::vector
和 cv::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 将是原始图像中的一行(并且它将与原始图像共享数据),或者以您需要的任何方式使用它。
【讨论】:
以上是关于如何在不复制数据的情况下将 cv::Mat 转换为 2d std::vector的主要内容,如果未能解决你的问题,请参考以下文章
如何在不将字体转换为轮廓的情况下将 cairo-pdf 转换为 eps
如何在不丢失值的情况下将 json 解析为 pandas 数据框? [复制]
如何在不使用画布的情况下将整个 div 数据转换为图像并将其保存到目录中?