存在遮挡时的卡尔曼滤波器跟踪

时间:2013-12-22 14:25:30

标签: python opencv image-processing tracking video-processing

我尝试过使用卡尔曼滤波器进行预测,效果很好。但是,在存在遮挡的情况下,代码根本无法正确预测。 这是我写的代码:

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()

2 个答案:

答案 0 :(得分:0)

卡尔曼滤波器使用来自实际测量的信息不断更新预测值。在遮挡期间,您将不得不仅使用卡尔曼预测值并以某种方式排除测量信息。即。根据最后的速度估计来预测所有状态向量分量。

这是一个例子:

http://hal.archives-ouvertes.fr/docs/00/15/65/55/PDF/Girondel_SSIAI_2004.pdf

答案 1 :(得分:0)

您必须检测到对象被遮挡,然后不要使用测量步骤,只需使用预测步骤。

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