Pythonで顔認識に挑戦!OpenCVで画像から顔を検出する方法

ブログのアイコン画像、覚えてますか?実はPythonを使って簡単に顔検出ができるんです!今回は、OpenCVライブラリを使ってリアルタイムで顔を認識するプログラムを紹介します。実際に私のアイコン画像で試した結果も載せているので、ぜひ参考にしてみてください!

なぜ顔検出するの?

顔検出って聞くと難しそうに感じるかもしれませんが、実は身近なところで使われているんですよ。例えば、スマートフォンの顔認証や、カメラアプリの顔認識フォーカスなど。セキュリティシステムや写真管理アプリにも活用されています。

OpenCVって?

OpenCV(Open Source Computer Vision Library)は、画像処理やコンピュータビジョンに特化したオープンソースライブラリです。高機能なのに使いやすく、リアルタイム処理も得意なので、今回のような顔検出プログラムにぴったりです。

プログラム全貌

早速ですが、今回使うプログラムを紹介します。少し長いですが、一つずつ解説していくので安心してくださいね。

import cv2
import time

def main():

    # 事前学習済み カスケード分類器の XML ファイルを読み込み(今回は、Opencvで標準のデータを使用)
    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    
    cap = cv2.VideoCapture( 0 )
    
    while(True):
        ret, frame = cap.read()

        if ret == True:
            # 顔を検出
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # グレースケールに変換(色情報を落とす)
            faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

            # 検出した顔に矩形を描画
            for (x, y, w, h) in faces:
                cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)

            # フレームを表示
            cv2.imshow('Camera Feed', frame)

        # 'q'キーが押されたらループを終了
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break


    cap.release()
    cv2.destroyAllWindows()
    
if __name__ == '__main__':
    main()

プログラム説明

グレースケール変換って必要?

プログラムの中でcv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)という部分、これは画像をグレースケールに変換する処理です。なぜこんなことをする必要があるのでしょうか?

  • 処理が速くなる!: カラー画像はRGB(赤、緑、青)の3つの情報を持っていますが、グレースケールは明るさだけの1つの情報でOK。だから処理が軽くなって速くなるんです。
  • アルゴリズムがシンプルになる!: 多くの画像処理アルゴリズムはグレースケール画像向けに作られているので、処理が簡単になります。
  • ノイズが減る!: カラー画像だと、それぞれの色の情報にノイズが入っている可能性があります。グレースケールに変換することで、これらのノイズの影響を減らす効果もあるんです。

顔を見つける魔法、カスケード分類器

face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))の部分では、カスケード分類器を使って顔検出を行っています。

  • カスケード分類器: リアルタイムで高精度な検出をするための、優秀な機械学習アルゴリズムです。
  • detectMultiScale: 画像の中から物体をさがす関数です。見つけた物体の位置と大きさを教えてくれます。
    • scaleFactor: 画像を縮小していく比率です。1より大きい値で、大きいほど処理は速くなりますが、小さい顔を見逃してしまう可能性も。
    • minNeighbors: 顔だと判断するための周りの矩形の最小数です。大きいほど誤検出は減りますが、見逃しも増えるかも。精度を上げたいときは大きくするのがポイントですが、処理速度は遅くなります。
    • minSize: 検出する顔の最小サイズです。
    • maxSize: 検出する顔の最大サイズです。

他の顔検出器も試してみよう!

haarcascade_frontalface_default.xml以外にも、opencvでは色々なカスケード分類器のデータセットがが用意されているんです。

ファイル名検出対象
haarcascade_frontalface_alt.xml正面の顔(代替版)
haarcascade_frontalface_alt2.xml正面の顔(代替版2)
haarcascade_frontalface_alt_tree.xml正面の顔(代替ツリー版)
haarcascade_profileface.xml横顔
haarcascade_eye.xml
haarcascade_eye_tree_eyeglasses.xml眼鏡をかけた目
haarcascade_nose.xml
haarcascade_smile.xml笑顔
haarcascade_fullbody.xml全身
haarcascade_upperbody.xml上半身
haarcascade_lowerbody.xml下半身
OpenCVカスケード分類器 学習データセット

まとめ

PythonとOpenCVを使えば、意外と簡単に顔検出プログラムが作れるんです!パラメータを調整することで、精度と速度のバランスも取れるので、色々試してみてください。

OpenCVのこの方法での顔検出は、非常に軽い処理でできているので、RaspberryPiなんかでも動作すると思いますので、試してみても面白いと思います。
RaspberryPiの立ち上げ方に関する記事はこちら

GUI付きでカメラ映像を表示して、録画と静止画保存ができるプログラムをこちらで紹介していますので、組み合わせると顔を認識すると録画開始!なんてことができて面白いかもしれないですね。

この記事が、あなたの役に立てば幸いです!

Pythonの学習には、こちらを参考にしてみてください

にいやん

出身 : 関西 居住区 : 関西 職業 : 組み込み機器エンジニア (エンジニア歴13年) 年齢 : 38歳(2022年11月現在) 最近 業務の効率化で噂もありPython言語に興味を持ち勉強しています。 そこで学んだことを記事にして皆さんとシェアさせていただければと思いブログをはじめました!! 興味ある記事があれば皆さん見ていってください!! にほんブログ村