vid中的卡尔曼滤波

2024-10-03 15:29:42 发布

您现在位置:Python中文网/ 问答频道 /正文

如何使用Kalman滤波器实时跟踪视频中一个人的运动?我对kalman还不熟悉,我正在尝试它。我已经能够运行kalman并在视频中预测球的路径。在

下面是背景减法的代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt
file="singleball.mov"
capture = cv2.VideoCapture(file)
print "\t Width: ",capture.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)
print "\t Height: ",capture.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)
print "\t FourCC: ",capture.get(cv2.cv.CV_CAP_PROP_FOURCC)
print "\t Framerate: ",capture.get(cv2.cv.CV_CAP_PROP_FPS)
numframes=capture.get(7)
print "\t Number of Frames: ",numframes
count=0
history = 10
nGauss = 3
bgThresh = 0.6
noise = 20
bgs = cv2.BackgroundSubtractorMOG(history,nGauss,bgThresh,noise)
plt.figure()
plt.hold(True)
plt.axis([0,480,360,0])
measuredTrack=np.zeros((numframes,2))-1
while count<numframes:
    count+=1
    img2 = capture.read()[1]
    cv2.imshow("Video",img2)
    foremat=bgs.apply(img2)
    cv2.waitKey(100)
    foremat=bgs.apply(img2)
    ret,thresh = cv2.threshold(foremat,127,255,0)
    contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    if len(contours) > 0:
        m= np.mean(contours[0],axis=0)
        measuredTrack[count-1,:]=m[0]
        plt.plot(m[0,0],m[0,1],'ob')
    cv2.imshow('Foreground',foremat)
    cv2.waitKey(80)
capture.release()
print measuredTrack
np.save("ballTrajectory", measuredTrack)
plt.show()

以下是等速卡尔曼滤波的代码:

^{pr2}$

我使用的视频链接:https://www.hdm-stuttgart.de/~maucher/Python/ComputerVision/html/files/singleball.mov

现在,问题是,我把轨迹存储在一个文件中,然后用这个文件作为kalman的输入。我如何扩展它使它成为实时的?另外,我如何跟踪一个团队中的一个人,其中可能有多人在场并在移动?在

Python版本:2.7

OpenCV版本:2.4.13


Tags: getcountnppltcv2cvcapturecap
1条回答
网友
1楼 · 发布于 2024-10-03 15:29:42

下面的代码演示了如何使用filter_update方法一次从视频中获取一个帧,并更新状态估计值。在

它或多或少基于您共享的代码,只是我使用了kf.smooth方法根据前半帧估计kalman滤波器的属性,然后使用滤波器更新后续帧的状态(位置)估计。pykalmansmooth方法将对一批测量进行操作,并尝试估计协方差等

我还修改了绘图,以便您可以在视频播放时看到更新的状态估计。在

你会看到,匀速卡尔曼滤波器可以合理地估计球在盒子下面的位置(以及它何时会再次出现)。在

图(视频末尾): enter image description here

代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt
from pykalman import KalmanFilter

# Main settings:
file="singleball.mov"
filter_train_ratio = 0.5

capture = cv2.VideoCapture(file)
numframes=int(capture.get(7))
numframes_train = int(filter_train_ratio*numframes)

print "\t Total No. Frames: ", numframes
print "\t No. Frames Train: ", numframes_train

# Background filter settings:
history = 10
nGauss = 3
bgThresh = 0.6
noise = 20

bgs = cv2.BackgroundSubtractorMOG(history,nGauss,bgThresh,noise)
f = plt.figure()
plt.ion()
plt.axis([0,480,360,0])
measuredTrack = np.zeros((numframes_train,2))-1
measurementMissingIdx = [False]*numframes_train

# Get measured trace to train a Kalman Filter:
count=0
legendPlotted = False

while count<numframes_train:
    count+=1
    img2 = capture.read()[1]
    cv2.imshow("Video",img2)
    foremat=bgs.apply(img2)
    cv2.waitKey(100)
    foremat=bgs.apply(img2)
    ret,thresh = cv2.threshold(foremat,127,255,0)
    contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    if len(contours) > 0:
        m= np.mean(contours[0],axis=0)
        measuredTrack[count-1,:]=m[0]
        if not legendPlotted:
            plt.plot(m[0,0],m[0,1],'ob', label='measurement')
            plt.legend(loc=2)
            legendPlotted = True
        else:
            plt.plot(m[0,0],m[0,1],'ob')
        plt.pause(0.05)
    else:
        measurementMissingIdx[count-1] = True
    cv2.imshow('Foreground',foremat)
    cv2.waitKey(80)

# Train the Kalman filter:
measurements = np.ma.asarray(measuredTrack)
measurements[measurementMissingIdx] = np.ma.masked

# Kalman filter settings:
Transition_Matrix=[[1,0,1,0],[0,1,0,1],[0,0,1,0],[0,0,0,1]]
Observation_Matrix=[[1,0,0,0],[0,1,0,0]]

kf=KalmanFilter(transition_matrices=Transition_Matrix,
            observation_matrices =Observation_Matrix)

(smoothed_state_means, smoothed_state_covariances) = kf.smooth(measurements)

plt.plot(smoothed_state_means[:,0],smoothed_state_means[:,1],'xr',label='kalman output')
legend = plt.legend(loc=2)
plt.title("Constant Velocity Kalman Filter")

# Apply (pre-trained) filter one interval at a time,
# with plotting in real time.

x_now = smoothed_state_means[-1, :]
P_now = smoothed_state_covariances[-1, :]
legendPlotted = False

while count<numframes:
    newMeasurement = np.ma.asarray(-1)
    count+=1
    img2 = capture.read()[1]
    cv2.imshow("Video",img2)
    foremat=bgs.apply(img2)
    cv2.waitKey(100)
    foremat=bgs.apply(img2)
    ret,thresh = cv2.threshold(foremat,127,255,0)
    contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    if len(contours) > 0:
        m= np.mean(contours[0],axis=0)
        newMeasurement = np.ma.asarray(m[0])

    else:
        newMeasurement = np.ma.masked

    cv2.imshow('Foreground',foremat)
    cv2.waitKey(80)

    (x_now, P_now) = kf.filter_update(filtered_state_mean = x_now,
                                      filtered_state_covariance = P_now,
                                      observation = newMeasurement)    
    if not legendPlotted:
        plt.plot(x_now[0],x_now[1],'xg', label='kalman update')
        legendPlotted = True
        plt.legend(loc=2)

    else:
        plt.plot(x_now[0],x_now[1],'xg')

    plt.pause(0.05)

f.savefig("so_42941634.pdf", bbox_inches='tight')

相关问题 更多 >