Python + dlibで顔検出

  • 13
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Python + dlibで顔検出

インストール

dlibを入れる前にCMAKE、Boost、Boost Python、G++他いろいろ必要

UbuntuでOpenCVとdlibを導入

dlibを用いたselective search

画像ファイルの入出力にOpenCV・scikit-imageあたりを入れる
今回はOpenCVを利用

コード

dlibでは顔っぽさのスコアを出せる
多少傾いていても検出してくれる感じがするので、回転させながら検出する場合でも回転角は45度ずつくらいでいいかもしれない
ある程度低いスコア(CUT_OFFの値)でスクリーニングをかけて、絞り込んだエリアを回転させながらスコアが高くなるように角度を調整してもいいかもしれないと思って試したけど、時間がかかりすぎる
検出結果に出てくるtypeは検出器の種類(顔が正面か横向きかとか?)に対応しているらしい
コメントアウトしたところは、検出した顔から68の特徴点を取り出してくれる
どの点が目・鼻・輪郭に対応しているとかわかるなら、もう少し改良できそう

detect_face.py
# -*- coding: utf-8 -*-

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os, sys, imghdr, shutil, dlib, cv2

CWD = os.getcwd()
DIR_ORIGIN = CWD + '/images/'
DIR_DESTINATION = CWD + '/faces/'
CUT_OFF = -0.1

detector = dlib.get_frontal_face_detector()
# predictor = dlib.shape_predictor('./shape_predictor_68_face_landmarks.dat')

def getFaces(path_full):
    results = []
    image = cv2.imread(path_full)
    height, width = image.shape[:2]
    rects, scores, types = detector.run(image, 1, CUT_OFF)
    for i, rect in enumerate(rects):
        top, bottom, left, right = rect.top(), rect.bottom(), rect.left(), rect.right()
        if min(top, height - bottom - 1, left, width - right - 1) < 0:
            continue
        results.append({
            'image'       : image[top : bottom, left : right],
            'score'       : scores[i],
            'orientation' : types[i]
        })
        # shape = predictor(image, rect)
        # for i in range(shape.num_parts):
        #     print(shape.part(i))
    return results

count = 1
for path, subdirs, files in os.walk(DIR_ORIGIN):
    for name in files:
            path_full = os.path.join(path, name)
            if imghdr.what(path_full) in ['jpeg']:
                faces = getFaces(path_full)
                for face in faces:
                    file_name = '{destination_dir}/{score}_{type}_{count}_dlib.jpg'.format(
                        destination_dir = DIR_DESTINATION,
                        score = face['score'],
                        type = int(face['orientation']),
                        count = count
                    )
                    cv2.imwrite(file_name, face['image'], [cv2.IMWRITE_JPEG_QUALITY, 100])
                    count += 1
                print(path_full)

参考サイト

chainerによるディープラーニングでAV女優の類似画像検索サービスをつくったノウハウを公開する

OpenCVとdlibを連携した顔検出プログラム

機械学習のライブラリ dlib

OpenFace 0.2.0: Higher accuracy and halved execution time

OpenCVとDlibとOpenFaceで顔検出をした知見まとめ

機械学習で用いる顔画像データセットの一作り方(3:候補画像から顔画像生成その1)