Python + dlibで顔検出を行う

この記事のまとめ:
  • dlibをインストールする。
  • dlibに標準実装されているHOGアルゴリズムによる顔検出を試す。
背景:

前回、OpenCVのCascade分類器による顔検出を行いましたがあまり精度が良いものではなかったため、より良さそうなものとしてHOG (Histogram of Gradients)というアルゴリズムによる顔検出をdlibライブラリをを用いて試してみたいと思います。

dlibのインストール:

前回と同様にWindowsでAnaconda環境を使ったPython 3.5を前提に話をしていきます。 (参考:AnacondaディストリビューションでPythonの仮想環境を整える

condaを使って、dlibのインストールをします。また、skimageというライブラリも使用するためこれもインストールします。

  1. # conda install -c menpo dlib
  2. # conda install -c anaconda scikit-image
HOGアルゴリズムについて

細かいアルゴリズムは理解していないので詳細説明はできませんが、なんとなく私の理解を書いておきます。

写真データの各ピクセルに隣接するピクセルの明暗を比較して勾配情報(gradient)に変換します。そのままでは情報が大きすぎるため、検索対象の矩形内の勾配情報を16x16個のスクエアにとなるように分割して各スクエア内の勾配情報のヒストグラムを算出します。この16x16個のヒストグラムと学習済みの顔のヒストグラムを比較して、似通ったヒストグラムであれば顔と識別するもののようです。

下記にイメージ付きでもう少し詳しく説明がありますので詳細を知りたい方はこちらをご覧ください。

dlibのHOGアルゴリズムを使ってみる

顔検出を試すサンプルコードを以下に示します。なお、画像への顔と検出された矩形の書き込みとその画像の保存のためにOpen CVも使用しております。

  1. import sys
  2. import dlib
  3. from skimage import io
  4. import cv2
  5.  
  6. def face_detection(file_name):
  7. face_detector  = dlib.get_frontal_face_detector()
  8. image          = io.imread(file_name)
  9. detected_faces = face_detector(image, 1)
  10.  
  11. print("I found {} faces in the file {}".format(len(detected_faces), file_name))
  12.  
  13. save_image = cv2.imread(file_name, cv2.IMREAD_COLOR)
  14.  
  15. for i, face_rect in enumerate(detected_faces):
  16. print("- Face #{} found at Left: {} Top: {} Right: {} Bottom: {}".format(i, face_rect.left(), face_rect.top(), face_rect.right(), face_rect.bottom()))
  17. cv2.rectangle(save_image, tuple([face_rect.left(),face_rect.top()]), tuple([face_rect.right(),face_rect.bottom()]), (0, 0,255), thickness=2)
  18.  
  19. cv2.imwrite('HOG_'+file_name, save_image)
  20.  
  21. def main(argv):
  22. image_file = argv[1]
  23. face_detection(image_file)
  24.  
  25. if __name__ == '__main__':
  26.     main(sys.argv)
  27.  
結果

前回と同じ6枚の写真を使って評価してみました。

1枚目
完璧です!
2枚目
これまた完璧です!
3枚目
流石に後ろ向きよりの横顔は認識しませんが十分です!
4枚目
真横くらいの顔まで認識してくれていますね。
5枚目
OpenCVのCascade分類器では全く検出してくれなかったものでも幾つか検出してくれています。
6枚目
ここもほとんど検出してくれていますね。
最後に

すべての写真でOpenCVのCascade分類器よりも良い結果となったのではないでしょうか。 このあとはこれを使って人物認識をやっていこうかと思います。




今回は以上です。 最後まで読んでいただき、ありがとうございます。


ブログランキング・にほんブログ村へ  ← 気に入っていただければ応援ポチをお願いします!

コメント

  1. 画像はどのようにセットするのでしょうか。
    特定のフォルダに入れて、引数にそのパスをセットして実行すればいいですか。

    返信削除
  2. 返信が遅くなってすいません。
    はい、おっしゃるとおり、mainの引数として画像のファイルパスを渡せば良いです。

    返信削除
  3. ご確認ありがとうございます。
    画像ファイルパス(フルパス)を渡して
    実行しているのですが、
    なぜか対象のファイルの顔に線が描画されません。

    実行すると特にエラーが出るわけでもなく
    そのまま正常終了するようです。

    こちらで記載いただいているコードで
    インデントなどは当方で修正して実行しています。

    何が原因か分かりますでしょうか。

    返信削除
  4. 連続での投稿失礼いたします。
    ファイルパスの受渡しが上手くいっていなかったようで
    少し、中身を書き換えて実行したところ
    無事に処理が通りました。

    ご報告までm(_ _)m

    返信削除
  5. 無事に処理が通ってよかったです!
    もし私のサンプルコードに誤りなどあればご指摘いただければ幸いです。

    返信削除

コメントを投稿

このブログの人気の投稿

ネットワーク越しの RTL-SDR で SDR# を使う方法

LinuxでのnVidia GPUのオーバークロック・電力チューニング方法