2012-05-02 35 views
6

मैं अपने चेहरे का पता लगाने कार्यक्रम के प्रदर्शन में सुधार के लिए अब कुछ दिनों के लिए कलमान फ़िल्टर के संचालन का अध्ययन कर रहा हूं। मैंने एकत्र की गई जानकारी से मैंने एक कोड रखा है। कलमान फ़िल्टर भाग के लिए कोड निम्नानुसार है।चार इनपुट पैरामीटर के साथ काल्मन फ़िल्टर

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; 
} 

चेहरे का पता लगाने भाग (दिखाया नहीं गया) में, चेहरे का पता लगाने के लिए एक बॉक्स खींचा जाता है। 'एक्स, वाई, फेसविड्थ और फेसहेइट' बॉक्स के निर्देशांक हैं और चौड़ाई और ऊंचाई कलमैन फ़िल्टर में गुजरती है। 'img1' एक वीडियो का वर्तमान फ्रेम है।

परिणाम:

हालांकि मैं 'state_post' और 'भविष्यवाणी' डेटा (कोड में देखा जाता है) से दो नए आयतों मिलता है, उनमें से कोई भी बिना तैयार प्रारंभिक बॉक्स के अलावा कोई और अधिक स्थिर होने लगते हैं कलमैन फ़िल्टर। इस चार इनपुट मामले के लिए सही

  1. मैट्रिक्स प्रारंभ (संक्रमण मैट्रिक्स A, माप मैट्रिक्स एच आदि) कर रहे हैं,:

    यहाँ मेरी सवाल कर रहे हैं? (उदाहरण के लिए चार इनपुट के लिए 4 * 4 matrices?)

  2. क्या हम प्रत्येक मैट्रिक्स को पहचान मैट्रिक्स के रूप में सेट नहीं कर सकते?
  3. क्या पद्धति मैंने सैद्धांतिक रूप से सही आयत की साजिश तक पालन की है? मैंने उदाहरणों का पालन किया this और पुस्तक 'लर्निंग ओपनसीवी' जो बाहरी इनपुट का उपयोग नहीं करती है।

इसके बारे में कोई भी मदद की सराहना की जाएगी!

उत्तर

4

एच [] यदि आप सीधे छवि से मापते हैं तो पहचान होना चाहिए। यदि आपके पास 4 माप हैं और आप 0 विकर्ण पर कुछ मान बनाते हैं, तो आप उन अपेक्षित माप (x * एच) 0 बना रहे हैं, जब यह सत्य नहीं है। फिर कलमैन फ़िल्टर पर नवाचार (जेड-एक्स * एच) उच्च होगा।

आर [] भी विकर्ण होना चाहिए, हालांकि माप की त्रुटि का कॉन्वर्सिस एक से अलग हो सकता है। यदि आपके पास सामान्यीकृत निर्देशांक हैं (चौड़ाई = ऊंचाई = 1), आर 0.01 की तरह कुछ हो सकता है। यदि आप पिक्सेल निर्देशांक से निपट रहे हैं, तो आर = डायगोनल_ऑन का अर्थ है एक पिक्सेल की त्रुटि, और यह ठीक है। आप 2,3,4, आदि के साथ प्रयास कर सकते हैं ...

आपका संक्रमण मैट्रिक्स ए [], जो कि प्रत्येक फ्रेम पर राज्य को प्रचारित करने वाला है, एक्स, वाई से बना एक राज्य के लिए एक संक्रमण मैट्रिक्स की तरह दिखता है, v_x और v_y। आप अपने मॉडल में वेग का उल्लेख नहीं करते हैं, आप केवल माप के बारे में बात करते हैं। सावधान रहें, माप (चेहरे की स्थिति का वर्णन) को भ्रमित न करें (राज्य को अद्यतन करने के लिए उपयोग किया जाता है)। आपका राज्य स्थिति, वेग और त्वरण हो सकता है, और आपके माप छवि में एन अंक हो सकते हैं। या चेहरे की एक्स और वाई स्थिति।

उम्मीद है कि इससे मदद मिलती है।

+1

जानकारीपूर्ण उत्तर के लिए बहुत बहुत धन्यवाद! मुझे कुछ भी बदलने की ज़रूरत नहीं थी क्योंकि मैंने इस चरण के लिए कलमान फ़िल्टर छोड़ने का फैसला किया था। लेकिन मुझे यकीन है कि कोई आपके उत्तर को उपयोगी पाएगा! एक बार फिर धन्यवाद। – Kavo