【OpenCV,PIL,Python】顔認識,画像の貼り付け,resizeの入門サンプルコード。人の顔をニンニクにする。

顔認識には様々な方法がありますが、今回はOpenCVを使った顔検出。
OpenCVはオープンソースの画像(動画)ライブラリ。とても有名で、機械学習においても利用場面は多いです。

OpenCVには日本語版チュートリアルがあるので、読むとよいです。使い方がわかります。
こちらなども参考にしてほしいです→OpenCVとPythonによる機械学習プログラミング

画像のresize(リサイズ)やpaste(貼り付け)も行うので、PILを利用します。
Pillow(PIL)もドキュメントがあります→https://pillow.readthedocs.io/en/latest/

OpenCVでの顔認識にはカスケードファイルを使う

カスケードファイルというのは、「人間の顔はこういう特徴があるんですよ」という情報が詰まったファイルです。
顔認識、顔検出といっても正面の顔・笑顔・目や身体を把握するものなどがあります。

カスケードファイルは以下のGitHubリポジトリからダウンロードすることができます。
https://github.com/opencv/opencv/tree/master/data/haarcascades
ちなみに、今回のサンプルは正面の顔を対象にしています。
haarcascade_frontalface_alt.xmlというファイルしか使わないので、このファイル単体でダウンロードしてもよいです。

リンクはこちら→https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_alt.xml

リンクを開いたら、右クリックして、「別名で保存」を選択してください。そうするとダウンロードできます。

OpenCVのインストール方法

OpenCVはpipでインストールすることができます。

$ pip install opencv-python
$ pip3 install opencv-python

などお試しください。

Pillow(PIL)の使い方:今回は画像の貼り付け

Pillow(PIL)はPythonの画像処理ライブラリです。
Pythonで画像を扱う時にはよく使うライブラリです。

今回は人の顔を認識し、その顔の部分にニンニクを貼り付けるサンプルコードです。
OpenCVとPillow(PIL)のための入門用のサンプルコードなので、深層学習(ディープラーニング)などは利用しません。

Pillowもpipでインストールできる

$ pip install Pillow
$ pip3 install Pillow

などお試しください。

pipで今までに何をインストールしたかわからない時は

$ pip list
で今までpip installした一覧が出てきます。

OpenCVで顔認識、Pillow(PIL)で画像貼り付け

OpenCVでカスケードファイルを利用して、顔認識を行います。
画像のリサイズや加工などはOpenCVでもかなりできます。
今回は画像に画像を貼り付けること、透過PNGを使うことから、Pillow(PIL)を使用しています。

この画像が、

こうなります。

人の画像(大川さん)もニンニクの画像もフリー素材です。
ニンニクの画像は加工しております。テイク4で完成したので、ninniku4.pngという名前になっています。

入門用のサンプルコード

import cv2
from PIL import Image


# カスケードファイルを指定して、分類機を作成
cascade_file = "haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_file)

# 画像を読み込み、グレイスケールに変換
img = cv2.imread("ookawa.png")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 顔検出
face_list = cascade.detectMultiScale(img_gray, minSize=(150,150))
if len(face_list) == 0:
    quit()
print("face_list:",face_list)  # 2次元リストになっていることに注意

# わかりやすいように、face_listの値をまとめておく
x = face_list[0][0]  # X座標
y = face_list[0][1]  # Y座標
w = face_list[0][2]  # 横幅
h = face_list[0][3]  # 縦幅

# PILで画像を開く
im1 = Image.open('ookawa.png')
im2 = Image.open('ninniku4.png')

# 顔に合ったサイズにニンニク画像をリサイズする
im22 = im2.resize((w, h))
im22.save('ninniku4_1.png')

# 原本はそのままにしておくため、コピーを加工する
back_im = im1.copy()

# 背景透過のためのsplit()
back_im.paste(im22, (x, y), im22.split()[3])

# 保存する
back_im.save('ninniku_ookawa.png')

OpenCV,Pillow(PIL)の解説

たとえば、上記のPythonコードのファイルをninniku.pyにしたら、
そのファイルのディレクトリにhaarcascade_frontalface_alt.xml,ookawa.png,ninniku4.pngがなければなりません。
あるいは、別のディレクトリにあるなら、適切なパスを指定してください。

OpenCV、Pillow(PIL)を扱うために、冒頭でインポート。
今回、PILからはImageしか使わないので、Imageのみインポートしました。

コードの中のコメントを見てもらえればほとんどわかると思います。


まずはカスケードファイルを指定して、カスケード分類器を作ります。

画像の読み込みはグレースケールで行います(cv2.COLOR_BGR2GRAY)。画像処理系はグレースケールにすることが多いです。
画像情報を読み取るためには、必ずしも赤色や青色といったカラー情報は必要ありません。
あなたの家族や友人が白黒写真で写っているからといって、その人たちが判別できないなんていうことはありませんよね。
必要な特徴をグレースケールで読み取るほうが、余計な情報がなくて済むのです。

顔認識に成功すると、サンプルコードではface_listに画像の座標と大きさの情報が格納されています。
2次元のリストであることに注意してください。

顔認識をして座標と大きさを取得→その箇所に画像を貼り付け

という流れになります。


さて、次はPILの出番となります。
Image.open()で画像を取得します。そして、顔認識の時に取得した座標と大きさにニンニクの画像をリサイズします。
背景透過のためにsplit()[3]というオプションをpaste()メソッドに追加していることに注意してください。

ninniku4.pngという原本の画像はそのままにしておき、
この人の顔に載せるためのニンニク画像は別に保存しています(ninniku4_1.png)。

copy()メソッドも、原本を傷つけないためです。

画像の貼り付けはpaste()メソッドです。

こちらなども参考に→OpenCVとPythonによる機械学習プログラミング

物体・画像認識と時系列データ