c++ - 函数返回和使用 copyTo 中的 OpenCV Mat

标签 c++ c opencv

我有这个片段来执行齐次矩阵的逆运算

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;
}

最佳答案

代码没问题。 Mat 是一个基本上由 header 和实际数据组成的对象。当您复制 Mat 时,您只是在复制 header ,而不是数据(这就是它非常快的原因)。复制时,内部引用计数器会增加。当引用计数器为零时,数据将被释放。 要执行深拷贝,您需要方法 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,您甚至不需要复制 header 。

关于c++ - 函数返回和使用 copyTo 中的 OpenCV Mat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31443288/

相关文章:

c++ - 访问冲突写入位置 0x0000000a

C++ 计算器跳过 Else 语句

c - 如何编写分配完整数据结构的函数

ios - CvVideoCamera - 相机不可用,Iphone 模拟器

c++ - 是否可以使用 opencv 将旋转图像复制到另一个图像的 rotatedrect ROI 中?

c++ - 在 C++ 中将指针传递给函数

c++ - 使用 Win32 子类化现有窗口

c - #include "existing file"失败 : no such file (C)

c - WinAPI C - 来自 REDMON_USER 和 REDMON_SESSIONID 的 RunAsUser

python - 从 rtsp H.264 视频流中捕获单个图像