我正在尝试使用基础矩阵和维基百科上给出的算法来恢复相机的运动。为此,我需要找到基础矩阵。我使用
两个意外行为:
以下是一个最小示例。创建12个人工点,将每个点向右移动10个像素,从这些点集中找到基础矩阵,并为每个点打印
示例:
对于
对于
我只找到了:从本质矩阵中估计T和R,但那并没有帮助太多。 编辑:
OpenCV::findFundamentalMat
来实现这一点。两个意外行为:
- 使用不同的拟合算法会产生不同的结果,特别是
FM_8POINT
。 - 给定一组点对(y,x),yFx=0未被满足,总是大于0。
以下是一个最小示例。创建12个人工点,将每个点向右移动10个像素,从这些点集中找到基础矩阵,并为每个点打印
yFx
。示例:
int main(int argc, const char* argv[])
{
// Create two sets of points. Points in pts2 are moved 10pixel to the right of the points in pts1.
std::vector<cv::Point2f> pts1, pts2;
for(double y = 0; y < 460; y+=150)
{
for(double x= 0; x < 320; x += 150)
{
pts1.push_back(cv::Point2f(x, y));
pts2.push_back(cv::Point2f(x+10.0, y));
}
}
cv::Mat F = cv::findFundamentalMat(pts1, pts2);
for(int i = 0; i < pts1.size(); i++)
{
// Creating p1, p2, the two points. Please let me know if this can be done in fewer lines.
cv::Mat p1(3,1, CV_64FC1), p2(3,1, CV_64FC1);
p1.at<double>(0) = pts1.at(i).x;
p1.at<double>(1) = pts1.at(i).y;
p1.at<double>(2) = 1.0;
p2.at<double>(0) = pts2.at(i).x;
p2.at<double>(1) = pts2.at(i).y;
p2.at<double>(2) = 1.0;
// Print yFx for each pair of points. This should be 0 for all.
cout << p1.t() * F * p2 << endl;
}
}
对于
FM_RANSAC
,我得到[1.999], [2], [2], [1.599], [1.599], [1.599], [1.198], [1.198], [1.198], [0.798], [0.798], [0.798]
对于
FM_8POINT
,基础矩阵是zeros(3,3)
,因此对于所有的y
和x
,yFx
都是0。我只找到了:从本质矩阵中估计T和R,但那并没有帮助太多。 编辑:
yFx
的顺序是错误的(在cout行中交换p1
/p2
)。这个例子也不起作用,因为所有的点都在一个平面上。