OpenCVで簡易な人の検出実験 HOG特徴量&SVMで

2020年7月15日

今回は「人間」の簡単な動画での検出を実験してみます。OpenCVにすでに組み込まれてる範囲で試してみます。頑張れば自分で学習もできるようです。

環境はUbuntu18.04とOpenCV4.2で試してます。

今回はHOG(Histgrams of Oriented Gradient)です。一言でいうと画像の輝度の勾配から人間の特徴を捉えよう、ということみたいです。よくわかりませんね。すいません検索ください。

学習済みの関数がOpenCVでは2つ準備されてますね。今回はこれ使ってみます。違いは使っているデータ・セットが違うようですが、どのように使い分ければよいのかは私にはまだ良くわかりませんね。

・cv2.HOGDescriptor_getDefaultPeopleDetector()

・v2.HOGDescriptor_getDaimlerPeopleDetector()

パラメータがたくさんありますので、今回はOpenCVにあったC++でのサンプルのパラメータで試してみます。

https://docs.opencv.org/4.0.0/df/d54/samples_2cpp_2peopledetect_8cpp-example.html#a5

ソースコードはこんなですね。DefaultとDaimlerの切り替えはwhileループ前の3行のコメントアウトで切り替えで。

import numpy as np
import cv2

#動画読み込み
cap = cv2.VideoCapture('Airport.mp4')

# 動画書き込み変数設定
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
writer = cv2.VideoWriter('output.mp4', fourcc, fps, (width, height))

hog = cv2.HOGDescriptor((48,96), (16,16), (8,8), (8,8), 9)
hog.setSVMDetector(cv2.HOGDescriptor_getDaimlerPeopleDetector())
hogParams = {'hitThreshold' : 0.5,'winStride': (8, 8), 'padding': (32, 32), 'scale': 1.05,'finalThreshold':2,'useMeanshiftGrouping':True}

#hog = cv2.HOGDescriptor()
#hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
#hogParams = {'hitThreshold' : 0.0,'winStride': (8, 8), 'padding': (32, 32), 'scale': 1.05,'finalThreshold':2,'useMeanshiftGrouping':False}

while(1):
    ret, frame = cap.read()

    if frame is None:
        break
    #ここで検出
    human, r = hog.detectMultiScale(frame,**hogParams)
    #検出結果を四角で囲む。
    for (x, y, w, h) in human:
    	cv2.rectangle(frame, (x, y),(x+w, y+h),(0,50,255), 3)

    cv2.imshow('frame',frame)
    writer.write(frame)

    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

cap.release()
writer.release()
cv2.destroyAllWindows()

pixabayから適当に動画を取ってきます。今回はAirportの動画を選択してみました。

また出力ファイルはffmpegで圧縮してあります。圧縮はこちらの前回のOpenCVの記事でも参考にいただければ。

Default 結果

Daimler 結果

まとめ

この動画ではDefaultのほうが結果が良さげですが、他の動画の場合はDaimlerのほうが良かったりしますね。たったこれだけのコードでここまで検出できちゃうのって凄いことですね。。

ただもっとふんだんにPCのリソースある場合は深層学習を使ってみたほうが良い結果が得られますね。処理時間は掛かる&ちょっとめんどくさいですが。いずれ別の記事にしてみます。

OpenCV

Posted by kitakantech