OpenCVを使って画像から顔の部分だけを切り取り保存するコードを書いたので備忘録として残しておきます。
環境
今回はPythonを使います。
- MacOS Mojave バージョン10.14.6
- Python 3.6.8
- opencv-python 4.1.1.26
準備
OpenCVのcascade分類器を使います。こちらからOpenCVをcloneしてきて、data/haarcascades
をコピーするのが早いと思います。今回は以下のような構造を想定します。
root/
┣ haarcascades/(opencvからコピーしてきたディレクトリ)
┣ target.jpg
┗ imgcut.py
画像はPAKUTASOから拾ってきたこちらのフリー画像を使用します。
コード
コードの全体は以下の通りです。一枚の画像から顔を切り出す処理になっています。複数の画像に対応させ少し使いやすくしたものをGitHubに置いていますのでこちらも参考にしてください。
import cv2
cascade = cv2.CascadeClassifier("./haarcascades/haarcascade_frontalface_default.xml")
img = cv2.imread("target.jpg")
face_pos = cascade.detectMultiScale(img)
for x,y,w,h in face_pos:
face = img[y:y+h, x:x+w]
cv2.imwrite("result.jpg", face)
コードの説明
OpenCVをインポートします。
import cv2
cascade分類器を読み込みます。今回は顔が正面を向いているのでhaarcascade_frontalface_default.xml
を使用します。
haarcascade_frontalface_default.xml
画像をndarrayに変換します。
img = cv2.imread("target.jpg")
cascade分類器を用いて顔の座標を特定します。
face_pos = cascade.detectMultiScale(img)
顔部分を切り取ります。座標は[[1003 135 196 196]]
のようになっており、左からx座標、y座標、幅、高さが入っています。複数の顔が見つかることもあります。
for x,y,w,h in face_pos:
face = img[y:y+h, x:x+w]
最後に画像を保存します。
cv2.imwrite("result.jpg", face)
実行結果
以下のコマンドで実行すると、result.jpgが生成されます。
python imgcut.py
上手くできたようです。なんとも言えない表情をしていますね。
感想・考察
今回はOpenCVを使って画像から顔だけを切り取る方法を書きました。モデルの学習など色々な場面で使えると思います。OpenCVすごいなと思いました。