Python+OpenCV|顔検出・顔認識と抽出する方法

こんにちは、βshortです。
今回の記事は、「PythonによるOpenCVで顔検出と抽出」です。

それでは、顔検出と抽出をしていきましょう。

PythonによるOpenCVで顔検出と抽出

Pythonの画像処理パッケージ「OpenCV」を利用して、人の画像から、顔を検出し、抽出していきます。
JupyterNotebookで、順番通りに実行することをおすすめします。
追加:顔画像の抽出を追加しました。

手順

以下の手順で、解説していきます。

  1. 画像を用意する
  2. 顔検出器を作る
  3. 実行する

画像を用意する

今回は、乃木坂46の生田絵梨花さんの画像を使い、顔検出を行います。
Pythonで、画像のあるURLからダウンロードします。
urllib.requestを使います。
以下のコードを実行すると、画像をダウンロードし、”test.jpg”で保存されます。


ソースコード

import urllib.request as req
url = "http://imgcc.naver.jp/kaze/mission/USER/20180519/35/3012705/157/500x718xedab7ba7e203cd7576d12004.jpg"
req.urlretrieve(url, "test.jpg")


使用画像



顔検出器を作る


元画像を表示させる

まずはじめに、先程ダウンロードした画像を表示させます。
ダウンロードした画像、つまり元画像をorigin_imgとします。
そして、顔検出用に元画像をimgにコピーしておきます。

顔検出で、cv2.rectangle()で顔部分を赤線で囲む処理をします。
代入で、画像を複製するだけだと、複製元の画像まで上書きされてしまいます。
未処理の画像を維持するために、copy()を用いて、コピーします。

origin_img = cv2.imread("test.jpg")
img = origin_img.copy()


ソースコード

import cv2
import matplotlib.pyplot as plt
%matplotlib inline

origin_img = cv2.imread("test.jpg")
img = origin_img.copy()
#plt.axis("off")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()


カスケードファイルを用意する

以下のリンクから、haarcascade_frontalface_alt.xmlをダウンロードし、プログラムファイルと同じディレクトリに移動させましょう。
カスケードファイル

カスケードファイルを利用して、検出器


ソースコード

#カスケードファイルを指定して、検出器を作成
cascade_file = "haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_file)
img_face = img

#画像の読み込んでグレースケール
img_gray = cv2.cvtColor(img_face, cv2.COLOR_RGB2GRAY)
#顔認識
face_list = cascade.detectMultiScale(img_gray, minSize = (150, 150))
#結果
if len(face_list) == 0:
    print("失敗")
    quit()
    
for (x,y,w,h) in face_list:
    print("顔の座標 = ", x, y, w, h)
    red = (0, 0, 255)
    cv2.rectangle(img_face, (x,y), (x+w, y+h), red, thickness=20)
    
#出力
plt.imshow(cv2.cvtColor(img_face, cv2.COLOR_BGR2RGB))
plt.show()


出力と保存

以上の手順で、以下の顔検出の画像が表示されたと思います。
いくちゃん可愛いですよね。。。

それは置いといて、最後にこの画像を保存します。

ソースコード

cv2.imwrite("out.jpg", img)


追加:顔画像の抽出

顔検出を実行した時、同時にxy座標も算出しました。
その座標の情報を使って切り取り、つまり顔画像の抽出を行います。

ソースコード

#切り取り
img_face_ex = origin_img[y:y+h, x:x+w]
plt.imshow(cv2.cvtColor(img_face_ex, cv2.COLOR_BGR2RGB))
plt.show()
#保存
cv2.imwrite("out_face.jpg", img_face_ex)

抽出した画像



注意

顔検出で、cv2.rectangle()で顔部分を赤線で囲む処理をします。
代入で、画像を複製するだけだと、複製元の画像まで全て、上書きされてしまいます。
未処理の画像を維持するために、copy()を用いて、コピーしておくことが必要です。

おわり


追加:横顔は苦手

カスケード(顔パーツのデータ)は、正面の顔検出用です。
なので、横顔の顔検出が苦手です。



参考書


すぐに使える! 業務で実践できる! Pythonによる AI・機械学習・深層学習アプリのつくり方

おすすめ