2016年10月25日火曜日

【Python × OpenCV】 動画で歩行者検知

リクエストがあったので動画で歩行者検知してみました。

結果

中々良い感じ。

動画ファイル読み込み


動画の処理についてはいつも通りチュートリアルを参考にしました。プログラムの流れは

  1. cv2.VideoCaptureで動画を読み込んで
  2. frame毎に画像表示させる

という簡単な手順です。

ただ私の環境ではVideoCaptureが機能しなかったので、StackOverflowを見たところ、
OpenCVフォルダ内のffmpeg関連の名前変更してpythonフォルダにコピペする必要がありました。

VideoCaptureが動いたら、前回のコードと合わせて「動画で歩行者検知」完成です。

import numpy as np
import cv2
cap = cv2.VideoCapture('../seq.mp4')
#shrink the rectangle from default
def draw_detections(img, rects, thickness = 1):
for x, y, w, h in rects:
pad_w, pad_h = int(0.15 * w), int(0.05 * h)
cv2.rectangle(img, (x + pad_w, y + pad_h), (x + w - pad_w, y + h - pad_h), (0, 255, 0), thickness)
#default detector
def PD_default(filename):
image = filename#cv2.imread(filename) #read image
hog = cv2.HOGDescriptor() #derive HOG features
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) #setSVMDetector
#pedestrian detection
found, w = hog.detectMultiScale(image, hitThreshold = 0, winStride = (8,8), padding = (0, 0), scale = 1.05, finalThreshold = 5)
draw_detections(image, found) #draw rectangles
#write & save image
cv2.imshow('original', image) #write image
cv2.waitKey(1) #for keyboard binding
#cv2.imwrite('test.jpg',image) # save image
while(cap.isOpened()):
ret, frame = cap.read()
PD_default(frame)
cap.release()
cv2.destroyAllWindows()
#print cap.grab()

使った動画


問題点

とにかく重いです。
ただでさえ重い歩行者検知に加え、動画を読み込んでいるからだと思います。
なので一般的には、動画をフレーム毎に画像にしたデータ群を使って検証するみたいです。

結果は動画読み込みと同じですが、倍以上早いプログラムがこちらです。
import cv2 #use opencv
#shrink the rectangle from default
def draw_detections(img, rects, thickness = 1):
for x, y, w, h in rects:
pad_w, pad_h = int(0.15 * w), int(0.05 * h)
cv2.rectangle(img, (x + pad_w, y + pad_h), (x + w - pad_w, y + h - pad_h), (0, 255, 0), thickness)
#default detector
def PD_default(filename):
image = cv2.imread(filename) #read image
hog = cv2.HOGDescriptor() #derive HOG features
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) #setSVMDetector
#pedestrian detection
found, w = hog.detectMultiScale(image, hitThreshold = 0, winStride = (8,8), padding = (0, 0), scale = 1.05, finalThreshold = 5)
draw_detections(image, found) #adraw rectangles
#write & save image
cv2.imshow('original', image) #write image
cv2.waitKey(1) #for keyboard binding
#cv2.imwrite('test.jpg',image) # save image
for k in range(10):
for j in range(10):
for i in range(10):
PD_default("../seq/image_00000" + str(k) + str(j) + str(i) + "_0.png")

パラメータは前回良かった

  • hit_threshold = 0
  • group_threshold = 5

を使いました。

おわりに


想像以上にこのデフォルト検出器の性能が良かったので、改良意欲が湧いてきました。
とはいえ専門家でもないので、実装しながら色々考えてみるつもりです、おわり。

0 件のコメント:

コメントを投稿