デジカメのように顔検出するプログラムを作ってみたいと思いませんか?
OpenCVを使えば、たった十数行で顔検出できるプログラムが出来上がります。
OpenCVには大量の画像から人の顔の特徴を学習し、人の顔を判別する「カスケード分類器」が用意されています。これを使用した顔検出プログラムを解説していきます。
顔検出の流れは以下のとおりとなります。
サンプルプログラム
import cv2 as cv
#カスケード分類器読み込み
HAAR_FILE = "haarcascade_frontalface_default.xml"
cascade = cv.CascadeClassifier(HAAR_FILE)
#画像の読み込み
img = cv.imread("sample.jpg")
#顔検出
face = cascade.detectMultiScale(img)
#顔部を枠で囲む
for x, y, w, h in face:
cv.rectangle(img,(x,y),(x+w,y+h),(0,0,255),1)
cv.imshow("img", img)
cv.waitKey(0)
cv.destroyAllWindows()
プログラム解説
カスケード分類器を読み込む
HAAR_FILE = "haarcascade_frontalface_default.xml"
cascade = cv.CascadeClassifier(HAAR_FILE)
cv.CascadeClassifier()メソッドを呼び出し、人の顔を検出するための「カスケード分類器」を読み込みます。
カスケード分類器?
OpenCVは、人の顔を集めた大量画像から人の顔の特徴量をまとめたHaar-Cascadeが用意されています。これはGitHubからダウンロードすることが出来ます。
今回は、正面の顔を検出する「haarcascade_frontalface_default.xml」を使用しました。他にも色々な分類器があります。
画像を読み込む
img = cv.imread("sample.jpg")
cv.imread()メソッドを呼び出し、人の顔を検出したい画像を読み込みます。
顔検出
face = cascade.detectMultiScale(img)
cascade.detectMultiScale()メソッドを呼び出し、画像内の顔を検出します。戻り値として、検出した顔の位置が配列に格納され返ってきます。戻り値は順に、顔の位置のx座標、y座標、横幅、縦幅になります。
顔部を枠で囲む
for x, y, w, h in face:
cv.rectangle(img,(x,y),(x+w,y+h),(0,0,255),1)
faceに顔の位置座標が格納されています。顔が正常に検出されたかどうか確認するため、元画像に赤枠を加えます。
色々な画像で顔検出を試してみる
違う画像でも試してみました。この画像は5人中、4人検出出来ました。検出出来ない人もいます。
横顔は検出するのが難しそうです。誤検出も発生しています。
PCカメラでリアルタイムに顔検出
ここまでの解説は静止画像でした。プログラムを少し改変することで、PCカメラのリアルタイム画像から顔検出することが出来ます。
自分の顔が検出されるか試してみて下さい。
import cv2 as cv
HAAR_FILE = "haarcascade_frontalface_default.xml"
cascade = cv.CascadeClassifier(HAAR_FILE)
cap = cv.VideoCapture(0)
while(True):
ret, frame = cap.read()
face = cascade.detectMultiScale(frame)
for x, y, w, h in face:
cv.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),1)
cv.imshow('frame',frame)
if cv.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv.destroyAllWindows()
まとめ
OpenCVの「カスケード分類器」を使用した顔検出プログラムについて解説しました。
手順をおさらいすると以下になります。
- カスケード分類器を読み込む
- 画像を読み込む
- 顔検出
- 顔部を枠で囲む
今回の記事が皆さんのPython学習に役立つなら幸いです。
Python独学が大変な方は、書籍やスクールを活用するのも手です。
Python 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイルを学ぶオンライン講座