OpenCV Mat在函数返回和使用copyTo

OpenCV Mat in function return and using copyTo

本文关键字:copyTo 返回 Mat 函数 OpenCV      更新时间:2023-10-16

我有这个代码片段来执行齐次矩阵的逆

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都是在函数范围内创建的。函数的"return"是否执行创建&复制到一个新的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是一个对象,主要由标头和实际数据组成。当你复制一个Mat时,你只复制头,而不是数据(这就是为什么它非常快)。复制时,内部引用计数器将递增。当参考计数器为零时,数据将被释放。执行深度拷贝时,需要使用clone()copyTo(...)方法。

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

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

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

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,你甚至不复制头。