2012-05-02 28 views
6

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:

  1. 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?)
  2. Chúng ta không thể đặt mọi ma trận thành ma trận nhận dạng?
  3. 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!

Trả lời

4

H [] phải là nhận dạng nếu bạn đo trực tiếp từ hình ảnh. Nếu bạn có 4 phép đo và bạn thực hiện 0 một số giá trị trên đường chéo, bạn đang thực hiện các phép đo dự kiến ​​đó (x * H) 0, khi nó không đúng. Sau đó, sự đổi mới (z- x * H) trên bộ lọc kalman sẽ cao.

R [] cũng phải là đường chéo, mặc dù hiệp phương sai của lỗi đo lường có thể khác với lỗi. Nếu bạn có tọa độ chuẩn hóa (width = height = 1), R có thể là 0,01. Nếu bạn đang xử lý các tọa độ pixel, R = diagonal_ones có nghĩa là lỗi của một pixel và điều đó là ổn. Bạn có thể thử với 2,3,4, vv ...

Ma trận chuyển tiếp A [], được cho là sẽ truyền bá trạng thái trên mỗi khung, giống như ma trận chuyển tiếp cho trạng thái gồm x, y, v_x và v_y. Bạn không đề cập đến vận tốc trong mô hình của bạn, bạn chỉ nói về các phép đo. Hãy cẩn thận, đừng nhầm lẫn Nhà nước (mô tả vị trí của khuôn mặt) với các phép đo (được sử dụng để cập nhật trạng thái). Trạng thái của bạn có thể là vị trí, vận tốc và gia tốc, và số đo của bạn có thể là n điểm trong hình ảnh. Hoặc vị trí x và y của khuôn mặt.

Hy vọng điều này sẽ hữu ích.

+1

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

Các vấn đề liên quan