Hello Ys world ?

技術的なことや何か役立つこと、日々の活動を記録する

PythonでOpenCVを使った顔検出してみた

PythonOpenCVのカスケード型分類器を使った顔検出をしてみた。検索すれば顔検出のやり方とかプログラムはたくさんでてくるけど、とりあえず投稿しておく。 f:id:Ysss:20180731053658j:plain

はじめに

顔検出とは

顔検出(Face detection)は、画像や映像の中から、顔の位置を検出する技術である。近年話題のAIや機械学習を用いた顔認識は、たくさんある顔画像の中から特定の人間の顔を認識する技術である。

OpenCVとは

OpenCV(Open Source Computer Vision Library)はインテルが開発、公開したオープンソースC/C++JavaPythonMATLAB向けライブラリで、画像処理・画像解析および機械学習等の機能を持つ。

OpenCV 公式Webサイト opencv.org

OpenCV GitHubレポジトリ github.com

環境

自分の環境は以下の通りである。PythonはMinicondaのPython仮想環境を使用している

Windows10 Pro 64bit, version 1709

Python 3.6.5 (Miniconda3 4.5.1 64-bit)

準備

[ 1 ] ライブラリのインストール

Pythonがすでにインストールされている状態場合は、PythonOpenCVとmatplotlibをインポートできるようにする。

■ matplotlib

conda install matplotlib

OpenCV

conda install opencv

OpenCVのインストール完了時 f:id:Ysss:20180731042935p:plain

[ 2 ] 学習済み分類器データのダウンロード

学習済みカスケード型分類器データ(カスケードファイル)がOpenCVには用意されているので、それを使う。 以下のOpenCVGitHubレポジトリにカスケードファイルがあるのでダウンロードする。

github.com

正面の顔を検出してみるため、以下のURLのhaarcascade_frontalface_alt.xmlをダウンロードし、Pythonプログラムと同じディレクトリに保存した。OpenCVには、正面の顔の他に、目や鼻、横顔を検出するものもある。

https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_alt.xml

[ 3 ] プログラムの作成

import cv2
import matplotlib.pyplot as plt

# 画像読込み
origin_img = cv2.imread("a.jpg")
# 画像コピー
img = origin_img.copy()

# カスケードファイルのパス
cascade_path = "haarcascade_frontalface_alt.xml"
# カスケード分類器の特徴量取得
cascade = cv2.CascadeClassifier(cascade_path)

# 画像グレースケール化
grayscale_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# 顔検出
# minSize 最小サイズ指定
front_face_list = cascade.detectMultiScale(grayscale_img, minSize = (100, 100))

# 検出判定
print(front_face_list)
if len(front_face_list) == 0:
    print("Failed")
    quit()

# 検出位置描画
for (x,y,w,h) in front_face_list:
    print("[x,y] = %d,%d [w,h] = %d,%d" %(x, y, w, h))
    cv2.rectangle(img, (x,y), (x+w, y+h), (0, 0, 255), thickness=10)
     
# 顔検出画像表示
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
# 顔検出画像出力
cv2.imwrite("out.jpg", img)

# 検出画像出力
for (x,y,w,h) in front_face_list:
    face_img = origin_img[y:y+h, x:x+w]
    filename = "face_" + str(x) + "-" + str(y) + ".jpg"
    cv2.imwrite(filename, face_img)

実行結果

以下のNASAの記事にある画像を使って顔検出をした。検出を行う画像をプログラムと同じディレクトリに a.jpg というファイル名で保存した。

Vice President Pence Delivers Remarks to NASA Astronauts Candidates | NASA

NASAのメディア使用ガイドライン Media Usage Guidelines | NASA

■ 検出する画像 (NASA/Bill Ingalls) f:id:Ysss:20180731050905j:plain

■ プログラム実行時 f:id:Ysss:20180731050842p:plain

■ 検出した顔を出力 f:id:Ysss:20180731050845p:plain

まとめ

思ったより簡単に実装することができた。

参考