トップページ -> Pythonによる視線検出について -> dlibによるリアルタイムな顔器官の検出

dlibによるリアルタイムな顔器官の検出

視線の検出をするには画像の中から目の位置を判定する必要があります. dlibを使って顔や顔器官の検出をすることができます. 今回はdlibのインストール,静止画の顔・顔器官検出,リアルタイムな顔・顔器官検出の方法について紹介します.

前回まで

dlibによる顔の検出
dlibのテスト

dlibのインストール

dlibのインストール方法に関してですが,少し複雑です. Git, CMake, Build Tools for Visual Studio 2022が必要になります. また,NVIDIAのGPUを使用したい場合は,NVIDIA ドライバ,NVIDIA CUDA ツールキット,NVIDIA cuDNNが追加で必要になります.(GPUが無くても動きます) 金子邦彦研究室のDlib,face_recognition のインストールと動作確認(顔検出,顔識別)(Python を使用)(Windows 上)で非常に分かりやすく解説されていますので詳しいインストール方法はこちらをご覧ください. 手元のWindows10, Python 3.9.7, Build Tools for Visual Studio 2022, NVIDIA CUDA ツールキット 11.8,NVIDIA cuDNN v8.6, NVIDIA GeForce RTX 2080で動作を確認しています. インストールの手順と参考になる金子邦彦研究室のリンクを載せておきます. 上から順に済ませていくと右往左往せずに済むと思います.

  1. Gitのインストール

  2. インストールしているか否かが分からない場合はコマンドプロンプトにて 「where git」 と打ち込んでパスが表示されるかを確認してください.
    Git 2.28 のインストール(Windows 上)
  3. CMake のインストール

  4. CMake のインストール(Windows 上)
  5. Build Tools for Visual Studio 2022 のインストール

  6. Build Tools for Visual Studio 2022 (ビルドツール for Visual Studio 2022)のインストール(Windows 上)
  7. NVIDIA ドライバ,NVIDIA CUDA ツールキット,NVIDIA cuDNNのインストール (GPUを使用する場合のみ)

  8. 必ず先にBuild Tools for Visual Studioをインストールしてください.今回動かす予定のプログラムはGPUが無くても問題なく動作します.
    どのバージョンを入れればいいのか分からない場合はNVIDIA CUDA Toolkit, cuDNNのバージョンについてをご覧ください. NVIDIA ドライバ,NVIDIA CUDA ツールキット 11.8,NVIDIA cuDNN v8.8 のインストールと動作確認(Windows 上)
  9. Dlib のインストール

  10. Dlib,face_recognition のインストールと動作確認(顔検出,顔識別)(Python を使用)(Windows 上)
【参考(外部サイト)】 金子邦彦研究室へようこそ(トップページ)
【関連(外部サイト)】 金子邦彦 YouTube チャンネル

dlibによる顔器官の検出 ~静止画~

インストールが正常に終了したらコマンドプロンプトで下記のコードを走らせることで,ページ冒頭のような画像が表示されると思います.


cd C:\dlib
cd python_examples
python cnn_face_detector.py mmod_human_face_detector.dat ..\examples\faces\2007_007763.jpg
静止画についての dlib/python_exampleに入っている cnn_face_detector.py や face_detector.pyで行うことができます. 具体的には下記のようなコードです. 画像はフリー素材を使っています. 使用した画像はこちら. frontal_face_detectorでは検出漏れがありますが,5人は検出できています.
dlibによる顔の検出 ~2~
dlibのテスト2

import sys
import dlib

# detectorオブジェクトの作成
detector = dlib.get_frontal_face_detector()

# 表示用のウィンドウ
win = dlib.image_window()

# 画像の読み込み
filepath = "23337291_s.jpg"
img = dlib.load_rgb_image(filepath)

# 画像を検出器(detector)にかけて顔を検出します
dets = detector(img, 1)
print("Number of faces detected: {}".format(len(dets)))
for i, d in enumerate(dets):
    print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
        i, d.left(), d.top(), d.right(), d.bottom()))

# 画像に検出した顔の位置を重ね合わせて表示する
win.clear_overlay()
win.set_image(img)
win.add_overlay(dets)
また,predictorを使うことで顔器官を検出することができます. 顔の輪郭,鼻,口,目の位置を推測することができます. 推測した顔器官の位置に赤い点を打ち込んでいます.
dlibによる顔器官の検出
dlibのテスト3

import sys
import dlib

# detectorオブジェクトの作成
detector = dlib.get_frontal_face_detector()

# predictorオブジェクトの作成
PREDICTOR_PATH = r"C:\dlib\python_examples\shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(PREDICTOR_PATH)

# 表示用のウィンドウ
win = dlib.image_window()

# 画像の読み込み
filepath = "23337291_s.jpg"
img = dlib.load_rgb_image(filepath)

# 画像を検出器(detector)にかけて顔を検出します
dets = detector(img, 1)

print("Number of faces detected: {}".format(len(dets)))
for i, d in enumerate(dets):
    print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
        i, d.left(), d.top(), d.right(), d.bottom()))

# 画像に検出した顔の位置を重ね合わせて表示する
win.clear_overlay()
win.set_image(img)
win.add_overlay(dets)
for i in range(len(dets)):
    parts = predictor(img, dets[i]).parts()
    for point in parts:
        win.add_overlay_circle(point, 1)

dlibによる顔器官の検出 ~リアルタイム~

静止画について顔の検出および顔器官の検出をすることができたので,これをウェブカメラで撮影されたリアルタイムな映像に対しても行ってみます. 静止画に対して行った処理を1フレームごとに行っています. show_image(frame*0, parts)で背景を黒く塗りつぶしていますが,show_image(frame, parts)に変えることでカメラから受け取った映像の上に点をプロットできます.

dlibによる顔器官の検出 ~リアルタイム~


import dlib
import cv2
import numpy as np

detector = dlib.get_frontal_face_detector()
PREDICTOR_PATH = r"C:\dlib\python_examples\shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(PREDICTOR_PATH)

def show_image(img, parts):
    for i in parts:
        cv2.circle(img, (i.x, i.y), 3, (255, 0, 0), -1)

    cv2.imshow("dlib realtime", img)

cap = cv2.VideoCapture(0)
while True:
    # カメラ映像の受け取り
    ret, frame = cap.read()

    # detetorによる顔の位置の推測
    dets = detector(frame[:, :, ::-1])
    if len(dets) > 0:
        # predictorによる顔のパーツの推測
        parts = predictor(frame, dets[0]).parts()
        # 映像の描画
        show_image(frame*0, parts) # *0 を取り除くことでそのままの映像が表示されます

    # エスケープキーを押して終了します
    if cv2.waitKey(1) == 27:
        break

cap.release()
cv2.destroyAllWindows()

リアルタイム映像から顔器官の位置を推測することができました. 次回はリアルタイム映像から視線の向きを検出します.

<- 前へ戻る 【目次に戻る】 次へ進む ->