函数返回中的 OpenCV Mat 并使用 copyTo

Posted

技术标签:

【中文标题】函数返回中的 OpenCV Mat 并使用 copyTo【英文标题】:OpenCV Mat in function return and using copyTo 【发布时间】:2015-07-16 00:04:01 【问题描述】:

我有这个 sn-p 来执行齐次矩阵的逆

Mat invHom(const Mat A)

    Mat invA = Mat::eye(4,4,CV_64FC1);
    Mat R, P;

    A(Range(0,3), Range(0,3)).copyTo(R);
    A(Range(0,3), Range(3,4)).copyTo(P);

    invA(Range(0,3), Range(0,3)) = R.t();
    invA(Range(0,3), Range(3,4)) = -R.t()*P;
    return invA;

此代码是否容易出错?因为 invA、R、P 是在函数范围内创建的 Mat。函数的“返回”是否执行创建和复制到新的 Mat 对象(即 Mat::copyTo()),以便 invA 的值在函数外部仍然可用?

抱歉我的英语和编程条件不好

没有错误的:

int invHom(const Mat A, Mat& invA_ou)

    Mat invA = Mat::eye(4,4,CV_64FC1);

    Mat R, P;
    A(Range(0,3), Range(0,3)).copyTo(R);
    A(Range(0,3), Range(3,4)).copyTo(P);

    //invA(Range(0,3), Range(0,3)) = R.t();
    //invA(Range(0,3), Range(3,4)) = -R.t()*P;

    Mat tmp1 = R.t();
    tmp1.copyTo(invA(Range(0,3), Range(0,3)));

    Mat tmp = -R.t()*P;
    tmp.copyTo(invA(Range(0,3), Range(3,4)));

    invA.copyTo(invA_ou);
    return 1;

【问题讨论】:

【参考方案1】:

代码没问题。 Mat 是一个对象,基本上由标题和实际数据组成。当您复制 Mat 时,您只是在复制标题,而不是数据(这就是它非常快的原因)。复制时,内部引用计数器会递增。当引用计数器为零时,数据将被释放。 要执行深层复制,您需要方法clone()copyTo(...)

所以,在你的情况下,你很好。

您可以查看 OpenCV 文档 here 了解更多详细信息。

另一种编码风格是将输出矩阵作为参数传递,例如:

void invHom(const Mat& A, Mat& invA)

    invA = Mat::eye(4,4,CV_64FC1);
    Mat R, P;

    A(Range(0,3), Range(0,3)).copyTo(R);
    A(Range(0,3), Range(3,4)).copyTo(P);

    invA(Range(0,3), Range(0,3)) = R.t();
    invA(Range(0,3), Range(3,4)) = -R.t()*P;        

请注意,将引用 (&) 传递给 Mat,您甚至不需要复制标头。

【讨论】:

问题是我的复制是从函数内部创建的对象进行的,所以函数返回后,主调用者​​不会收到这个值 您的 return 语句将复制 Mat(标题),这将为函数内部创建的数据增加引用计数器。当你退出函数时,引用计数器会减少,但数据不会被取消,因为它们仍然被返回的 Mat 引用 如果你想确定,直接返回invA.clone(),但这是不必要的深拷贝。 感谢您的解释!我想更多地了解这种增加引用计数器并在函数存在时减少它的机制。您能帮我解决一些术语,例如 c/c++ 术语吗? 嗨@ray没问题:)我应该检查(可能明天),但是......掩码中的0个元素没有被复制。如果矩阵未初始化,则创建矩阵以正确大小进行零初始化(应检查),然后像以前一样。我从来没有使用带有面具的copyTo。可能 setTo 是您需要的。

以上是关于函数返回中的 OpenCV Mat 并使用 copyTo的主要内容,如果未能解决你的问题,请参考以下文章

如何将 opencv Mat 类型传递给 Python 并返回一个数组?

FFTW 和 OpenCV 的 C++ 接口,Mat 输出中的实部和虚部

使用 JNI 传递和返回 OpenCv Mat 对象

OpenCV Mat 对象 - 获取数据长度

OpenCV:arcLength 断言失败并出现 cv::Mat

将我的数组移动到 Mat 并使用 openCV 显示图像