複数の写真から検出した人物を切り抜いて並べる
複数の写真から検出した人物を切り抜いて一つの画像に並べます。OpenCVの顔検出で顔の位置を特定しその上下左右を切り抜くことで人物を抽出します。顔検出はOpenCVに付属するHaar特徴ベースCascade型分類器による機械学習データ(検出器)のうち、正面の人の顔の機械学習データhaarcascade_frontalface_default.xmlを画像に適用することで行います。
関連記事
写真から顔検出をする(人間、猫)
顔にモザイクをかける
まちまちなサイズの複数の画像をきれいに並べて一枚の画像にまとめる
使った関数・メソッド
- cv2.imread : 画像ファイルの読み出し
- cv2.CascadeClassifier : 学習データの読みだし
- cv2.CascadeClassifier.detectMultiScale : オブジェクトを検出し検出範囲の矩形データ(x、y、幅、高さ)を返す
- cv2.resize : 画像サイズ変更
- cv2.imwrite : 画像をファイルに保存
環境
準備
人の写っている5枚の画像ファイルをフリー写真素材ぱくたそからダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリにフォルダ'pics'を作って保存しました。
また、正面の顔の特徴量学習データファイルhaarcascade_frontalface_default.xmlをjupyter notebookファイルと同じディレクトリにコピーしています。
コード
import os import numpy as np import cv2 # picsフォルダ内のファイルをリストに files = os.listdir('pics/') # 連結元の画像の作成 people = np.zeros((400, 1, 3), np.uint8) # 特徴量学習データhaarcascade_frontalface_default.xmlを読み込みface_cascadeに代入 face_cascade=cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # ファイルの数だけ繰り返す for i in files: # 画像ファイルの読み込み img = cv2.imread(i) # 画像に顔検出を適用 faces = face_cascade.detectMultiScale(img) # 検出した顔の数だけ、x,y,width,heightを取り出す for x, y, width, height in faces: # 人物部分を切り取る person = img[y-40:y+350, x-40:x+120] # 切り取った人物のサイズ height, width, ch = person.shape # 高さ400にリサイズ resize = cv2.resize(person, (int(width*400/height), 400)) # リサイズした画像をpeopleに連結 people = cv2.hconcat([people, resize]) # 画像を保存 cv2.imwrite('people.jpg', people)
実行結果
自動的に人物が切り抜かれ一枚の画像にまとめられました。
以下のサイトを参考にさせていただきました
Pythonの文法メモ >> 【OpenCV】画像サイズを変更するresize