前回は写真から顔検出を行いましたが、今回はPCについているカメラまたはUSBカメラからリアルタイムで顔の検出を行うプログラムを紹介します。
実行結果
OS:Windows11
IDE:VS Code
言語:Python 3.10.9
パッケージ:opencv 4.6.0、qt-main 5.15.2
仮想環境:Miniconda
事前準備
前回の作業フォルダ「python_work」内に「camera_face_detection.py」を新規追加します。仮想環境は「face_detection」となります。作業環境等の詳細は下記をご覧ください。
顔認証に使った画像は「写真AC」を利用しました。今回はPCに付いているカメラを利用しますので皆さんの顔が検出されるか確かめてください。
プログラミング
「camera_face_detection.py」にコードを記述します。
import cv2
# 分類器
cascade_path = 'opencv-master/data/haarcascades/haarcascade_frontalface_default.xml'
# 特徴量読み込み
cascade = cv2.CascadeClassifier(cascade_path)
# カメラ定義
cap = cv2.VideoCapture(0, cv2.CAP_MSMF)
while(True):
# ビデオキャプチャ
ret, frame = cap.read()
# 顔検出
faces = cascade.detectMultiScale(frame, scaleFactor=1.23, minNeighbors=3, minSize=(50, 50))
# 検出した顔を囲む矩形の作成
for x, y, w, h in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (127, 255, 0), 2)
# 表示
cv2.imshow('frame', frame)
# qが押されたら終了
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# カメラ終了
cap.release()
# ウィンドウ終了
cv2.destroyAllWindows()
import
import cv2
opencvをプログラム内で使えるようにインポートします。
分類器の設定
# 分類器
cascade_path = 'opencv-master/data/haarcascades/haarcascade_frontalface_default.xml'
# 特徴量読み込み
cascade = cv2.CascadeClassifier(cascade_path)
cascade_path:顔検出用のファイルを設定します。「haarcascade_frontalface_default.xml」は正面の顔を検出するためのxmlファイルです。
cv2.CascadeClassifier():顔検出用のxmlファイルを読み込みます。
カメラの定義
# カメラ定義
cap = cv2.VideoCapture(0, cv2.CAP_MSMF)
cv2.VideoCapture():PCに接続されているカメラの設定を行います。
第1引数はカメラデバイスIDです。基本的に「0」で問題ありませんが複数のカメラやIRカメラがある場合は「1」の場合もあります。
第2引数は「apiPreference」を設定します。OS等でAPIが異なるのでここで指定します。Windowsであれば「cv2.CAP_MSMF」macOSであれば「cv2.CAP_AVFOUNDATION」と入力します。
macではエラーは出なかったのですがWindowsでは下記のエラーが発生しますが動作に影響はありません。
QMimeDatabase: Error loading internal MIME data
An error has been encountered at line 1 of <internal MIME data>: Premature end of document.:
ビデオキャプチャ
# ビデオキャプチャ
ret, frame = cap.read()
read():先ほどカメラの定義を行った「cap」を使ってビデオキャプチャを行います。
第1戻り値「ret」にはキャプチャ(画像取得)が成功したか結果が入ります。成功:True、失敗:False
第2戻り値「frame」には画像データ(1フレーム)が入ります。
顔の検出
# 顔検出
faces = cascade.detectMultiScale(frame, scaleFactor=1.23, minNeighbors=3, minSize=(50, 50))
detectMultiScale():特徴量を読み込んだ「cascade」を使って検出を行います。
第1引数は検出する画像を指定します。
第2引数「scaleFactor」は画像サイズをどれくらい縮小して検出を行うかを設定します。「1.1」は10%まで縮小します。設定できる範囲は「1.0 < scaleFactor」、1.0に近いほど処理が重くなります。
第3引数「minNeighbors」は候補となる矩形に含まれる近傍矩形の数を設定します。「3」は近傍矩形が3つないと候補から除外されます。設定できる範囲は「0 <= minNeighbors」0だと精度が下がります。
第4引数「minSize」は候補となる矩形サイズが設定値以下だと候補から除外されます。サイズはpixel単位となります。
戻り値「faces」には検出した顔の座標が入ります。
検出した顔を囲む矩形の作成
# 検出した顔を囲む矩形の作成
for x, y, w, h in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (127, 255, 0), 2)
rectangle():長方形を描画します。
第1引数「frame」は描画する画像を指定します。
第2引数「(x, y)」は長方形を描画する座標1を指定します。pixel単位となります。
第3引数「(x+w, y+h)」は長方形を描画する座標1を指定します。pixel単位となります。
第4引数「(127, 255, 0)」は長方形を描画する色を指定します。RGBで指定します。
第5引数「2」は長方形を描画する太さを指定します。pixel単位となります。
表示処理
# 表示
cv2.imshow('frame', frame)
imshow():画面へ表示します。
第1引数「’frame’」画面に表示するウィンドウ名を指定します。
第2引数「frame」実際に表示する画像を指定します。
ブレイク処理
# qが押されたら終了
if cv2.waitKey(1) & 0xFF == ord('q'):
break
waitKey():表示している画面でキーイベントの発生を待ちます。
第1引数「1」は1ミリ秒待機となります。
条件式「0xFF == ord(‘q’)」キーボードの「q」が押下されたかを判定します。
キーボードの「q」が押下されたらwhile文を抜けます。
後処理
# カメラ終了
cap.release()
# ウィンドウ終了
cv2.destroyAllWindows()
release():カメラを終了します。
destroyAllWindows():ウィンドウを閉じます。
プログラムの実行
python camera_face_detection.py
ウィンドウにカメラ画像が表示され顔を検出すると枠線で囲まれるます。
終了はキーボードの「q」を押下します。
まとめ
カメラ画像をリアルタイムで表示しながら顔の検出を行うプログラムが20行程度で出来てしまいます。
Haar Cascade識別器を変えることで瞳の検出や人物の検出等行うことができます。
色々試してみてください。
コメント