嘿那裏:)我目前開始在OpenCv中使用卡爾曼濾波器。 我遇到了2個問題。卡爾曼OpenCV估計沒有測量
第一個是,我用http://www.morethantechnical.com/2011/06/17/simple-kalman-filter-for-tracking-using-opencv-2-2-w-code/的例子。 在視頻中,似乎Kalman濾波器會降低噪聲,但如果我運行我的代碼,噪聲不會降低,所以如果我移動鼠標,則預測的行爲幾乎完全像鼠標移動,而不會降低噪聲。是由於我的高採樣率還是measurementMatrix,processNoiseCov,measurementNoiseCov和errorCovPost設置錯誤的值?我希望你能理解我的意思。
我的其他問題是,如果我按「n」我想禁用新的測量,我想Kalmanfilter仍然猜測鼠標的新位置。在http://code.opencv.org/issues/1380 Mircea Popa說:
「但在kalman.correct()調用之前將測量矩陣設置爲0(這是程序員的職責),因此修正係數(增益)爲0,並且過濾器的狀態會根據預測的結果進行更新。「所以我試圖這樣做:測量= Mat ::零(2,1,CV_32F),但只是預測的位置已經在位置(0,0),所以不是我所期望的。有什麼我明白錯誤?不是測量Mircea Popa談到的「測量矩陣」嗎?還是有另一種方法讓KalmanFilter無需測量就能預測新的位置?
爲了表明我期望卡爾曼濾波器做什麼:如果沒有測量,估計位置的運動應該是均勻的,運動方向應該在由最後兩個位置確定的直線上。
這裏是我的代碼:
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/video/tracking.hpp"
using namespace cv;
using namespace std;
int m_X = 0;
int m_Y = 0;
bool cursorSet = false;
bool noDetection = false;
Mat_<float> lastPosition(2,1);
void drawCross(Mat &img, Point ¢er, Scalar color, int d) {
line(img, Point(center.x - d, center.y - d), Point(center.x + d, center.y + d), color, 2, CV_AA, 0);
line(img, Point(center.x + d, center.y - d), Point(center.x - d, center.y + d), color, 2, CV_AA, 0);
};
void CallBackFunc(int event, int x, int y, int flags, void* userdata) {
m_X = x;
m_Y = y;
cursorSet = true;
cout << "Mouse move over the window - position (" << x << ", " << y << ")" << endl;
};
void GetCursorPos(Point &mousepos){
mousepos = Point(m_X, m_Y);
};
int main() {
//create window and set callback for mouse movement
namedWindow("window", 1);
setMouseCallback("window", CallBackFunc, NULL);
// Image to show mouse tracking
Mat img(600, 800, CV_8UC3);
vector<Point> mousev,kalmanv;
mousev.clear();
kalmanv.clear();
//wait until mouse has an initial position inside the window
while(!cursorSet) {
imshow("window", img);
waitKey(10);
};
//create kalman Filter
KalmanFilter KF(6, 2, 0);
//position of the mouse will be observed
Point mousePos;
GetCursorPos(mousePos);
// intialization of KF...
KF.transitionMatrix = *(Mat_<float>(6, 6) << 1,0,1,0,.5,0, // x + v_x + 1/2 a_x
0,1,0,1,0,0.5, // y + v_Y + 1/2 a_y
0,0,1,0,1,0, // v_x + a_x
0,0,0,1,0,1, // v_y + a_y
0,0,0,0,1,0, // a_x
0,0,0,0,0,1); // a_y
Mat_<float> measurement(2,1); measurement.setTo(Scalar(0));
//initialize the pre state
KF.statePost.at<float>(0) = mousePos.x;
KF.statePost.at<float>(1) = mousePos.y;
KF.statePost.at<float>(2) = 0;
KF.statePost.at<float>(3) = 0;
KF.statePost.at<float>(4) = 0;
KF.statePost.at<float>(5) = 0;
setIdentity(KF.measurementMatrix);
setIdentity(KF.processNoiseCov, Scalar::all(1e-1));
setIdentity(KF.measurementNoiseCov, Scalar::all(1e-5));
setIdentity(KF.errorCovPost, Scalar::all(1e-3));
while(1) {
img = Scalar::all(0);
// First predict, to update the internal statePre variable
Mat prediction = KF.predict();
Point predictPt(prediction.at<float>(0),prediction.at<float>(1));
// Get mouse point
if (!noDetection) {
GetCursorPos(mousePos);
measurement(0) = mousePos.x;
measurement(1) = mousePos.y;
}else {
measurement(0) = prediction.at<float>(0);
measurement(1) = prediction.at<float>(1);
}
// The update phase3
Mat estimated = KF.correct(measurement);
Point statePt(estimated.at<float>(0),estimated.at<float>(1));
Point measPt(measurement(0),measurement(1));
// draw cross for actual mouse position and kalman guess
mousev.push_back(measPt);
kalmanv.push_back(statePt);
drawCross(img, statePt, Scalar(255,255,255), 5);
drawCross(img, measPt, Scalar(0,0,255), 5);
// draw lines of movement
for (int i = 0; i < mousev.size()-1; i++)
line(img, mousev[i], mousev[i+1], Scalar(0,0,255), 1);
for (int i = 0; i < kalmanv.size()-1; i++)
line(img, kalmanv[i], kalmanv[i+1], Scalar(255,255,255), 1);
imshow("window", img);
char key = waitKey(10);
if (key == 'c') {
mousev.clear();
kalmanv.clear(); // press c to clear screen
}if (key == 'n') {
noDetection = true; //press n to simulate that no measurement is made
}if (key == 'd') {
noDetection = false;//press d to allow measurements again
}else if(key == 'x') {
break; // press x to exit program
};
}
return 0;
}
謝謝你的快速答覆梅茨堡。我的理解是否正確:這些矩陣在初始化時設置了一次?或者我需要每次更換它們? – CelesterSpencer
在初始化中設置一次...是的。 – metsburg