Python | OpenCVで笑顔を検出する
- 2022.09.25
- Python
こんにちは!今回は「笑顔検出」を検証します。
利用するもの
前回の記事同様「Haar Cascades(Haar特徴ベースのCascade型分類器)」のうち、「Haarcascade_smile.xml」を利用します。
画像の笑顔識別
以下が今回作成したプログラムです。
#------------------------------------------------------------
#笑顔の検出(画像)
#------------------------------------------------------------
import cv2
try:
# 1)画像を読み取る
img = cv2.imread('lena_std.bmp')
if img is None:
raise FileNotFoudError('IMG Not Found!')
# 2)サイズを 縦400px にリサイズする(高さは連動)
img_h,img_w = img.shape[:2]
size = (400,int(400/img_w*img_h),)
img = cv2.resize(img,size)
# 3)検出器をロードする
# face_cascade : 顔を検出
# smile_cascade : 笑顔を検出
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
smile_cascade = cv2.CascadeClassifier('haarcascade_smile.xml')
if face_cascade is None or smile_cascade is None:
raise FileNotFoudError('XML Not Found!')
# 4)画像に検出器を適用する
for (x1,y1,w1,h1) in face_cascade.detectMultiScale(img):
# 5)顔領域(下半分)だけを抽出する
# 行、列の順なので img[y,x] で記載
only_mouse_img = img[int(y1+h1/2):(y1+h1),x1:x1+w1]
# 6)face_only_imgに対して、笑顔判定を掛ける
smile = smile_cascade.detectMultiScale(only_mouse_img)
# 7)顔領域を囲む
cv2.rectangle(img, (x1,y1), (x1+w1,y1+h1),(0,0,255), thickness=2)
# 8)笑顔の要素を囲む
if len(smile)>0:
for (x2,y2,w2,h2) in smile:
cv2.rectangle(img, (x1+x2,int(y1+h1/2)+y2), (x1+x2+w2,int(y1+h1/2)+y2+h2),(0,255,0), thickness=2)
else:
print('Not Smile')
# 9)画像を表示
cv2.imshow('lena',img)
# 10)キーイベントの待機 / 引数=0 で何か入力されるまで待つ
cv2.waitKey(0)
# 11)入力されたら、ウィンドウを閉じる
cv2.destroyAllWindows()
# except) Error時
except FileNotFoundError as e:
print(e)
Lenaの口元を検出することができました。
応用:動画から識別する
今回はカメラで投影したものに対して、笑顔か否かを判定します。
眼鏡等を外した状態で、笑顔時と無表情時の反応を比較してみてください。
#------------------------------------------------------------
#顔検出のプログラム(カメラ)
#------------------------------------------------------------
import cv2
try:
# 1)カメラIDを設定
camera = cv2.VideoCapture(0)
# 2)検出器をロードする
# face_cascade : 顔を検出
# smile_cascade : 笑顔を検出
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
smile_cascade = cv2.CascadeClassifier('haarcascade_smile.xml')
if face_cascade is None or smile_cascade is None:
raise FileNotFoudError('XML Not Found!')
# 3)繰り返し画像を取得する
while True:
# 4)設定したカメラから画像を取得
ret, img = camera.read()
# 5)サイズを 縦400px にリサイズする(高さは連動)
img_h,img_w = img.shape[:2]
size = (400,int(400/img_w*img_h),)
img = cv2.resize(img,size)
# 6)グレースケールに変換
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 7)画像に検出器を適用する
for (x1,y1,w1,h1) in face_cascade.detectMultiScale(img_gray):
# 8)顔領域(下半分)だけを抽出する
# 行、列の順なので img[y,x] で記載
only_mouse_img = img_gray[int(y1+h1/2):(y1+h1),x1:x1+w1]
# 9)face_only_imgに対して、笑顔判定を掛ける
smile = smile_cascade.detectMultiScale(only_mouse_img)
# 10)顔領域を囲む
cv2.rectangle(img, (x1,y1), (x1+w1,y1+h1),(0,0,255), thickness=2)
# 11)笑顔の要素を囲む
if len(smile)>0:
for (x2,y2,w2,h2) in smile:
cv2.rectangle(img, (x1+x2,int(y1+h1/2)+y2), (x1+x2+w2,int(y1+h1/2)+y2+h2),(0,255,0), thickness=2)
# 12) 画像を表示
cv2.imshow('Face_Capture',img)
# 13) Escが入力されたらループ処理を終了する
key = cv2.waitKey(10)
if key == 27:
break
# 14)入力されたら、ウィンドウを閉じる
cv2.destroyAllWindows()
# 15)カメラのメモリを解放する
camera.release()
# except) Error時
except FileNotFoundError as e:
print(e)
今回は以上です。
ではまた。
-
前の記事
Python | OpenCVで顔を検出する 2022.09.23
-
次の記事
Python | OpenCVで色の割合を求める 2022.09.27