OpenCVで顔認証を行い、顔の画像のみをトリミングして保存する
OpenCVでは画像の変換に関するライブラリが非常に揃っています。このライブラリを使用することで、画像編集が苦手な方でも比較的容易に画像を編集することができます。また、画像認証のみならず、画像ファイルから顔認証や瞳検出を行うことができます。
OpenCVにて画像ファイルから顔認証や瞳検出を行う場合には、カスケード型分類器を使用します。カスケード型分類器はOpenCVのインストールに合わせてインストールされるため、特別な環境の設定は必要としません。カスケード型分類器を使用することで非常に簡単に顔の検出や笑顔の検出、目の部分のみの検出を行えるようになります。
これらで検出した結果を用いて、顔の周りを枠で囲ったり、顔の画像のみをトリミングして機械学習を行うなど、いろいろ応用することが出来るようになります。
オリジナルの画像(フリー画像)
こちらのフリー画像を元に顔認証を行っていきます。
白枠で顔を囲んだ画像
顔認証で検出した部分について白枠で囲っています。
顔の画像のみをトリミングした画像
顔の部分だけトリミングして切り取った結果です。
ソースコード
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 |
#OpenCVのインポート import cv2 #カスケード型分類器に使用する分類器のデータ(xmlファイル)を読み込み HAAR_FILE = "C:/Users/user/Anaconda3/pkgs/opencv3-3.1.0-py35_0/Library/etc/haarcascades/haarcascade_frontalface_default.xml" cascade = cv2.CascadeClassifier(HAAR_FILE) #画像ファイルの読み込み image_picture = "★画像ファイル" img = cv2.imread(image_picture) #グレースケールに変換する img_g = cv2.imread(image_picture,0) #カスケード型分類器を使用して画像ファイルから顔部分を検出する face = cascade.detectMultiScale(img_g) #顔の座標を表示する print(face) #顔部分を切り取る for x,y,w,h in face: face_cut = img[y:y+h, x:x+w] #白枠で顔を囲む for x,y,w,h in face: cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),2) #画像の出力 cv2.imwrite('face_cut.jpg', face_cut) cv2.imwrite('face_rectangle.jpg', img) |
ソースコードの詳細
OpenCVのインポート
1 2 |
#OpenCVのインポート import cv2 |
カスケード型分類器に使用する分類器のデータ(xmlファイル)を読み込み
1 2 3 |
#カスケード型分類器に使用する分類器のデータ(xmlファイル)を読み込み HAAR_FILE = "C:/Users/user/Anaconda3/pkgs/opencv3-3.1.0-py35_0/Library/etc/haarcascades/haarcascade_frontalface_default.xml" cascade = cv2.CascadeClassifier(HAAR_FILE) |
今回は顔検出を行いたいため、haarcascade_frontalface_default.xmlを指定します。
他にも以下のようなデータが存在します。
- haarcascade_smile.xml・・・笑顔検出
- haarcascade_eye.xml・・・目検出
- haarcascade_frontalface_default.xml・・・顔検出
分類器のデータはOpenCVをインストールしたディレクトリのライブラリ配下にあります。見当たらない場合は、以下のGIT-Hubのリポジトリからダウンロード可能です。
https://github.com/opencv/opencv/tree/master/data/haarcascades
画像ファイルの読み込み
1 2 3 |
#画像ファイルの読み込み image_picture = "★画像ファイル" img = cv2.imread(image_picture) |
グレースケールに変換する
1 2 |
#グレースケールに変換する img_g = cv2.imread(image_picture,0) |
カラースケールのみでも十分顔検出が可能ですが、グレースケールを使用することで高速に顔検出できると言われています。
ただ、実際に試してみた感じでは、カラースケールとグレースケールで検出時間や精度について差分は感じられなかったため、サイズが小さいデータであったり、少数枚程度ならば特にどちらでも良さそうでした。
カスケード型分類器を使用して画像ファイルから顔部分を検出する
1 2 |
#カスケード型分類器を使用して画像ファイルから顔部分を検出する face = cascade.detectMultiScale(img_g) |
顔の座標を表示する
1 2 |
#顔の座標を表示する print(face) |
顔部分を切り取る
1 2 3 |
#顔部分を切り取る for x,y,w,h in face: face_cut = img[y:y+h, x:x+w] |
白枠で顔を囲む
1 2 3 |
#白枠で顔を囲む for x,y,w,h in face: cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),2) |
(255,255,255)が白色で太さは2としています。
画像の出力
1 2 3 |
#画像の出力 cv2.imwrite('face_cut.jpg', face_cut) cv2.imwrite('face_rectangle.jpg', img) |
同じように、白枠で顔を囲んだ画像をface_rectangle.jpgとして保存しています。
機械学習やディープラーニングなどで顔の認識精度が上らないという場合は、顔の部分のみに特化して切り取ることで精度が上がる可能性があります。
いろいろ試してください。