Python + dlibで顔検出
インストール
dlibを入れる前にCMAKE、Boost、Boost Python、G++他いろいろ必要
画像ファイルの入出力に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女優の類似画像検索サービスをつくったノウハウを公開する
OpenFace 0.2.0: Higher accuracy and halved execution time