FindFundamentalMatrix找不到基本矩阵

Una*_*dra 5 opencv image-processing computer-vision

我试图通过使用基本矩阵和维基百科上给出的算法来恢复相机的运动.为此,我需要找到基本矩阵.我正在使用 OpenCV::findFundamentalMat这个.

两个意外的行为:

  1. 使用不同的拟合算法产生不同的结果,尤其FM_8POINT是不同的.
  2. 给定一组点对(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;
   }
}
Run Code Online (Sandbox Code Playgroud)

因为FM_RANSAC我明白了

[1.999], [2], [2], [1.599], [1.599], [1.599], [1.198], [1.198], [1.198], [0.798], [0.798], [0.798]
Run Code Online (Sandbox Code Playgroud)

对于FM_8POINT该基本矩阵是zeros(3,3),因此yFx为0,所有y,x.

我只发现:基本矩阵的T和R估计,但没有多大帮助.

编辑:yFx圆路错误(p1/ p2在cout-line中切换).这个例子也不起作用,因为所有点都在一个平面上.

Sea*_*ean 3

我相信基本矩阵可以解方程p2.t() * F * p1 = 0,即您的代码中的 p1 和 p2 颠倒了。至于为什么8点算法返回零矩阵,我不知道,抱歉。

编辑:好的,我相信我记得为什么 8 点算法在这里产生不好的结果。两组点之间的运动是纯粹的平移,没有旋转,即它只有三个自由度。基础矩阵有7个自由度,因此无法估计;这称为退化案例。有关基本/本质矩阵估计中退化情况的进一步描述,请参阅本文。

也可能是通过人为移动像素坐标得到的两个视点之间没有刚性变换,因此没有满足要求的基本矩阵。更好的测试用例可能是将 cv::warpPerspective 等函数与已知的扭曲矩阵一起使用。