gpt4 book ai didi

opencv - 无需测量的卡尔曼 OpenCV 估计

转载 作者:太空宇宙 更新时间:2023-11-03 20:58:47 24 4
gpt4 key购买 nike

你好 :) 我目前开始在 OpenCv 中使用卡尔曼滤波器。我遇到了 2 个问题。

第一个是,我使用了 http://www.morethantechnical.com/2011/06/17/simple-kalman-filter-for-tracking-using-opencv-2-2-w-code/ 中的示例.在视频中,卡尔曼滤波器似乎降低了噪音,但如果我运行我的代码,噪音并没有降低,所以如果我移动鼠标,预测的行为几乎与鼠标移动完全一样,但没有降低噪音。是因为我的高采样率还是 measurementMatrix、processNoiseCov、measurementNoiseCov 和 errorCovPost 的值设置不好?我希望你能明白我的意思。

我的另一个问题是,如果我按“n”我想禁用新的测量并且我希望 Kalmanfilter 仍然猜测鼠标的新位置。在 http://code.opencv.org/issues/1380 Mircea Popa 说:

”但在调用kalman.correct()之前将测量矩阵设置为0(这是程序员的职责)。这样做,校正因子(增益)变为0,滤波器的状态被更新根据预测。”

所以我尝试这样做:measurement = Mat::zeros(2,1, CV_32F) 但是预测的位置一直在位置 (0,0),所以不是我所期望的。有什么我理解错了吗? measurment不就是Mircea Popa口中的“测量矩阵”吗?还是有另一种方法让卡尔曼滤波器无需测量即可预测新位置?

明确我希望卡尔曼滤波器做什么:如果没有测量,估计位置的移动应该是均匀的,移动方向应该在由最后两个位置确定的直线上。

这是我的代码:

#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 &center, 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;
}

最佳答案

从更广义的 PoV 来说...如果您希望有一个卡尔曼滤波器来软化测量噪声,您必须更多地依赖过程模型而不是测量更新。因此,在您的情况下,调整“measurementMatrix、processNoiseCov、measurementNoiseCov”可能会使您获得更柔和的输出。

关于opencv - 无需测量的卡尔曼 OpenCV 估计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24630949/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com