矩阵的简单传递,即。 cv::Mat 到 OpenCV2.4 中的函数

Posted

技术标签:

【中文标题】矩阵的简单传递,即。 cv::Mat 到 OpenCV2.4 中的函数【英文标题】:Simple passing of Matrices ie. cv::Mat to functions in OpenCV2.4 【发布时间】:2012-06-13 14:18:47 【问题描述】:

我是 opencv 新手,我对编码中最简单的操作之一有疑问:将值传递给函数。

这就是我想做的,

    在 main 函数中初始化一个 cv:Mat,例如,从 0 到 50 的值。 将此矩阵作为参数传递给函数foo(),该函数又简单地打印出矩阵中每个元素的值。就是这样。

现在我在多个地方读到,当传递这些矩阵时,传递的只是标题,而不是实际数据。那我怎么还能在被调用函数中读出这个矩阵的值,就好像整个矩阵都被传递了一样?

【问题讨论】:

这些地方在哪里?你能分享他们的参考资料吗? opencv.willowgarage.com/documentation/cpp/… 【参考方案1】:

要了解发生了什么,您需要查看 C++ constructors,更具体地说是 copy constructor

当您从另一个cv::Mat 创建cv::Mat 时,如下所示:

cv::Mat a = cv::imread("huge.png", 1);
cv::Mat b = a;

调用cv::Mat复制构造函数(它是一个函数)来执行对象的复制。在我谈论复制过程中发生的事情之前,您必须意识到cv::Mat 用于存储图像,较大的图像可能会占用数百兆的内存。所以上面例子中cv::Mat复制构造函数所做的是将a的整个标题(高度、宽度、深度信息等)复制到b中,而不是复制a 的整个数据/像素(可能是数百 MB),它只是指向(使用指针)a 的原始数据。

换句话说,不复制整个图像数据是一项优化/性能决定

现在,考虑这个调用函数并将cv::Mat 作为参数传递的代码:

void do_something(cv::Mat src)

    // changing src pixels will be the same as changing orig pixels


int main()

    cv::Mat orig = cv::imread("huge.png", 1);
    do_something(orig);
    return 0;

如果你研究过如何将参数传递给函数,你就会知道调用do_something(a);pass the parameter by value。这意味着它将尝试将orig 的内容复制到src,但是,此过程会激活cv::Mat 的复制构造函数,它不会像我刚才解释的那样制作数据的硬拷贝。

解决这个问题?如果您正在编写do_something(),并且您只想制作orig 的真实副本,只需创建一个新的cv::Mat 并调用方法copyTo()

void do_something(cv::Mat src)

    cv::Mat real_copy = src.copyTo();
    // operating on the data of real_copy will not affect orig

但请记住,如果 src 约为 100MB,则调用 copyTo() 来制作真实副本将占用另外的 ~100MB 内存,这意味着在单个函数调用中,您的程序刚刚从 100MB 变为 200MB。在设计系统时请记住这一点。祝你好运。

【讨论】:

优秀。就像您读懂了我的想法并回答了我的确切问题。先生非常感谢您。非常感谢。 酷,只需点击它旁边的复选框即可将其选为官方答案。

以上是关于矩阵的简单传递,即。 cv::Mat 到 OpenCV2.4 中的函数的主要内容,如果未能解决你的问题,请参考以下文章

open cv mat怎样将数据类型转化为double

如何将像素数据的所有权传递给 cv::Mat

将八度矩阵转换为 oct 文件中的 cv::Mat

合并两个 cv::Mat 而不复制数据

OpenCV 中的矩阵乘法 - 结合 cv::Mat 和 cv::Scalar 对象

cv::Mat 转换为特征矩阵并返回