我有这个代码片段来执行齐次矩阵的逆
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
,你甚至不复制头。