OpenCV 使用 stride 从数组生成 cv::Mat

Posted

技术标签:

【中文标题】OpenCV 使用 stride 从数组生成 cv::Mat【英文标题】:OpenCV generate cv::Mat from array using stride 【发布时间】:2014-05-22 13:19:42 【问题描述】:

我有一个 RGBA 格式的像素数据数组。虽然我已经使用 GPU 将这些数据转换为灰度(因此所有 4 个通道都是相同的)。

我现在想在 OpenCV 中使用这个灰度数据,我不想存储相同数据的 4 个副本。是否可以通过指定步幅来从此像素数组创建 cv::Mat 结构。 (即仅每第 4 个字节读取一次)

我正在使用

GLubyte* Img = stuff from GPU;
cv::Mat tmp(height, width, CV_8UC4, Img);

但这会复制所有数据,还是将现有指针包装到 cv::Mat 中而不复制它?如果它在没有复制的情况下包装,那么我很乐意使用标准的 c++ 例程将我想要的数据从 Img 复制到新的内存部分,然后将其包装为 cv::Mat。

否则,您如何建议这样做以减少被复制的数据量。

谢谢

【问题讨论】:

所以,这会复制所有 4 个频道,但您只需要/想要一个? (到目前为止,它只复制 pointer,而不是数据) 是的,这将复制所有 4 个通道,我只想要 1 个。我不确定这是复制指针还是数据。 仅指针。它是一个借来的指针,所以它不会分配内存或复制任何东西。也许在上面做一个 cvtColor 到灰度? 哦,请把上面的宽、高倒过来。 啊啊,解决了。感谢您指出。我已经有一个灰度图像,因此浪费 CPU 周期将灰度转换为灰度似乎毫无意义。我只是将我想要的值复制到一个新的缓冲区并将其转换为 cvMat。谢谢 【参考方案1】:

您正在使用的代码

cv::Mat tmp(rows, cols, CV_8UC4, dataPointer);

不执行任何复制,只分配Mat 实例的data 字段。

如果您可以使用 4 个通道的矩阵,那就继续吧。 否则,如果您更喜欢使用 1 通道矩阵,则只需使用函数 cv::cvtColor() 来创建具有单通道的新图像(但随后您将在内存中获得一个额外的图像并为转换支付 CPU 周期) :

cv::Mat grey;
cv::cvtColor(tmp, grey, CV_BGR2GRAY);

最后,最后一件事:如果您可以预先对颜色平面进行反交错(例如在 GPU 上)并获得一些带有 [blue plane, green plane, red plane] 的图像,那么您可以将 CV_8UC1 作为图像类型传入tmp 的构造,你得到一个没有任何数据副本的单通道灰度图像。

【讨论】:

以上是关于OpenCV 使用 stride 从数组生成 cv::Mat的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++/OpenCV 中将 cv::Point 添加到数组或向量?

从 java opencv 中的字节数组创建 CV_16UC1 Mat

打印 cv::Mat opencv

使用 Python 将 OpenCV BoundingRect 转换为 NumPy 数组

如何使用 PIL 对 numpy 数组进行编码,例如 opencv 的 cv2.imencode()?

OpenCV修复方法不会从IC图像中删除文本