2013-12-22 117 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

你必须检测该对象被遮挡,那么不使用测量步骤,只是预测步骤。

这意味着如果发生遮挡,您的测量是完全错误的,所以测量步骤不会为您提供关于对象位置的任何新信息。你可以表示这是给你的观察一个非常大的协方差矩阵,或者(这基本上是相同的),你可以忽略观察。无论哪种方式,因为时间不会停止,你应该不断更新你的状态预测。因为没有新的信息被添加,所以状态的协方差应该变大。