Python 视频中的卡尔曼滤波

Python 视频中的卡尔曼滤波,python,python-2.7,opencv,kalman-filter,pykalman,Python,Python 2.7,Opencv,Kalman Filter,Pykalman,如何使用卡尔曼滤波器实时跟踪视频中人的运动?我对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_FR

如何使用卡尔曼滤波器实时跟踪视频中人的运动?我对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()
我使用的视频链接:

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

Python版本:2.7


OpenCV版本:2.4.13

下面的代码显示了如何使用
filter\u update
方法一次从视频中获取单个帧,并更新状态估计值的示例

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

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

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

图(视频末尾):

代码:

导入cv2
将numpy作为np导入
将matplotlib.pyplot作为plt导入
从pykalman输入Kalman滤波器
#主要设置:
file=“singleball.mov”
过滤器与机组的比率=0.5
capture=cv2.VideoCapture(文件)
numframes=int(capture.get(7))
numframes\u train=int(过滤器\u train\u比率*numframes)
打印“\t总帧数:”,numframes
打印“\t编号帧序列:”,numframes\u序列
#背景过滤器设置:
历史=10
nGauss=3
bg阈值=0.6
噪音=20
bgs=cv2.BackgroundSubtractorMOG(历史、nGauss、bgThresh、噪声)
f=plt.图()
plt.ion()
plt.轴([0480360,0])
测量轨迹=np.0((numframes\u列,2))-1
measurementMissingIdx=[False]*numframes\u train
#获取测量轨迹以训练卡尔曼滤波器:
计数=0
勒让德=假
计数为0时:
m=np.平均值(等高线[0],轴=0)
被测轨道[count-1,:]=m[0]
如果不是LegendPloted:
plt.绘图(m[0,0],m[0,1],'ob',label='measurement')
plt.图例(loc=2)
勒让德=真
其他:
plt.图(m[0,0],m[0,1],'ob')
plt.暂停(0.05)
其他:
measurementMissingIdx[count-1]=真
cv2.imshow(“前台”,领班)
cv2.等待键(80)
#训练卡尔曼滤波器:
测量值=毫安纳秒阵列(测量轨道)
测量值[measurementMissingIdx]=np.ma.屏蔽
#卡尔曼滤波器设置:
转移矩阵=[[1,0,1,0],[0,1,0,1],[0,0,1,0],[0,0,0,1]]
观测矩阵=[[1,0,0,0],[0,1,0,0]]
kf=Kalman滤波器(转换矩阵=转换矩阵,
观测矩阵=观测矩阵)
(平滑状态表示,平滑状态协方差)=kf.平滑(测量)
plt.plot(平滑状态表示[:,0],平滑状态表示[:,1],'xr',label='kalman output')
图例=plt.图例(loc=2)
plt.标题(“恒速卡尔曼滤波器”)
#每次应用(预训练)过滤器一次,
#具有实时绘图功能。
x_now=平滑的_状态_表示[-1,:]
P_now=平滑的状态协方差[-1,:]
勒让德=假
计数为0时:
m=np.平均值(等高线[0],轴=0)
newMeasurement=np.ma.asarray(m[0])
其他:
newMeasurement=np.ma.masked
cv2.imshow(“前台”,领班)
cv2.等待键(80)
(x_now,P_now)=kf.filter_update(filter_state_mean=x_now,
过滤状态协方差=P\u现在,
观察=新测量)
如果不是LegendPloted:
plt.plot(x_now[0],x_now[1],'xg',label='kalman update')
勒让德=真
plt.图例(loc=2)
其他:
plt.plot(x_now[0],x_now[1],'xg')
plt.暂停(0.05)
f、 savefig(“so_42941634.pdf”,bbox_inches='tight')

查看学生Dave的视频,matlab中的代码有很好的解释:@sks您需要查看
过滤器更新
方法,请参阅。这允许您提供一个新的度量,并返回更新的状态估计。
import numpy as np
from pykalman import KalmanFilter
from matplotlib import pyplot as plt
Measured=np.load("ballTrajectory.npy")
while True:
   if Measured[0,0]==-1.:
       Measured=np.delete(Measured,0,0)
   else:
       break
numMeas=Measured.shape[0]
MarkedMeasure=np.ma.masked_less(Measured,0)
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]]
xinit=MarkedMeasure[0,0]
yinit=MarkedMeasure[0,1]
vxinit=MarkedMeasure[1,0]-MarkedMeasure[0,0]
vyinit=MarkedMeasure[1,1]-MarkedMeasure[0,1]
initstate=[xinit,yinit,vxinit,vyinit]
initcovariance=1.0e-3*np.eye(4)
transistionCov=1.0e-4*np.eye(4)
observationCov=1.0e-1*np.eye(2)
kf=KalmanFilter(transition_matrices=Transition_Matrix,
            observation_matrices =Observation_Matrix,
            initial_state_mean=initstate,
            initial_state_covariance=initcovariance,
            transition_covariance=transistionCov,
            observation_covariance=observationCov)
(filtered_state_means, filtered_state_covariances) = kf.filter(MarkedMeasure)
plt.plot(MarkedMeasure[:,0],MarkedMeasure[:,1],'xr',label='measured')
plt.axis([0,520,360,0])
plt.hold(True)
plt.plot(filtered_state_means[:,0],filtered_state_means[:,1],'ob',label='kalman output')
plt.legend(loc=2)
plt.title("Constant Velocity Kalman Filter")
plt.show()
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')