如何将C++数组转换为OpenCV Mat。

15

如何快速将C++数组转换为2D opencv Mat对象? 暴力方法是遍历2D矩阵的所有条目,并使用数组的值填充它们。
是否有更好/更快的方法来完成这个任务?
我能否只是将数组的指针传递给2D矩阵?
(我正在使用opencv 2.4.8)


1
阅读OpenCV的文档!它有清晰的解释。 - Elvis Dukaj
参见:https://dev59.com/rWct5IYBdhLWcg3wXsXH - Haozhe Xie
2个回答

34
是的,有的,在cv::Mat文档中可以看到如何实现这一点。
具体来说,在这一行中:

C++: Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)

这意味着你可以做类似的事情。
double x[100][100];

cv::Mat A(100, 100, CV_64F, x);

这不会将数据复制到其中。您还必须记住,OpenCV数据是按行主序排列的,这意味着它将所有列放在一行中,然后是下一行,依此类推。因此,您的数组必须与此样式匹配才能正常工作。
关于速度,文档也有相关说明:
“data” - 指向用户数据的指针。使用data和step参数的矩阵构造函数不会分配矩阵数据。相反,它们只是初始化指向指定数据的矩阵头,这意味着不会复制任何数据。这个操作非常高效,可以用来使用OpenCV函数处理外部数据。外部数据不会自动释放,所以您需要自行处理。
它的工作速度非常快,但它是同一个数组,如果您在cv::Mat之外对其进行修改,它也会在cv::Mat中被修改,如果在任何时候销毁它,cv::Mat的data成员将指向一个不存在的位置。
更新:
我忘了还要说,你可以创建cv::Mat并使用std::memcpy进行操作。这样做的话,它会复制数据,可能会慢一些,但数据将由cv::Mat对象拥有,并在cv::Mat销毁时被销毁。
double x[100][100];
cv::Mat A(100,100,CV_64F);
std::memcpy(A.data, x, 100*100*sizeof(double));

2
这不会将数据复制到它上面。这行代码解决了我的崩溃问题... - Kai Wang

1
#include <opencv2/opencv.hpp>

int main()
{
    // First row contains 3 white pixels
    // Second row contains 3 black pixels
    uchar temp[2][3] = {{255, 255, 255}, {0, 0, 0}};

    cv::Mat mat = cv::Mat(2, 3, CV_8UC1);
    // The first element of temp decays to int* data.
    // It means that mat.data tracks temp.
    mat.data = temp[0];

    // Change the upper left pixel to black from temp,
    // the change affects mat.
    temp[0][0] = uchar(0);

    cv::namedWindow("title", cv::WINDOW_NORMAL);
    cv::imshow("title", mat);
    cv::waitKey();
    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接