【问题标题】:Better estimation of Homography using Kalman filter?使用卡尔曼滤波器更好地估计单应性?
【发布时间】:2013-07-26 08:10:50
【问题描述】:

我正在创建一个 AR 应用程序,它可以跟踪特征、计算单应性,然后从 3D-2D 点对应关系中获取对象的姿势,并使用它来渲染任何 3D 对象。

我正在选择一个特定区域来检测源图像上的特征(通过遮罩)。然后将其与在后续帧上检测到的特征进行匹配。然后过滤这些匹配项并估计未屏蔽区域的单应性。

问题在于单应性估计。它每次都不同(非常轻微,但仍然不同)。效果是:即使我的相机保持静止,我也会在我的跟踪区域周围得到一个振动矩形,我使用估计的单应性绘制它。

我已经发布了一个标题为Unstable homography estimation using ORB 的问题,并得到了我正在考虑的事实的保证(如果该区域的位置与其上一个位置相似,则不会重新计算我的单应性)。

不过,我最近知道了卡尔曼滤波器,它通过将我们的先验知识与我们的测量观察相结合,可以更好地估计位置。

因此,在查看了各种示例(特别是 http://www.youtube.com/watch?v=GBYW1j9lC1I)之后,我为我的场景建模了一个卡尔曼滤波器(而不是 4 个,矩形区域的每个点一个):

m_KF1.init(4, 2, 1); 
setIdentity(m_KF2.transitionMatrix);
m_measurement1 = Mat::zeros(2,1,cv::DataType<float>::type);
m_KF1.statePre.setTo(0);
m_KF1.controlMatrix.setTo(0);

//initialzing filter 
m_KF1.statePre.at<float>(0) = m_scene_corners[1].x; //the first reading
m_KF1.statePre.at<float>(1) = m_scene_corners[1].y;
m_KF1.statePre.at<float>(2) = 0;
m_KF1.statePre.at<float>(3) = 0;

setIdentity(m_KF1.measurementMatrix);
setIdentity(m_KF1.processNoiseCov,Scalar::all(.1)) //updated at every step
setIdentity(m_KF1.measurementNoiseCov, Scalar::all(4)); //assuming measurement error of      
                                                        //not more than 2 pixels
setIdentity(m_KF1.errorCovPost, Scalar::all(.1)); 

4 个状态变量(x,y 中的位置和 x,y 中的速度)。

2 个测量变量(x,y 中的位置)

1 个控制变量(加速度)

在每次迭代中采取的以下步骤

//---First,the predicion phase , to update the internal variables-------//

// 'dt' is the time taken between the measurements

//Updating the transitionMatrix
m_KF1.transitionMatrix.at<float>(0,2) = dt;
m_KF1.transitionMatrix.at<float>(1,3) = dt;

//Updating the Control matrix
m_KF1.controlMatrix.at<float>(0,1) = (dt*dt)/2;
m_KF1.controlMatrix.at<float>(1,1) = (dt*dt)/2;
m_KF1.controlMatrix.at<float>(2,1) = dt;
m_KF1.controlMatrix.at<float>(3,1) = dt;

//Updating the processNoiseCovmatrix
m_KF1.processNoiseCov.at<float>(0,0) = (dt*dt*dt*dt)/4;
m_KF1.processNoiseCov.at<float>(0,2) = (dt*dt*dt)/2;
m_KF1.processNoiseCov.at<float>(1,1) = (dt*dt*dt*dt)/4;
m_KF1.processNoiseCov.at<float>(1,3) = (dt*dt*dt)/2;

m_KF1.processNoiseCov.at<float>(2,0) = (dt*dt*dt)/2;
m_KF1.processNoiseCov.at<float>(2,2) = dt*dt;

m_KF1.processNoiseCov.at<float>(3,1) = (dt*dt*dt)/2;
m_KF1.processNoiseCov.at<float>(3,3) = dt*dt;

Mat prediction1 = m_KF1.predict();
Point2f predictPt1(prediction1.at<float>(0),prediction1.at<float>(1));

// Get the measured corner
m_measurement1.at<float>(0,0) = scene_corners[0].x;
m_measurement1.at<float>(0,1) = scene_corners[0].y;

//----Then, the correction phase which uses the predicted value and our measured value

Mat estimated = m_KF1.correct(m_measurement1);
Point2f statePt1(estimated.at<float>(0),estimated.at<float>(1));

这个模型几乎不能修正我的测量值

现在我的问题是:

  1. 卡尔曼滤波器适合我的场景吗?它会给我带来更好的结果吗?
  2. 如果是,那么缺少什么?我建模对吗?而是为矩形的四个点创建 4 个过滤器,我应该以其他方式对其进行建模(例如,根据距离获取 10 个最强匹配并将其用作过滤器的输入)
  3. 如果不适合卡尔曼滤波器,我还能做些什么来为估计的单应性提供更高的稳定性?

任何帮助将不胜感激。 谢谢。

【问题讨论】:

  • 提示:您不是在跟踪球体特征,而是在每帧检测它们。我最好将过滤器应用于findHomography 方法的输出 以过滤实际的相机位置。由于存在一些非线性,因此建模会更棘手,但可行。你可以开始here

标签: opencv augmented-reality feature-detection homography kalman-filter


【解决方案1】:

这个问题的标题很糟糕,在阅读了您的解释后,您真正要问的是:“为什么我的 OpenCV 卡尔曼滤波器仍然会留下很多噪音?

不管怎样,你的答案是:

  1. 是的,卡尔曼适用于您的场景
  2. 你用错了
  3. 修改:KF.processNoiseCov,您可以从这里获取代码:Opencv kalman filter prediction without new observtion 有很好的解释。

见:

 setIdentity(KF.processNoiseCov, Scalar::all(.005)); //adjust this for faster convergence - but higher noise

就我所见,您对它有非常基本的了解,您可以采用一种简单的方法并使用四个 2D 卡尔曼滤波器,为此您可以使用此处的代码:.它会起作用,从那里成长和适应,直到你得到更好的理解。

之后,您可以更贴近您的问题对其进行建模,或者您可以继续使用四个过滤器,没有“完美”的实现,所以如果它适合您,那就去做吧。

【讨论】:

    猜你喜欢
    • 2012-01-17
    • 2023-03-23
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    相关资源
    最近更新 更多