我正在创建一个AR应用程序,用于跟踪特征,计算单应性,然后从3D-2D点对应中获取对象的姿势,并使用它来渲染任何3D对象。
我正在选择一个特定区域来检测源图像上的特征(通过屏蔽)。然后将其与后续帧中检测到的特征进行匹配。然后我过滤这些匹配并估计未屏蔽区域的Homography。
问题在于Homography估计。它每次都不同(非常轻微,但仍然不同)。效果是:即使保持我的相机静止,我在我的跟踪区域周围得到一个振动的矩形,我使用估计的单应性绘制。
我已经发布了一个题为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));
此模型几乎无法更正我的测量值
现在我的问题是:
任何帮助都将受到高度赞赏。 感谢。
答案 0 :(得分:1)
这个问题标题很糟糕,在阅读了你的解释后,你真正要问的是:“为什么我的OpenCV卡尔曼滤波器仍然会留下很多噪音?”
无论如何,你的答案是:
KF.processNoiseCov
,您可以从此处获取代码:Opencv kalman filter prediction without new observtion有很好的解释权。请参阅:
setIdentity(KF.processNoiseCov, Scalar::all(.005)); //adjust this for faster convergence - but higher noise
对于我所看到的,你对它有非常基本的了解,你可以采用一种天真的方法并使用四个2D卡尔曼滤波器,为此你可以在这里使用代码:。它会起作用,从那里成长和适应,直到你获得更好的理解。
之后,您可以更贴近您的问题对其进行建模,或者您可以继续使用四个过滤器,没有“完美”的实现,所以如果这对您有效,那就去吧。