読者です 読者をやめる 読者になる 読者になる

Pythonの学習の過程とか

学習の記録をつけておきましょう。すぐ忘れるんだから。

Python OpenCVの基礎 ついに顔検出してみます

OpenCVでの顔検出

f:id:PeaceAndHiLight:20160218005019j:plain

やっとそれっぽいことを始めます。助走が長くてなかなかここまでたどり着きませんでしたね。

さてさて、OpenCVググると大体顔検出ってのが上位にきます。

ということなので、詳しいところを知りたい方はそちらをご覧いただくのがいちばんなのですが。。。。 とりあえず私も頑張ってチャレンジしてみますので、お暇なら読んでみてください。

顔検出の流れ

  1. 分類器の読み込み
  2. 画像読み込み
  3. BGR2GRAY変換
  4. 顔検出
  5. (おまけ)顔の部分を四角く描画

顔検出できた時点でOKなんですけど、座標で出してもいまいち分かりにくいので、みなさん顔枠を描画してらっしゃるようです。

ソースはこちら

OpenCV Face Detect

カスケード分類器

ここでカスケード分類器というモノが登場します。

こちらを参照してください

カスケード型分類器 — opencv 2.2 (r4295) documentation

ざっくり言うと、顔検出についてのいろんな情報が集まっていて、それを参照しながら画像を見てきましょう、という感じのものですね。 この精度により、顔が検出できたりできなかったりするみたいです。面白いですね。

分類器は、自分で作ることもできるようですし、それが必ずしも顔である必要はないみたいです。特定のモノ(ボールとか)を指定することもアリなんですね。

デフォルトで用意されている分類器を使ってみます。

で、その分類器をゼロから作るのは大変です(だと思います、作ったことないから分かりませんが、、) なので、OpenCVをインストールした時に一緒に付属してきた分類器を使ってみようと思います。

カスケード分類器の場所は

ここにあります。 opencv-2.4.9/data/haarcascades

22ファイルもありました。名前から色々と推測できますが、今回はhaarcascade_frontalface_default.xmlを使ってみます。

機会があれば、それぞれがどういう特徴を持っているのかを調べてみたいですね。

ファイルはxmlです。中身をちらっと見てみましたが、よくわからない。。。。この中身が何なのかはまた次の機会に。

ちなみにカスケード以外の分類器もあります。色々と勉強することが多いです。

ソースを詳しく見ていきましょう

#カスケード分類器を読み込む
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

cv2.CascadeClassifierでカスケード分類器を読み込む

こちらにCascadeClassifierの説明がありました。

Cascade Classification — OpenCV 2.4.12.0 documentation

Loads a classifier from a file.

cv2.CascadeClassifier([filename]) →

Parameters: filename – Name of the file from which the classifier is loaded.

要はカスケード分類器のファイルの中身を読み込んでくれているわけですね。

ここでは、faceCascadeにCascadeClassifierのオブジェクトが設定されました。

画像の読み込みとBGR2GRAY変換

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

グレイに変換したほうが処理が早いようです。変換しなくても処理はできますし、結果もあまり変わらないと思いますが(多分)、変換したうえで検出するのが一般的のようですね。

detectMultiScaleで検出処理

face = faceCascade.detectMultiScale(gray, 1.1, 3)

これでとりあえずはfaceに画像の中の顔情報が格納されているはずです。すごい便利ですね、これだけでいいなんて!

ちょっと詳細を見てみます。

CascadeClassifier::detectMultiScale

Python: cv2.CascadeClassifier.detectMultiScale(image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]]) → objects

ここで、imageはgrayを入れますが、あとの1.1と3は何でしょうか??

  • scaleFactor
  • minNeightbors

とりあえずまたここで調べました

Cascade Classification — OpenCV 2.4.12.0 documentation

ちょっと古い資料のようですが、日本語訳はここを参考にしました。

物体検出 — opencv v2.1 documentation

scaleFactor

Parameter specifying how much the image size is reduced at each image scale.

各画像スケールにおける縮小量を表します

minNeightbors

Parameter specifying how many neighbors each candidate rectangle should have to retain it.

物体候補となる矩形は,最低でもこの数だけの近傍矩形を含む必要があります

...よくわからないですね。。。ここは後回しにしましょう。すみません。

検出した顔について、顔枠の描画処理を行う

if len(face) > 0:
    for rect in face:
        cv2.rectangle(img, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), (0, 0,255), thickness=2)
else:
    print "no face"

すでに顔の検出はできましたので描画していきます。ここは特に解説の必要はないと思いますが、ついでなのできちんと抑えておきましょう。

rectangle

Drawing Functions — OpenCV 2.4.12.0 documentation

Draws a simple, thick, or filled up-right rectangle.

Python: cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) → None

Parameters:

 img – Image.

 pt1 – Vertex of the rectangle.

 pt2 – Vertex of the rectangle opposite to pt1 .

 color – Rectangle color or brightness (grayscale image).

 thickness – Thickness of lines that make up the rectangle. Negative values, like CV_FILLED , mean that the function has to draw a filled rectangle.

画像、枠の左上、枠の幅高、色、枠線の太さを指定すればいいんですね。

カスケード分類器を変えてみたら?

ちなみに分類器を変えてみたらどうなるでしょうか?

ソースはそのまま、分類器だけhaarcascade_eye.xmlに変更してみました。

はい、その結果がこれです

f:id:PeaceAndHiLight:20160218201553j:plain

顔は4人を全て性格に検出できたのに、目となるとこうなってしまいました。難しい画だとは思えないのですが。。。。

今回はこちらを参考にさせていただきました

大変勉強になりました。ありがとうございました。

www.takunoko.com

OpenCV: Face Detection using Haar Cascades