pythonでOpenCVを使った顔検出
OpenCVを使って顔検出をしてみる
今回はサッカー選手メッシの画像でトライしてみた
参考
bing image search APIを使ってみた - ヘビ夫のプログラミング備忘録
OpenCVを使った顔検出(番外編) - ヘビ夫のプログラミング備忘録
サッカー選手の顔画像を分類してみた - ヘビ夫のプログラミング備忘録
事前準備
ひとつひとつ画像を保存して収集することも可能だが、あまりに面倒くさいので
bingAPIを使ってメッシの画像を一括で収集する。
なお画像は採番して./save/messiディレクトリに保存しておく
bingAPIを使った画像の収集方法は以下参照
programdl.hatenablog.com
ソース
実行
python obj_detect.py ./save/messi/
第2引数には画像の格納されるディレクトリを指定
カレントディレクトリにはhaarcascadesディレクトリを格納すること(後述)
実装
検出の実装以下のとおり
obj_detect.py
import cv2 import numpy as np import sys import os def make_dir(path): if not os.path.isdir(path): os.mkdir(path) input_data_path = sys.argv[1] save_dir_path = sys.argv[1]+"face/" detect_dir_path = sys.argv[1]+"detect/" make_dir(save_dir_path) make_dir(detect_dir_path) cascade_path = './haarcascades/haarcascade_frontalface_default.xml' cascade = cv2.CascadeClassifier(cascade_path) image_count = 30 detect_count = 0 for i in range(image_count): img = cv2.imread(input_data_path + '{0:03d}'.format(i) + '.jpg', cv2.IMREAD_COLOR) try: gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) except: #ファイルがなければ次のファイルへ print("Not found:"+input_data_path + '{0:03d}'.format(i) + '.jpg') continue #scaleFactor – 各画像スケールにおける縮小量 #minNeighbors – 信頼度に関するパラメーター target = cascade.detectMultiScale(gray, scaleFactor=1.1,minNeighbors= 40) if len(target) > 0: for rect in target: #対象区間を赤線で囲み保存 cv2.rectangle(img, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), (0, 0,255), thickness=1) cv2.imwrite(detect_dir_path + '{0:03d}'.format(i) +'.jpg', img) #対象区間を切り取り保存 x = rect[0] y = rect[1] w = rect[2] h = rect[3] cv2.imwrite(save_dir_path + '{0:03d}'.format(i) + '.jpg', img[y:y+h, x:x+w]) print(save_dir_path + '{0:03d}'.format(i) + '.jpg') detect_count = detect_count + 1 else: print('image' + '{0:03d}'.format(i) + ':No Target')
./save/messi/detect
./save/messi/face
にそれぞれ画像を出力
注意1 分類器
cascade_path = './haarcascades/haarcascade_frontalface_default.xml' cascade = cv2.CascadeClassifier(cascade_path)
検出について、CascadeClassifierで設定を行う
何を検出したいかによって指定すべきxmlファイルが違うので注意
今回自作は避け、opencvで提供されるxmlファイルhaarcascade_frontalface_default.xmlを使用した
入手方法は以下の通り
$ wget https://github.com/Itseez/opencv/archive/3.1.0.zip
解凍後、opencv-3.1.0/data/haarcascadesを作業ディレクトリにコピー なおhaarcascadesディレクトリ配下にはxmlファイルが複数格納されている
$ cd opencv-3.1.0/data/haarcascades $ ls haarcascade_eye.xml haarcascade_eye_tree_eyeglasses.xml haarcascade_frontalcatface.xml haarcascade_frontalcatface_extended.xml haarcascade_frontalface_alt.xml haarcascade_frontalface_alt2.xml haarcascade_frontalface_alt_tree.xml haarcascade_frontalface_default.xml haarcascade_fullbody.xml haarcascade_lefteye_2splits.xml haarcascade_licence_plate_rus_16stages.xml haarcascade_lowerbody.xml haarcascade_profileface.xml haarcascade_righteye_2splits.xml haarcascade_russian_plate_number.xml haarcascade_smile.xml haarcascade_upperbody.xml
haarcascade_eye.xmlは目の検出
haarcascade_fullbody.xmlは体の検出
と言った感じで、何を検出したいかによって、ファイルの指定を変更する必要がある
opencv以外にも各個人がxmlファイルを公開していたりするので是非利用したい
注意2 認識精度のチューニング
#scaleFactor – 各画像スケールにおける縮小量 #minNeighbors – 信頼度に関するパラメーター target = cascade.detectMultiScale(gray, scaleFactor=1.1,minNeighbors=40)
minNeighborsの値をいくつにするかで、検出結果が異なってくるので注意
対象とする画像セットごとに随時変更する必要がある。
minNeighbors=3
少しわかりにくいが、メッシの顔の他、胸中央のエンブレム、背景の顔の3つを検出している
minNeighbors=40
メッシのみを検出している
よって今回は minNeighbors=40を採用した
結果
メッシの顔の検出に成功
ただし、一部ご認識があるため今後どのように扱うか検討
その他