顔認識には様々な方法がありますが、今回は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というファイルしか使わないので、このファイル単体でダウンロードしてもよいです。
リンクを開いたら、右クリックして、「別名で保存」を選択してください。そうするとダウンロードできます。
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という名前になっています。
入門用のサンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
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による機械学習プログラミング
コメント
お世話になります。
2点質問です。
①物体検知
人の顔ではなく、絵柄の中の〇とか□の物体検知も上記プログラムの部分変更
によりできるのでしょうか? どうすればよいのでしょうか?
②物体の時のバウンディングボックス
上記プログラムの face_list[][] がそのボックスかと思いますが、1枚の
画像に対象物体が複数ある時は、それらの座標をリスト化しておいて引き出す
ということになるのでしょうか?
③物体の中心座標点
定義方法を教えていただけないでしょうか。