2017-03-22 4 views
1

어떻게 Kalman 필터를 사용하여 동영상에서 사람의 움직임을 실시간으로 추적 할 수 있습니까? 나는 칼만을 처음 보았고 나는 그것을 실험하고 있었다. 나는 칼만을 실행하고 비디오에서 공의 경로를 예측할 수있었습니다. 내가 사용되는 비디오의Kalman 필터 동영상에서

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

링크 : https://www.hdm-stuttgart.de/~maucher/Python/ComputerVision/html/files/singleball.mov

이제 문제 여기

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

상수 속도 칼만 필터에 대한 코드입니다 : 여기

는 배경 빼기위한 코드입니다 여기에 내가 파일에 궤도를 저장하고 다음 칼만에 대한 입력으로 그 파일을 사용하고 있습니다. 어떻게 실시간으로 만들 수 있습니까? 또한 여러 사람이 출동하여 이동하는 그룹의 한 사람을 어떻게 추적합니까?

파이썬 버전 2.7

OpenCV의 버전 : 2.4.13는

+0

확인 학생 데이브의 비디오 : https://www.youtube.com/watch? v = FkCT_LV9Syk –

+0

@sks 당신은'filter_update' 메소드를 확인하고 싶습니다. [here] (https://pykalman.github.io/#pykalman.KalmanFilter.filter_update)를보십시오. 이를 통해 하나의 새 측정 값을 제공하고 업데이트 된 상태 추정치를 반환 할 수 있습니다. – kabdulla

답변

1

아래의 코드는 한 번에 영상에서 하나의 프레임을 취할 filter_update 방법을 사용하는 방법의 일례를 나타낸다 상태 추정을 갱신 할 수있다.

kf.smooth 메서드를 사용하여 프레임의 첫 번째 절반을 기반으로 칼만 필터의 속성을 추정 한 다음 상태 (위치) 추정을 업데이트한다는 점을 제외하고는 공유 한 코드를 기반으로합니다. 후속 프레임에 필터를 사용합니다. pykalmansmooth 방법은 일련의 측정에 대해 작동하고 공분산 등을 추정하려고합니다.

또한 비디오가 재생 될 때 업데이트 된 상태 견적을 볼 수 있도록 플로팅을 수정했습니다.

일정 속도의 칼만 필터가 공이 상자 아래 어디에 있는지 (다시 표시 될 때) 추정하는 작업이 적절하다는 것을 알 수 있습니다. (비디오의 끝)

그림 : enter image description here

코드 : MATLAB 코드와 잘 설명이있다

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