今、話題の人工知能(AI)などで人気のPython。初心者に優しいとか言われていますが、全然優しくない! という事を、つらつら、愚痴っていきます

384.顔検出、顔認識(1)

»

初回:2024/10/02

 OpenCV を使用した、顔検出と顔認識について何回かに分けて述べてみたいと思います。

P子「PINTOとかMediaPipeとか、色々あるわね」※1

 ≪参考資料1≫
  https://kazuhito00.hatenablog.com/entry/2021/11/28/225947
  PINTO_model_zoo:顔検出(129_SCRFD)Pythonデモ追加
  2021-11-28
  高橋かずひとのプログラミング、その他、備忘録。

 ≪参考資料2≫
  https://ai.google.dev/edge/mediapipe/solutions/vision/face_detector?hl=ja
  MediaPipe Face Detector
  顔検出ガイド

 ここでは高度な検出ではなく、OpenCVで使える簡単な仕組みでそれなりに使えることを実証してみたいと思います。

1.インストール

 まずは、OpenCV の顔検出を見てみましょう。
 対象は、Raspberry Pi の bookworm を対象に行っていきます。

  $ sudo apt install python3-opencv
  SDカードの延命処置として、/tmpなどを メモリに割り当てている場合は、一旦解除しておきます。OpenCV のインストール時にディスク容量不足で止まってしまいます。
  $ sudo nano /etc/fstab
        下記の2行が追加されていれば、# を付けてコメントアウトします。
        tmpfs /tmp           tmpfs defaults,size=64m,noatime,nodiratime,mode=1777 0 0
        tmpfs /var/tmp       tmpfs defaults,size=32m,noatime,nodiratime,mode=1777 0 0
  $
  $ sudo reboot
  元に戻す場合は、上記のコメントアウトを戻し、ディスク上の /tmp などを削除してから、再起動になります。
 その際、物理ディスクの削除と再起動を同時(一つのコマンド)で行います。
  $ sudo rm -rf /var/tmp || sudo rm -rf /tmp && sudo reboot

2.顔検出

 OpenCVで使用する顔検出として、Face Detector を試してみます。カスケード型分類器を使用します。カメラ映像からの顔検出を行ってみます。

 ≪参考資料3≫
  https://qiita.com/FukuharaYohei/items/ec6dce7cc5ea21a51a82
  【入門者向け解説】openCV顔検出の仕組と実践(detectMultiScale)
  最終更新日 2019年09月19日 投稿日 2017年08月03日

import time
import cv2

GREEN = (0, 255, 0)                 # BGR形式

if __name__ == '__main__':
    faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

    cap = cv2.VideoCapture(0)
    try:
        while True:
            ret, frame = cap.read()

            if ret:
                gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
                faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3, minSize=(30, 30))

                for (x, y, w, h) in faces:
                    cv2.rectangle(frame, (x, y), (x + w, y + h), GREEN, 2)

                cv2.imshow('Face Detect Frame', frame)

            k = cv2.waitKey(10)                 # ミリ秒単位で表されるキーボード入力待ち時間
            if k == ord('q') or k == 27:        # q または、ESC で終了
                break

            time.sleep(0.1)                     # CPU処理の軽減化

    except KeyboardInterrupt:                   # Ctl+Cが押されたらループを終了
        print("\nCtl+C Stop")
    except Exception as ex:
        print(ex)                               # 例外処理の内容をコンソールに表示
        import traceback
        traceback.print_exc()                   # Exception のトレース
    finally:
        if cap is not None:
            cap.release()
        cv2.destroyAllWindows()
        print("終了")

 haarcascade_frontalface_default.xml ファイルは、/usr/local/lib/python3.11/dist-packages/cv2/data から入手して、実行ファイルのあるフォルダにコピーします。もちろん、直接ファイルパスを記述しても構いません。フォルダは各自のインストール済みの python に依存します。

 そして、faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') からの
 faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3, minSize=(30, 30)) で、検出します。

 非常に簡単です。

 ※ openCV のインストール先の見つけ方。
  先の cascade ファイルを見つけるには、openCV のインストール先を見つける必要があります。

  $ python
Python 3.11.2 (main, Aug 26 2024, 07:20:54) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__file__
'/usr/local/lib/python3.11/dist-packages/cv2/__init__.py'
>>> exit()
  フォルダが特定できれば、その下の data フォルダに、各種cascade ファイルが置いてあります。

3.まとめ

 とりあえず、カメラ映像からの顔検出が出来ました。本当にお手軽ですね。

 この検出では、正面でないと検出しないとか光の当たり具合が重要とか各種の制約がありますが、ラズパイ B4 でも、それなりの速度で検出できます。まだまだ誤検知も多いのですが、次の顔識別にまでつなげられれば、色々と活用方法が広がると思います。

 ほな、さいなら

======= <<注釈>>=======

※1 P子「PINTOとかMediaPipeとか、色々あるわね」
 P子とは、私があこがれているツンデレPythonの仮想女性の心の声です。

Comment(0)

コメント

コメントを投稿する