Python版OpenCVで顔検出
2017年9月、Raspberry PiでPython版OpenCVを用いて顔検出するPythonスクリプトを作成しました。
USBカメラから画像を入力して顔検出し、顔検出枠を付加して描画します。また、フレームレートを計測して画面に表示しました。フレームレート計測は、下記を参照してください。
PythonとOpenCVのバージョンを確認します。
- Python : 2.7.13
- OpenCV : 3.3.0
$ python Python 2.7.13 (default, Jan 19 2017, 14:48:08) [GCC 6.3.0 20170124] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> print cv2.__version__ 3.3.0 >>> quit()
顔検出スクリプト
顔検出するPythonスクリプトを下記に示します。
$ cat cvface.py #!/usr/bin/python # -*- coding: utf-8 -*- import cv2 import fps cascade_file = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" cascade = cv2.CascadeClassifier(cascade_file) # ■ 識別器読み込み gFrameRate = fps.FrameRate() # フレームレート初期化 fontcolor = (255,255,255) fontface = cv2.FONT_HERSHEY_SIMPLEX fontthick = 2 cap = cv2.VideoCapture(0) cap.set( cv2.CAP_PROP_FRAME_WIDTH , 320 ) cap.set( cv2.CAP_PROP_FRAME_HEIGHT , 240 ) while( cv2.waitKey(1) < 0 ): ret, ImgFrame = cap.read() # カメラ入力 ImgGray = cv2.cvtColor(ImgFrame, cv2.COLOR_RGB2GRAY) # グレースケール画像に変換 # ■ 顔検出 FaceList = cascade.detectMultiScale( ImgGray, scaleFactor=1.1, minNeighbors=2, minSize=(20,20)) for face in FaceList: (x, y, w, h) = face cv2.rectangle(ImgGray, (x,y), (x+w, y+h), (255,0,0), 2) # 顔枠表示 fps = gFrameRate.get() # フレームレート取得 fps_str = '%4d' % fps cv2.putText(ImgGray, fps_str, (10,25), fontface, 1.0, fontcolor, fontthick , cv2.LINE_AA) cv2.imshow('Face Detect',ImgGray) # When everything done, release the capture cap.release() cv2.destroyAllWindows()
「cascade = cv2.CascadeClassifier(cascade_file)」で、正面顔検出用の学習済み識別器カスケードを読み込みます。
「cv2.VideoCapture(0)」で、VideoCaptureクラスをインスタンス化して、インスタンス cap を生成します。「cap.set( )」で、画像サイズ CAP_PROP_FRAME_WIDTH(幅)と CAP_PROP_FRAME_HEIGHT(高さ)を設定します。
「ImgFrame = cap.read()」で、キャプチャーデバイスから次のフレームを取得・デコードして、ImgFrameに格納します。
「ImgGray = cv2.cvtColor()」で、グレースケール画像に変換します。
「cascade.detectMultiScale()」で、グレースケール画像から顔検出して、FaceListに検出結果を格納します。
FaceList = cascade.detectMultiScale(
ImgGray, scaleFactor=1.1, minNeighbors=2, minSize=(20,20))
- scaleFactor : 各画像スケールにおける縮小量
- minNeighbors : 信頼性のパラメーターで、物体候補となる矩形の最小近傍矩形数
- minSize : 物体が取り得る最小サイズ
検出結果 FaceList は、複数の顔検出結果をリスト構造にしたものです。たとえば、3つの顔を検出した場合は次のようになります。
[ [166 24 44 44]
[257 93 51 51]
[180 106 52 52] ]
ひとつのリストは、[x, y, w, h]の値です。顔枠は、(x,y)と(x+w, y+h)を対角線とする矩形を「cv2.rectangle(ImgGray ・・・)」で描画します。
「cv2.imshow( )」で、ウインドウFace DetectにImgGrayの画像を表示します。
顔検出の実行
OpenCVのサンプル画像( /opencv-3.3.0/samples/data/lena.jpg )を使用します。
lena画像を3つ(100% , 75% , 53%)表示して、そのモニター画像をカメラで撮影して顔を検出します。その結果、3つのlena画像を顔認識することができました。
フレームレートは、5~10fps程度で動作しました。やはり顔検出は、重たい処理です。
画面の右上を見ると、見慣れない温度計マークが表示されました。
顔検出処理でCPU負荷が上がり、CPU温度が高くなったという警告らしいです。