OpenCVで顔認識を行い、顔の部分だけトリミングして保存する【Python】
顔認識を行う
以下のソースで顔認識を行い、顔が認識された座標をコンソールに表示します。
解析する画像は実行時に引数として指定してください。
# -*- coding:utf-8 -*- import cv2 import sys import os import shutil args = sys.argv argc = len(args) if(argc != 2): print '引数を指定して実行してください。' quit() image_path = args[1] cascade_path = "/usr/local/opt/opencv/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" #ファイル読み込み image = cv2.imread(image_path) if(image is None): print '画像を開けません。' quit() #グレースケール変換 image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY) #カスケード分類器の特徴量を取得する cascade = cv2.CascadeClassifier(cascade_path) #物体認識(顔認識)の実行 facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.2, minNeighbors=2, minSize=(10, 10)) print "face rectangle" print facerect
以下の画像で実行すると、コンソールに6人分の座標が表示がされます。
face rectangle [[363 138 58 58] [435 196 54 54] [507 146 70 70] [295 171 57 57] [230 212 64 64] [126 141 74 74]]
ちゃんと6人とも認識されていることがわかります。
顔をトリミングして保存
次に、認識された顔の部分だけをトリミングして保存します。
先ほどのソースに以下のコードを追加してください。
#ディレクトリの作成 if len(facerect) > 0: path = os.path.splitext(image_path) dir_path = path[0] + '_face' if os.path.isdir(dir_path): shutil.rmtree(dir_path) os.mkdir(dir_path) i = 0; for rect in facerect: #顔だけ切り出して保存 x = rect[0] y = rect[1] width = rect[2] height = rect[3] dst = image[y:y+height, x:x+width] new_image_path = dir_path + '/' + str(i) + path[1]; cv2.imwrite(new_image_path, dst) i += 1
顔が一つ以上検出されれば、「元のファイル名_face」という名前のディレクトリが作成されます。
もともとその名前のフォルダがあれば一度全て削除してから再度ディレクトリを作り直すので注意してください。
その後、顔の数だけトリミングを行い、画像を保存しています。
ファイル名は0からの連番設定です。
先ほどの画像で実行すると、以下のような画像が得られます。
顔の部分だけ白枠をつける
ついでですが、顔の部分に白枠をつけて画像を保存する作業も行います。
先ほどのソースにさらに以下の文を追加してください。
if len(facerect) > 0: color = (255, 255, 255) #白 for rect in facerect: #検出した顔を囲む矩形の作成 cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2] + rect[2:4]), color, thickness=2) #認識結果の保存 new_image_path = dir_path + '/' +'all' + path[1] cv2.imwrite(new_image_path, image)
検出された顔の数だけ四角形を作成し、先ほど作ったディレクトリに「all」という名前で保存しています。
先ほどの画像で実行すると、以下のようになります。
コード
# -*- coding:utf-8 -*- import cv2 import sys import os import shutil args = sys.argv argc = len(args) if(argc != 2): print '引数を指定して実行してください。' quit() image_path = args[1] cascade_path = "/usr/local/opt/opencv/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml" #ファイル読み込み image = cv2.imread(image_path) if(image is None): print '画像を開けません。' quit() #グレースケール変換 image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY) #カスケード分類器の特徴量を取得する cascade = cv2.CascadeClassifier(cascade_path) #物体認識(顔認識)の実行 facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.2, minNeighbors=2, minSize=(10, 10)) print "face rectangle" print facerect #ディレクトリの作成 if len(facerect) > 0: path = os.path.splitext(image_path) dir_path = path[0] + '_face' if os.path.isdir(dir_path): shutil.rmtree(dir_path) os.mkdir(dir_path) i = 0; for rect in facerect: #顔だけ切り出して保存 x = rect[0] y = rect[1] width = rect[2] height = rect[3] dst = image[y:y+height, x:x+width] new_image_path = dir_path + '/' + str(i) + path[1]; cv2.imwrite(new_image_path, dst) i += 1 if len(facerect) > 0: color = (255, 255, 255) #白 for rect in facerect: #検出した顔を囲む矩形の作成 cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2] + rect[2:4]), color, thickness=2) #認識結果の保存 new_image_path = dir_path + '/' +'all' + path[1] cv2.imwrite(new_image_path, image)