Python | OpenCVで顔を検出する
- 2022.09.23
- Python
今回はOpenCVの顔検出機能を検証します。
Haar Cascadesのダウンロード
物体検出を行うための測定器である「Haar Cascades(Haar特徴ベースのCascade型分類器)」を利用します。
あらかじめ特徴量を学習しておいたxmlファイルをプログラムにセットすることで、簡単に顔検出器を作成することができます。
XMLファイルは以下のリンクから取得することができます。
今回は「顔検出」ということで、「haarcascade_frontalface_default.xml」を利用します。
顔画像の準備
今回は「Lena」画像をもとに顔認証します。
画像の入手方法はこちらを参照ください。
検証
今回のソースは以下の通りです。
#------------------------------------------------------------
#顔検出のプログラム(画像)
#------------------------------------------------------------
import cv2
try:
# 1)画像を読み取る
img = cv2.imread('lena_std.bmp')
if img is None:
raise FileNotFoudError('IMG Not Found!')
# 2)検出器をロードする
cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
if cascade is None:
raise FileNotFoudError('XML Not Found!')
# 3)画像に検出器を適用する
# arrayが返ってくる
# 例:array([[217, 201, 173, 173]])
# array([[x, y, w, h]])
face = cascade.detectMultiScale(img)
# 4)顔を枠で囲む
# cv2.retangle(画像,xy座標,対角線上のxy座標,色,線の太さ)
if len(face)>0:
for (x,y,w,h) in face:
cv2.rectangle(img, (x,y), (x+w,y+h),(0,255,0), thickness=2)
else:
print('ERROR')
# 5)画像を表示
cv2.imshow('lena',img)
# 6)キーイベントの待機 / 引数=0 で何か入力されるまで待つ
cv2.waitKey(0)
# 7)入力されたら、ウィンドウを閉じる
cv2.destroyAllWindows()
# except) Error時
except FileNotFoundError as e:
print(e)
顔検出を行うことができました!
応用:目の検出
目を検出する場合は「haarcascade_eye.xml」を利用します。
cascadeを以下のように変更します。
cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
応用:目と顔を検出する
顔を赤色、目を緑色で示します。
#------------------------------------------------------------
#顔&目検出のプログラム(画像)
#------------------------------------------------------------
import cv2
try:
# 1)画像を読み取る
img = cv2.imread('lena_std.bmp')
if img is None:
raise FileNotFoudError('IMG Not Found!')
# 2)検出器をロードする
cascade_face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cascade_eye = cv2.CascadeClassifier('haarcascade_eye.xml')
if cascade is None:
raise FileNotFoudError('XML Not Found!')
# 3)画像に検出器を適用する
face = cascade_face.detectMultiScale(img)
eye = cascade_eye.detectMultiScale(img)
# 4)顔を枠で囲む
if len(face)>0 and len(eye)>0:
for (x,y,w,h) in face:
cv2.rectangle(img, (x,y), (x+w,y+h),(0,0,255), thickness=2)
for (x,y,w,h) in eye:
cv2.rectangle(img, (x,y), (x+w,y+h),(0,255,0), thickness=2)
else:
print('ERROR')
# 5)画像を表示
cv2.imshow('lena',img)
# 6)キーイベントの待機 / 引数=0 で何か入力されるまで待つ
cv2.waitKey(0)
# 7)入力されたら、ウィンドウを閉じる
cv2.destroyAllWindows()
# except) Error時
except FileNotFoundError as e:
print(e)
応用:映像から顔を検出する
上記の画像処理を応用して、カメラから取得した画像にたいして、顔検出を適用してみます。
import cv2
try:
# 1)カメラIDを設定
camera = cv2.VideoCapture(0)
# 2)検出器をロードする
cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
if cascade is None:
raise FileNotFoudError('XML Not Found!')
# 3)繰り返し画像を取得する
while True:
# 4)設定したカメラから画像を取得
ret, img = camera.read()
# 5)画像に検出器を適用する
face = cascade.detectMultiScale(img)
# 6)顔を枠で囲む
if len(face)>0:
for (x,y,w,h) in face:
cv2.rectangle(img, (x,y), (x+w,y+h),(0,255,0), thickness=2)
# 7) 画像を表示
cv2.imshow('Face_Capture',img)
# 8) Escが入力されたらループ処理を終了する
key = cv2.waitKey(10)
if key == 27:
break
# 9)入力されたら、ウィンドウを閉じる
cv2.destroyAllWindows()
# 10)カメラのメモリを解放する
camera.release()
# except) Error時
except FileNotFoundError as e:
print(e)
こちらも映像から顔を検出することができたかと思います。
原理としては、画像から顔を検出する処理を繰り返しているだけです。
ただ、この検出器は「横顔」や「眼鏡」には対応しきれないようでした。
いろいろな検出器がありますので、試してみるのもよいですね!
ではまた!
-
前の記事
Python | OpenCVでQRコードリーダーを作成する 2022.09.22
-
次の記事
Python | OpenCVで笑顔を検出する 2022.09.25