Tôi đã nghiên cứu hoạt động của bộ lọc Kalman trong vài ngày để cải thiện hiệu suất của chương trình phát hiện khuôn mặt của tôi. Từ những thông tin tôi thu thập được, tôi đã đặt cùng một mã. Mã cho phần bộ lọc Kalman như sau.Bộ lọc Kalman với bốn thông số đầu vào
int Kalman(int X,int faceWidth,int Y,int faceHeight, IplImage *img1){
CvRandState rng;
const float T = 0.1;
// Initialize Kalman filter object, window, number generator, etc
cvRandInit(&rng, 0, 1, -1, CV_RAND_UNI);
//IplImage* img = cvCreateImage(cvSize(500,500), 8, 3);
CvKalman* kalman = cvCreateKalman(4, 4, 0 );
// Initializing with random guesses
// state x_k
CvMat* state = cvCreateMat(4, 1, CV_32FC1);
cvRandSetRange(&rng, 0, 0.1, 0);
rng.disttype = CV_RAND_NORMAL;
cvRand(&rng, state);
// Process noise w_k
CvMat* process_noise = cvCreateMat(4, 1, CV_32FC1);
// Measurement z_k
CvMat* measurement = cvCreateMat(4, 1, CV_32FC1);
cvZero(measurement);
/* create matrix data */
const float A[] = {
1, 0, T, 0,
0, 1, 0, T,
0, 0, 1, 0,
0, 0, 0, 1
};
const float H[] = {
1, 0, 0, 0,
0, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 0
};
//Didn't use this matrix in the end as it gave an error:'ambiguous call to overloaded function'
/* const float P[] = {
pow(320,2), pow(320,2)/T, 0, 0,
pow(320,2)/T, pow(320,2)/pow(T,2), 0, 0,
0, 0, pow(240,2), pow(240,2)/T,
0, 0, pow(240,2)/T, pow(240,2)/pow(T,2)
}; */
const float Q[] = {
pow(T,3)/3, pow(T,2)/2, 0, 0,
pow(T,2)/2, T, 0, 0,
0, 0, pow(T,3)/3, pow(T,2)/2,
0, 0, pow(T,2)/2, T
};
const float R[] = {
1, 0, 0, 0,
0, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 0
};
//Copy created matrices into kalman structure
memcpy(kalman->transition_matrix->data.fl, A, sizeof(A));
memcpy(kalman->measurement_matrix->data.fl, H, sizeof(H));
memcpy(kalman->process_noise_cov->data.fl, Q, sizeof(Q));
//memcpy(kalman->error_cov_post->data.fl, P, sizeof(P));
memcpy(kalman->measurement_noise_cov->data.fl, R, sizeof(R));
//Initialize other Kalman Filter parameters
//cvSetIdentity(kalman->measurement_matrix, cvRealScalar(1));
//cvSetIdentity(kalman->process_noise_cov, cvRealScalar(1e-5));
/*cvSetIdentity(kalman->measurement_noise_cov, cvRealScalar(1e-1));*/
cvSetIdentity(kalman->error_cov_post, cvRealScalar(1e-5));
/* choose initial state */
kalman->state_post->data.fl[0]=X;
kalman->state_post->data.fl[1]=faceWidth;
kalman->state_post->data.fl[2]=Y;
kalman->state_post->data.fl[3]=faceHeight;
//cvRand(&rng, kalman->state_post);
/* predict position of point */
const CvMat* prediction=cvKalmanPredict(kalman,0);
//generate measurement (z_k)
cvRandSetRange(&rng, 0, sqrt(kalman->measurement_noise_cov->data.fl[0]), 0);
cvRand(&rng, measurement);
cvMatMulAdd(kalman->measurement_matrix, state, measurement, measurement);
//Draw rectangles in detected face location
cvRectangle(img1,
cvPoint(kalman->state_post->data.fl[0], kalman->state_post->data.fl[2]),
cvPoint(kalman->state_post->data.fl[1], kalman->state_post->data.fl[3]),
CV_RGB(0, 255, 0), 1, 8, 0);
cvRectangle(img1,
cvPoint(prediction->data.fl[0], prediction->data.fl[2]),
cvPoint(prediction->data.fl[1], prediction->data.fl[3]),
CV_RGB(0, 0, 255), 1, 8, 0);
cvShowImage("Kalman",img1);
//adjust kalman filter state
cvKalmanCorrect(kalman,measurement);
cvMatMulAdd(kalman->transition_matrix, state, process_noise, state);
return 0;
}
Trong phần phát hiện khuôn mặt (không được hiển thị), một hộp được vẽ cho khuôn mặt được phát hiện. 'X, Y, faceWidth và faceHeight' là tọa độ của hộp và chiều rộng và chiều cao được chuyển vào bộ lọc Kalman. 'img1' là khung hình hiện tại của video.
Kết quả:
Mặc dù tôi làm được hai hình chữ nhật mới từ 'dự đoán' dữ liệu (như đã thấy trong code) 'state_post' và, không ai trong số họ dường như là bất kỳ ổn định hơn hộp ban đầu rút ra mà không bộ lọc Kalman.
Here are tôi questions:
- Are the matrices initialized (transition matrix A, measurement matrix H etc.), correct for this 4 input case? (ví dụ: 4 * 4 ma trận cho bốn đầu vào?)
- Chúng ta không thể đặt mọi ma trận thành ma trận nhận dạng?
- Phương pháp tôi đã theo dõi cho đến khi vẽ các hình chữ nhật về mặt lý thuyết có đúng không? Tôi đã làm theo các ví dụ trong this và cuốn sách 'Học OpenCV' không sử dụng đầu vào bên ngoài.
Bất kỳ trợ giúp nào về vấn đề này sẽ được đánh giá cao!
Cảm ơn bạn rất nhiều vì câu trả lời thông tin! Tôi đã không thay đổi bất cứ điều gì mặc dù bởi vì tôi quyết định rời khỏi bộ lọc Kalman cho giai đoạn này. Nhưng tôi chắc chắn ai đó sẽ tìm thấy câu trả lời của bạn hữu ích! Cảm ơn một lần nữa. – Kavo