ORB

mac2022-06-30  75

ORB_SLAM2 计算 F21 的代码是这样的。

cv::Mat Initializer::ComputeF21(const vector<cv::Point2f> &vP1,const vector<cv::Point2f> &vP2) { const int N = vP1.size(); cv::Mat A(N,9,CV_32F); for(int i=0; i<N; i++) { const float u1 = vP1[i].x; const float v1 = vP1[i].y; const float u2 = vP2[i].x; const float v2 = vP2[i].y; A.at<float>(i,0) = u2*u1; A.at<float>(i,1) = u2*v1; A.at<float>(i,2) = u2; A.at<float>(i,3) = v2*u1; A.at<float>(i,4) = v2*v1; A.at<float>(i,5) = v2; A.at<float>(i,6) = u1; A.at<float>(i,7) = v1; A.at<float>(i,8) = 1; } cv::Mat u,w,vt; cv::SVDecomp(A,w,u,vt,cv::SVD::MODIFY_A | cv::SVD::FULL_UV); cv::Mat Fpre = vt.row(8).reshape(0, 3); cv::SVDecomp(Fpre,w,u,vt,cv::SVD::MODIFY_A | cv::SVD::FULL_UV); w.at<float>(2)=0; return u*cv::Mat::diag(w)*vt; }

F21 的真正意思是:

\[ x_2^TF_{21}x_1^T=0 \]

而写成克罗内克积的形式应该是这样的:

\[ (x_1 \otimes x_2)^TF_{21}^s = 0 \]

\[ (x_1 \otimes x_2)^T = [ u_1 u_2, u_1 v_2, u_1, v_1 u_2, v_1 v_2, v_1, u_2, v_2, 1 ]^T \]

这样上面的代码不是写错了吗?

不,OpenCV 是“ROW stack”,而数学公式里面写的是“COL stack”。

OpenCV:

\[F_{21}^s = [f_{11}, f_{12}, f_{13}, …, f_{31}, f_{32}, f_{33}]^T\]

数学公式:

\[F_{21}^s = [f_{11}, f_{21}, f_{31}, …, f_{13}, f_{23}, f_{33}]^T\]

总结

“ROW stack”用$ (x_2 \otimes x_1)^T $ 计算 \(F_{21}\)。“COL stack”用$ (x_1 \otimes x_2)^T $,计算 \(F_{21}\)

转载于:https://www.cnblogs.com/JingeTU/p/6519120.html

最新回复(0)