2013-12-22 51 views
0

我已經嘗試使用卡爾曼濾波器進行預測,並且它完美地工作。但是,在存在遮擋的情況下,代碼根本無法正確預測。 這裏是我寫的代碼:卡爾曼濾波器跟蹤存在的遮擋

import cv 


class Target: 

    def __init__(self): 
     self.capture = cv.CaptureFromFile('F:\\Project\\Video3\\av.avi') 
     cv.NamedWindow("Target", 1) 


    def run(self): 
     frame = cv.QueryFrame(self.capture) 
     frame_size = cv.GetSize(frame) 
     fps=cv.GetCaptureProperty(self.capture, cv.CV_CAP_PROP_FPS) 

     color_image = cv.CreateImage(cv.GetSize(frame), 8, 3) 
     grey_image = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 1) 
     moving_average = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_32F, 3) 

     # Create Kalman Filter 
     kalman = cv.CreateKalman(4, 2, 0) 
     kalman_state = cv.CreateMat(4, 1, cv.CV_32FC1) 
     kalman_process_noise = cv.CreateMat(4, 1, cv.CV_32FC1) 
     kalman_measurement = cv.CreateMat(2, 1, cv.CV_32FC1) 

     first = True 
     second=True 
     n=0 
     cp11 = [] 
     cp22 = [] 
     center_point1 = [] 
     predict_pt1 = [] 
     count=0 

     while True: 
      closest_to_left = cv.GetSize(frame)[0] 
      closest_to_right = cv.GetSize(frame)[1] 

      color_image = cv.QueryFrame(self.capture) 

      cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 3, 0) 
      if first: 
       difference = cv.CloneImage(color_image) #fully copies the image. 
       temp = cv.CloneImage(color_image) 
       cv.ConvertScale(color_image, moving_average, 1.0, 0.0) 
       first = False 
      else:   
       cv.RunningAvg(color_image, moving_average, 0.02, None) 

      cv.ConvertScale(moving_average, temp, 1.0, 0.0) 

      # Minus the current frame from the moving average. 
      cv.AbsDiff(color_image, temp, difference) 

      # Convert the image to grayscale. 
      cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY) 

      # Convert the image to black and white. 
      cv.Threshold(grey_image, grey_image, 70, 255, cv.CV_THRESH_BINARY) 

      # Dilate and erode to get people blobs 
      cv.Dilate(grey_image, grey_image, None, 18) 
      cv.Erode(grey_image, grey_image, None, 10) 

      storage = cv.CreateMemStorage(0) 
      contour = cv.FindContours(grey_image, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) 

      points = [] 

      i=0 
      k=0 
      while contour: 
       area=cv.ContourArea(list(contour)) 
       #print area 
       bound_rect = cv.BoundingRect(list(contour)) 
       contour = contour.h_next() 
       if (area > 1500.0): 
        pt1 = (bound_rect[0], bound_rect[1]) 
        pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]) 
        points.append(pt1) 
        points.append(pt2) 
        cv.Rectangle(color_image, pt1, pt2, cv.CV_RGB(255,0,0), 1) 

        cp1 = bound_rect[0] + (bound_rect[2]/2) 
        cp2 = bound_rect[1] + (bound_rect[3]/2) 
        cp11.append(cp1) 
        cp22.append(cp2) 

        # set previous state for prediction 
        kalman.state_pre[0,0] = cp1 
        kalman.state_pre[1,0] = cp2 
        kalman.state_pre[2,0] = 0 
        kalman.state_pre[3,0] = 0 

        # set kalman transition matrix 
        kalman.transition_matrix[0,0] = 1 
        kalman.transition_matrix[0,1] = 0 
        kalman.transition_matrix[0,2] = 0 
        kalman.transition_matrix[0,3] = 0 
        kalman.transition_matrix[1,0] = 0 
        kalman.transition_matrix[1,1] = 1 
        kalman.transition_matrix[1,2] = 0 
        kalman.transition_matrix[1,3] = 0 
        kalman.transition_matrix[2,0] = 0 
        kalman.transition_matrix[2,1] = 0 
        kalman.transition_matrix[2,2] = 0 
        kalman.transition_matrix[2,3] = 1 
        kalman.transition_matrix[3,0] = 0 
        kalman.transition_matrix[3,1] = 0 
        kalman.transition_matrix[3,2] = 0 
        kalman.transition_matrix[3,3] = 1 

        # set Kalman Filter 
        cv.SetIdentity(kalman.measurement_matrix, cv.RealScalar(1)) 
        cv.SetIdentity(kalman.process_noise_cov, cv.RealScalar(1e-5)) 
        cv.SetIdentity(kalman.measurement_noise_cov, cv.RealScalar(1e-1)) 
        cv.SetIdentity(kalman.error_cov_post, cv.RealScalar(1)) 

        #Prediction 
        kalman_prediction = cv.KalmanPredict(kalman) 
        predict_pt = (int(kalman_prediction[0,0]),int(kalman_prediction[1,0])) 
        predict_pt1.append(predict_pt) 
        print "Prediction",predict_pt 
        #Correction 
        kalman_estimated = cv.KalmanCorrect(kalman, kalman_measurement) 
        state_pt = (kalman_estimated[0,0], kalman_estimated[1,0]) 

        #measurement 
        kalman_measurement[0, 0] = center_point[0] 
        kalman_measurement[1, 0] = center_point[1] 

      while(i<count): 
       cv.Circle(color_image, (cp11[i], cp22[i]), 1, cv.CV_RGB(255, 100, 0), 1) 


       cv.Circle(color_image, predict_pt1[i], 1, cv.CV_RGB(0, 255, 0), 1) 
       i=i+1 
      cv.ShowImage("Target", color_image) 

      c = cv.WaitKey(int(fps)) 
      if c == 27: 
       break 

if __name__=="__main__": 
    t = Target() 
    t.run() 
+1

爲什麼你使用舊的'cv'界面而不是更新的'cv2'?至於實際問題,如果你能以某種方式說明你的問題,這將有所幫助。 「不能在存在閉塞的情況下工作」是非常模糊的。 –

+0

我同意上面的評論。另外,上傳一些圖片可以幫助我們理解問題。 – GilLevi

+0

我看到一個跟蹤使用cv的例子,自從我開始學習cv以來,我一直在繼續使用它。我開始跟蹤一個正在房間裏走的男人。當他走到屏幕後面時,預測和跟蹤點不會出現。跟蹤點不應該出現,所以這沒關係。但從我讀過的關於卡爾曼濾波器的文章中可以看出,即使這個人在屏幕後面,它也應該繼續預測。但是上面的代碼並沒有這樣做。 – user3082806

回答

0

你必須檢測該對象被遮擋,那麼不使用測量步驟,只是預測步驟。

這意味着如果發生遮擋,您的測量是完全錯誤的,所以測量步驟不會爲您提供關於對象位置的任何新信息。你可以表示這是給你的觀察一個非常大的協方差矩陣,或者(這基本上是相同的),你可以忽略觀察。無論哪種方式,因爲時間不會停止,你應該不斷更新你的狀態預測。因爲沒有新的信息被添加,所以狀態的協方差應該變大。