PythonとOpenCV 3でPCのビデオカメラでリアルタイム顔認識してみた
はじめに
Pythonを最近触り始めているので、いまさらながらOpenCV3を使ってPCのWebカメラから顔認識をやってみる。
環境はMac上でanacondaでPython 3.6環境を作っているので、その上で検証する。
環境は以下の通り。
- Mac: Sierra - バージョン10.12.6
- Python: 3.6
- OpenCV: 3.3.0
OpenCV 3インストール
まずはcondaでインストールしようとしたが、普通にsearchすると2系が出て来る。
$ conda search opencv Fetching package metadata ............. opencv 2.4.8 np17py27_2 defaults
調べたところ、3系はcondaの場合はここから入れられるようだったので、-cオプションを付けてインストールしてみる。
https://anaconda.org/menpo/opencv3
$ conda install -c menpo opencv3 Fetching package metadata ............... Solving package specifications: . UnsatisfiableError: The following specifications were found to be in conflict: - opencv3 -> python 2.7* - python 3.6* Use "conda info <package>" to see the dependencies for each package.
エラー。
さらに調べたところ、menpoのopencvは、現在(2017/10/22)Python3.6に対応したものにまだなっていないらしい。
また、以下の場所からでも3.6対応済みのopencv3が入れられるようだったので、こちらから入れてみる。
$ conda install -c conda-forge opencv
今度は正常に終了した。
$ conda list opencv # packages in environment at /anaconda: # opencv 3.3.0 py36_blas_openblas_200 [blas_openblas] conda-forge
OpenCV3がインストールできた。
OpenCVの顔認識チュートリアルをやってみる
チュートリアルがここにあるので、ここのサンプルコードをそのまま動かしてみる。
https://docs.opencv.org/trunk/d6/d00/tutorial_py_root.html
顔認識のチュートリアルはこちら。
https://docs.opencv.org/trunk/d7/d8b/tutorial_py_face_detection.html
顔認識のためにはOpenCVで標準で付属している識別器を使う。Haar 特徴量にもとづくCascade 識別器ということで、haarcascadesフォルダ以下にxmlファイルとして容易されているのが、mac上のcondaで導入した場合は以下のパスにファイルがあった。
/anaconda/share/OpenCV/haarcascades
チュートリアルで使う以下の二つをプロジェクトフォルダにコピーしておく。顔認識用と、目を認識するための識別器となっている。
haarcascade_frontalface_default.xml haarcascade_aarcascade_eye.xml
まずサンプル通りのコードを静的なファイルに対して実行する。
画像処理のサンプルデータとしておなじみのlena画像ファイルをプロジェクトフォルダにコピーしておき、それに対して実行した。
import numpy as np import cv2 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml') img = cv2.imread('lena.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x,y,w,h) in faces: cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] eyes = eye_cascade.detectMultiScale(roi_gray) for (ex,ey,ew,eh) in eyes: cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2) cv2.imshow('img',img) cv2.waitKey(0) cv2.destroyAllWindows()
実行するとこのように、顔と目が認識されていることが分かる!
PCのビデオカメラでリアルタイム顔認識をやってみる
続いて、静的な画像ファイルではなく、PC本体のカメラから動的に顔認識を行ってみる。
基本的なコードは先ほどのものをベースに、ビデオキャプチャを行うcv2.VideoCapture
で画像を取得し、キーボードのqが押されるまでカメラから取得した画像に対して先ほどの顔と目の認識を行い続ける。
import numpy as np import cv2 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml') cap = cv2.VideoCapture(0) while(True): ret, img = cap.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x,y,w,h) in faces: cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] eyes = eye_cascade.detectMultiScale(roi_gray) for (ex,ey,ew,eh) in eyes: cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2) cv2.imshow('img', img) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
これを実行するとカメラが起動するので、自分の顔に対して正しく認識がうまくいくことを確認できる。
以下は、私がジョン・F・ケネディ博物館に行ったときにおみやげで買ってきた、アメリカ歴代大統領の顔写真のシートである。わかりづらいが、シートを直接持ってPCのカメラに写しているところ。
中央のケネディ大統領は問題なく顔と目が認識でき、それ以外の大統領も全てではないが、いくつかの顔認識がうまくいっている(ちょっと外しているものもあるが)。さすがに目は小さくて取れなかったよう。
まとめ
PythonからOpenCV3の顔認識を試してみた。かなり簡単に実装でき、カメラからの動的な画像に対しても処理できているので、Raspberry Piのカメラとかでリアルタイムにやることとかも色々できそう。
以上!