OpenCV Mat函数返回并使用copyTo

时间:2015-07-16 00:04:02

标签: 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;
}

1 个答案:

答案 0 :(得分:2)

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

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

您可以查看OpenCV doc 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,您甚至不会复制标题。