TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

dlibの顔のパーツ検出をマンガで試してみた

前回の日記でサンプルで試した顔器官検出を、マンガの画像で試してみた。

学習データ準備

サンプルでは特徴点が68個あるが、入力するのが大変なので、顔の輪郭5点と左右の眼それぞれ4個ずつの13個とした。

前回説明した通り、imglabツール(前の日記参照)の引数に「--parts "00 01 …"」のように付与するラベルのリストを与えて起動する。

このような形で学習データの画像に点を打っていく。
f:id:TadaoYamaoka:20160923235615p:plain


入力に時間がかかるので、はじめ1ページのみで試したが全然だめだったので、数時間かけて10ページ分入力した。

学習

これを、サンプルの学習用スクリプトで学習する。

./train_shape_predictor.py images

10ページ分のデータで、学習に3分くらいかかった。

検出

学習データとは別の画像で、検出を行う。
サンプルのスクリプト(train_shape_predictor.py)を修正して、検出のみ行うスクリプト(predict_shape_predictor.py)を作成した。

predict_shape_predictor.py
#!/usr/bin/python
import os
import sys
import glob

import dlib
from skimage import io

if len(sys.argv) != 2:
    print(
        "Give the path to the examples/faces directory as the argument to this "
        "program. For example, if you are in the python_examples folder then "
        "execute this program by running:\n"
        "    ./train_shape_predictor.py ../examples/faces")
    exit()
faces_folder = sys.argv[1]

predictor = dlib.shape_predictor("predictor.dat")
detector = dlib.get_frontal_face_detector()

print("Showing detections and predictions on the images in the faces folder...")
win = dlib.image_window()
for f in glob.glob(os.path.join(faces_folder, "*.jpg")):
    print("Processing file: {}".format(f))
    img = io.imread(f)

    win.clear_overlay()
    win.set_image(img)

    dets = detector(img, 1)
    print("Number of faces detected: {}".format(len(dets)))
    for k, d in enumerate(dets):
        print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
            k, d.left(), d.top(), d.right(), d.bottom()))
        # Get the landmarks/parts for the face in box d.
        shape = predictor(img, d)
        print("Part 0: {}, Part 1: {} ...".format(shape.part(0),
                                                  shape.part(1)))
        # Draw the face landmarks on the screen.
        win.add_overlay(shape)

    win.add_overlay(dets)
    dlib.hit_enter_to_continue()

これを、検出対象の画像ファイル(.jpg)を格納したディレクトリを引数として実行する。

./predict_shape_predictor.py targets

特徴点の数を減らしているので、そのままだと表示でエラーになる。
前回説明した通り、特徴点13個の場合に表示できるようにdlibのソースを修正している。

結果

このような結果となり、全く検出できなかった。
f:id:TadaoYamaoka:20160923235724p:plain

一部目の位置が不正確だが顔の検出ができたものもあったが、ほとんど検出できていない。
f:id:TadaoYamaoka:20160924000157p:plain

考察

特徴点を減らしたことが原因か確認するために、サンプルの画像の特徴点を13個にして試してみた。

結果、サンプルでは特徴点を減らしても正しく検出できた。
f:id:TadaoYamaoka:20160924000440p:plain


アルゴリズムの詳細を理解していないのではっきりは言えないが、dlibの顔器官検出は、写真の場合はうまくいくが、モノクロのイラストの場合は有効ではなさそうである。

マンガの場合は、HOG特徴+SVMで顔検出を行った領域に対して、目などのパーツを同じくHOG特徴+SVMで検索するという方法の方が有効かもしれない。


ひと目ではマンガには使えない方法だと見抜けなかったよ。


2017/2/25追記
後日、DCNNを使用してマンガの顔パーツ検出に成功しました。
興味がございましたら、こちらの日記をご参照ください。