-- coding: utf-8 --
import cv2.cv as cv
import cv2
import numpy as np
MAX_FEATURES = 500 #
RADIUS2 = 25
DETECT_TURM = 20 #何フレームごとにするかの決定
WINDOW_NAME = u'物体追跡'.encode('cp932')
反復アルゴリズムの終了条件
criteria = (cv2.TERM_CRITERIA_MAX_ITER | cv2.TERM_CRITERIA_EPS , 20 , 0.03)
class App:
def __init__(self):
cv2.namedWindow(WINDOW_NAME)
cv2.setMouseCallback(WINDOW_NAME , self.on_mouse)
self.src = cv2.VideoCapture('crossing_accident.avi')
if not self.src.isOpened():
print u'出力不可'
import sys
sys.exit()
self.points_now = None
self.detect_count = DETECT_TURM #DETECT_TURMの数だけ数を数える
def auto_detect(self):
self.points_now = cv2.goodFeaturesToTrack(self.img_now , MAX_FEATURES , 0.01 , 10)
cv2.cornerSubPix(self.img_now , self.points_now , (10 , 10) , (-1 , -1) , criteria)
def remove_points(self):
index = 0
while index < len(self.points_now):
if self.status[index] == 0:
self.points_now = np.delete(self.points_now , index , 0)
self.status = np.delete(self.status , index , 0)
index -= 1
index += 1
def on_mouse(self , event , x , y , flags , param):
if event != cv2.EVENT_LBUTTONDOWN:
return
index = -1
mini = RADIUS2
count = 0
if self.points_now != None:
for point in self.points_now:
dx = x - point[0][0]
dy = y - point[0][1]
r2 = dx * dx + dy * dy
if r2 <= mini:
index = count
mini = r2
break
count += 1
if index >= 0:
self.points_now = np.delete(self.points_now , index , 0)
self.status = np.delete(self.status , index , 0)
else:
if self.points_now != None and len(self.points_now) >= MAX_FEATURES:
print u'これ以上特徴点の抽出は不可能'
return
if self.points_now == None:
self.points_now = np.array([[[x , y]]] , np.float32)
else:
self.points_now = np.append(self.points_now , [[[x , y]]] , axis = 0).astype(np.float32)
cv2.cornerSubPix(self.img_now , self.points_now , (10 , 10) , (-1 , -1) , criteria)
def chk_detect(self):
self.detect_count -= 1 #self.detect_countに代入されたDETECT_TURMの数から1ずつ引いていく
if self.detect_count == 0: #もし、self.detect_countが0になった場合
self.detect_count = DETECT_TURM #self.detect_countを最初のDETECT_TURMの値に戻す
self.auto_detect() #自動での特徴点の抽出を行う
def run(self):
while True:
self.chk_detect() #動画が再生されてるあいだ、DETECT_TURMで指定した数のフレームごとに自動での特徴点抽出を行う
retval , frame = self.src.read()
if frame is None:
break
self.img_now = cv2.cvtColor(frame , cv2.COLOR_BGR2GRAY)
if self.points_now != None and len(self.points_now) > 0:
points_pre = self.points_now
self.points_now , self.status , err = \
cv2.calcOpticalFlowPyrLK(self.img_pre , self.img_now , points_pre , winSize = (10 , 10) , maxLevel = 3 , criteria = criteria , flags = 0 , minEigThreshold = 0.01)
print 'aaaa'
print len(points_pre)
print len(self.points_now)
#self.remove_points()
#for point in self.points_now:
for i in range(len(points_pre)): #points_preの「0~配列の要素の数」をiに代入し、「0~配列の要素の数」の間、処理を繰り返す
diff_x = points_pre[i][0][0] - self.points_now[i][0][0] #前フレームの点と現フレームの点のx座標の差分を取る
diff_y = points_pre[i][0][1] - self.points_now[i][0][1] #前フレームの点と現フレームの点のy座標の差分を取る
point = self.points_now[i] #
diff = diff_x*diff_x + diff_y*diff_y #三平方の定理の要領で、前フレームの点と現フレームの点の間の距離を取る
if diff > 1 and diff < 2: #前フレームの点と現フレームの点の間の距離が1より大きく、2より小さければ
cv2.circle(frame , (point[0][0] , point[0][1]) , 4 , (0 , 0 , 255 - 255*-(1 - diff)) , -1 , 8 , 0) #点を描画する。点の色は、物体の移動速度によって変化するようにする。早いと赤、遅いと黒色の点となる。
#cv2.circle(frame , (point[0][0] , point[0][1]) , 4 , (0 , 0 , 255*random.random()) , -1 , 8 , 0)
self.remove_points()
cv2.imshow(WINDOW_NAME , frame)
self.img_pre = self.img_now.copy()
key = cv2.waitKey(33)
if key == 27:
break
elif key == 67 or key == 99:
self.points_now = None
elif key == 32:
self.auto_detect()
cv2.destroyAllWindows()
self.src.release()
if name == 'main':
App().run()
上記のプログラムをSpyderで実行すると、下記のようなエラーが出ます。
runfile('C:/Users/tatomi/Desktop/chase/chasing.py', wdir='C:/Users/tatomi/Desktop/chase')
出力不可
An exception has occurred, use %tb to see the full traceback.
SystemExit
どうもパスか何かがとっていないような気がするのですがどうすればいいでしょうか。