我尝试过使用卡尔曼滤波器进行预测,效果很好。但是,在存在遮挡的情况下,代码根本无法正确预测。 这是我写的代码:
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()
答案 0 :(得分:0)
卡尔曼滤波器使用来自实际测量的信息不断更新预测值。在遮挡期间,您将不得不仅使用卡尔曼预测值并以某种方式排除测量信息。即。根据最后的速度估计来预测所有状态向量分量。
这是一个例子:
http://hal.archives-ouvertes.fr/docs/00/15/65/55/PDF/Girondel_SSIAI_2004.pdf
答案 1 :(得分:0)
您必须检测到对象被遮挡,然后不要使用测量步骤,只需使用预测步骤。
这意味着如果发生遮挡,则您的测量完全错误,因此测量步骤不会为您提供有关对象位置的任何新信息。您可以将此表示为给您的观察一个非常大的协方差矩阵,或者(这基本上是相同的)您可以忽略观察。无论哪种方式,因为时间不会停止,你应该不断更新你的州的预测。国家的协方差应该变大,因为没有添加新的信息。