以前、OpenCVを使って顔認識をしたのですが、dlibというライブラリを使うと顔の細かいパーツのランドマークが検出できると聞いたので試しに動かしてみました。




dlibのインストール


まずは事前準備をしていきます。

dlibのインストールは以下のコマンドで行うことができます。

pip install dlib

dlibのインストールができたら、dlibの公式サイトから学習済みモデルをダウンロードしましょう。



「shape_predictor_68_face_landmarks.dat.bz2 」というファイルが顔から68個のランドマークを検出する学習済みモデルです。

また、上記の物の他に処理が軽い学習済みモデルとし「shape_predictor_5_face_landmarks.dat.bz2 」という顔から68個のランドマークを検出するモデルがあります。

今回は「shape_predictor_68_face_landmarks.dat.bz2 」を使用していきます。





写真から顔のランドマークを検出する


dlibの準備ができたところで顔のランドマークを検出してみましょう。

今回学習済みモデルは実行ファイルと同じパスにおいています。

import dlib
from imutils import face_utils
import cv2

# 顔検出ツールの呼び出し
faceDetector = dlib.get_frontal_face_detector()

# 顔のランドマーク検出ツールの呼び出し
facePredictor = dlib.shape_predictor('shape_predictor_5_face_landmarks.dat')

# 検出対象の画像の呼び込み
img = cv2.imread('検出したい画像のパス')

# 顔検出
faces = faceDetector(img1)

# 検出した全顔に対して処理
for face in faces:
    # 顔のランドマーク検出
    landmark = facePredictor(imgface)
    # 処理高速化のためランドマーク群をNumPy配列に変換(必須)
    landmark = face_utils.shape_to_np(landmark)

    # ランドマーク描画
    for (i, (xy)) in enumerate(landmark):
        cv2.circle(img, (xy), 1, (25500), -1)

# 顔検出ファイルを出力
cv2.imwrite("dLibSample-output.PNG"img)

以下の画像を今回は入れてみました。

woman-1274056_1280

分かりにくいので顔部分をアップしますが確かにランドマークが検出されていますね。

キャプチャ

顔のランドマークの番号は以下のように1~68番まで割り当てられているみたいです。

figure_68_markup

https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/より


ちなみに「shape_predictor_5_face_landmarks.dat.bz2 」のモデルを使用した場合は以下のような出力になりました。

キャプチャ



まとめ


dlibを使って顔のランドマークを検出してみました。

ランドマーク検出って論文など見ていたら難しそうだというイメージがあったのですが今はこんなに便利なライブラリがあるんですね。

せっかくだからこのdlibを使ってなにかおもしろいソフトを作ってみたいですね。

OpenCVではうまくいかなかったface swapでも試してみようかな。