読者です 読者をやめる 読者になる 読者になる

OpenCVを使ってカメラの映像を顔認識をしてみる

開発

Python,OpenCV3を使ってカメラの映像からざっくり顔認識してみる。 Mac環境で、パッケージ管理はanacndaを利用。

インストール

brew install pyenv
$ xcode-select --install
$ pyenv install anaconda3-4.0.0
$ pyenv global anaconda3-4.0.0
$ pyenv rehash
$ pyenv version
anaconda3-4.0.0 (set by /Users/username/.pyenv/version)

env を設定

export PATH="$HOME/.pyenv/shims:$PATH"
export LC_ALL='ja_JP.UTF-8'

condaのアップデート

$ conda update conda
$ python --version
Python 3.5.1 :: Anaconda custom (x86_64)

OpenCV3のインストール

condaを使ってインストール。

$ conda install -c https://conda.binstar.org/menpo opencv3

エラーになる場合

libhdf5でエラーになる時がある。

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    import cv2, matplotlib
ImportError: dlopen(/Users/username/.pyenv/versions/anaconda3-4.0.0/lib/python3.5/site-packages/cv2.cpython-35m-darwin.so, 2): Library not loaded: @rpath/libhdf5.10.dylib
  Referenced from: /Users/username/.pyenv/versions/anaconda3-4.0.0/lib/libopencv_hdf.3.1.0.dylib
  Reason: Incompatible library version: libopencv_hdf.3.1.dylib requires version 12.0.0 or later, but libhdf5.10.dylib provides version 11.0.0

libhdf5 をインストールしたりアップデートしたりする。

$ brew tap homebrew/science
$ brew install hdf5
$ brew search 
$ conda update libhdf5

OpenCVのバージョンを確認

python
>>> import cv2
>>> print(cv2.__version__)
3.1.0

必要なパッケージをインストールしておく。

$ conda install numpy matplotlib

カメラから映像を取り込む

cv2.VideoCapture() を使うとisightカメラをそのまま使える。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)
cap.set(3, 640) # 横サイズ
cap.set(4, 480) # 縦サイズ

while(True):
    ret, frame = cap.read()
    if ret == False:
        break

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # グレースケールに変換

    cv2.imshow('fram', gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.dstroyAllWindows()
  • 毎フレームごとに読み込んで、cv2.imshow() に設定する

実行するとカメラの映像を白黒にしたプレビューが表示される。

送られてきた映像から、顔認識をする

パフォーマンスを気にしないで、ざっくりと顔認識を体験したいとする。 顔認識は、cv2.CascadeClassifier() を使う。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)
cap.set(3,640)
cap.set(4,480)

cascade_path = "/Users/username/.pyenv/versions/anaconda3-4.0.0/pkgs/opencv3-3.1.0-py35_0/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_path)
color = (0,0,255)

cnt = 0
while(True):
    ret, frame = cap.read()
    if ret == False:
        break
    else:
        if (cnt % 10) == 0:
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            facerect = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=1, minSize=(1, 1))

        cnt += 1

        if len(facerect) > 0:
            for rect in facerect:
                cv2.rectangle(frame, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), color, thickness=4)

    cv2.imshow('fram', frame)

cap.release()
cv2.dstroyAllWindows()
  • 全てのフレームに cascade.detectMultiScale() をかけるとCPU負荷がかなりかかるので適当に10フレームごとに確認をする
  • cascade.detectMultiScale() はグレースケールの画像を使って精査する
  • 顔認識の結果を cv2.rectangle() を使って毎フレームごとに枠線を書き込むようにする

結果

f:id:taizo_onexone:20160627143923g:plain

仗助の顔を識別してくれない。

参考

postd.cc qiita.com