写真から顔検出をする(人間、猫)
写真から人間と猫の顔検出をします。OpenCVにはあらかじめいくつかのHaar特徴ベースCascade型分類器による機械学習データ(検出器)が付属しており、その学習データとオブジェクト検出関数を用いることで、顔検出が簡単に実現できます。
やること
- ファイル名を指定して画像ファイルを読み出す
- 顔、目などの特徴量を学習したデータの入ったXMLファイルを読み出し、画像ファイルからオブジェクト検出をする
- 検出したオブジェクトを元画像に重ね書きし別ウィンドウで表示する
- キー入力で表示用ウィンドウを破棄し終了
使った関数
- cv2.imread : 画像ファイルの読み出し
- cv2.imshow : 画像を別ウィンドウに表示する
- cv2.CascadeClassifier : 学習データの読みだし
- cv2.CascadeClassifier.detectMultiScale : オブジェクトを検出し検出範囲の矩形データ(x、y、幅、高さ)を返す
環境
準備
- 画像ファイルはフリー写真素材ぱくたそからダウンロードさせていただき、ファイル名"twins.jpg"で、jupyter notebookファイル(***.ipynb)と同じディレクトリに保存しました。
- 正面の顔の特徴量学習データファイルhaarcascade_frontalface_default.xmlはAnaconda3\Lib\site-packages\cv2\dataフォルダにありましたが、同様にjupyter notebookファイルと同じディレクトリにコピーしています。
コード
import cv2 fname = "twins.jpg" #画像ファイル名 img = cv2.imread(fname) #画像を読み出しimgに代入 #特徴量学習データhaarcascade_frontalface_default.xmlを読み込みface_cascadeに代入 face_cascade=cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #学習データを元にimgに対してオブジェクト検出し、検出したオブジェクトのx,y,幅、高さのリストをfacesに代入 faces=face_cascade.detectMultiScale(img) for x, y, width, height in faces: #オブジェクトの数だけ、x,y,width,heightを取り出す cv2.rectangle(img, (x, y), (x + width, y + height), (255, 255, 255), 2) #矩形をimg上に白で描画 cv2.imshow("faces",img) #別ウィンドウ"faces"を開きimgを表示 cv2.waitKey(0) #キー入力待ち cv2.destroyAllWindows() #ウインドウを閉じる
実行結果
顔が検出され検出部分に白い矩形が描かれます
猫の写真(cat.jpg)でも試してみます。
コード
画像ファイル名を変えるだけです。
import cv2 fname = "cat.jpg" #画像ファイル名 img = cv2.imread(fname) #画像を読み出しimgに代入 #特徴量学習データhaarcascade_frontalface_default.xmlを読み込みface_cascadeに代入 face_cascade=cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #学習データを元にimgに対してオブジェクト検出し、検出したオブジェクトのx,y,幅、高さのリストをfacesに代入 faces=face_cascade.detectMultiScale(img) for x, y, width, height in faces: #オブジェクトの数だけ、x,y,width,heightを取り出す cv2.rectangle(img, (x, y), (x + width, y + height), (255, 255, 255), 2) #矩形をimg上に白で描画 cv2.imshow("faces",img) #別ウィンドウ"faces"を開きimgを表示 cv2.waitKey(0) #キー入力待ち cv2.destroyAllWindows() #ウインドウを閉じる
実行結果
なにも検出されません。
opencvには猫の顔の特徴量学習データが用意されているので、そちらを使ってみます。
コード
'haarcascade_frontalcatface_extended.xml'に変更しています。
import cv2 fname = "cat.jpg" #画像ファイル名 img = cv2.imread(fname) #画像を読み出しimgに代入 #特徴量学習データhaarcascade_frontalcatface_extended.xmlを読み込みface_cascadeに代入 face_cascade=cv2.CascadeClassifier('haarcascade_frontalcatface_extended.xml') #学習データを元にimgに対してオブジェクト検出し、検出したオブジェクトのx,y,幅、高さのリストをfacesに代入 faces=face_cascade.detectMultiScale(img) for x, y, width, height in faces: #オブジェクトの数だけ、x,y,width,heightを取り出す cv2.rectangle(img, (x, y), (x + width, y + height), (255, 255, 255), 2) #矩形をimg上に白で描画 cv2.imshow("faces",img) #別ウィンドウ"faces"を開きimgを表示 cv2.waitKey(0) #キー入力待ち cv2.destroyAllWindows() #ウインドウを閉じる
実行結果
顔が検出されます。
以下のサイトを参考にさせていただきました
note.nkmk.me >> Python, OpenCVで顔検出と瞳検出(顔認識、瞳認識)
OpenCV-Python Tutorials >> Haar Cascadesを使った顔検出