face recognition with opencv and scikit-learn

14
OpenCV と scikit-learn で楽々顔認識 杜 世橋 FreeBit @lucidfrontier45 26, January, 2013

Upload: shiqiao-du

Post on 06-May-2015

17.241 views

Category:

Technology


9 download

DESCRIPTION

A lightweight implementation of Face Recognition system with Python. OpenCV and scikit-learn. Python, OpenCv, scikit-learnによる簡易な顔認識システムの実装. Tokyo.Scipy5にて発表。

TRANSCRIPT

Page 1: Face Recognition with OpenCV and scikit-learn

OpenCVと scikit-learnで楽々顔認識

杜 世橋 FreeBit@lucidfrontier45

26, January, 2013

Page 2: Face Recognition with OpenCV and scikit-learn

顔認識とは?

Face Detection

Face Recognition

Lena

画像から人の顔部分を抜き取る

与えられた顔の人物を推定する

Page 3: Face Recognition with OpenCV and scikit-learn

顔認識とは?Face Detection

Haar Cascade Classifier

Haar-like feature

Weak classifier

Weak classifier

Weak classifier

AdaBoost

原著論文は Paul Viola and Michael J. Jones. Rapid Object Detection using a Boosted Cascade of Simple Features. IEEE CVPR, 2001.日本語ではこちらのスライドがわかりやすい。

+

Page 4: Face Recognition with OpenCV and scikit-learn

顔認識とは?Face Recognition

EigenFaceInput PictureX (dim = d1 x d2)

PCA

Projected PictureY (dim = p < d1 x d2)

Nearest Neighbor orOther Supervised Prediction

* ちなみに PCA の代わりに Fisher 判別分析を使用した FisherFace やLPP を使用した LaplacianFace などもある。

M. Turk and A. Pentland (1991).“Face recognition using eigenfaces”.

http://scikit-learn.org/ より

Page 5: Face Recognition with OpenCV and scikit-learn

実装イメージFace RecognitionFace Detection

OpenCV

NumPy

SciPy

scikit-learn

Face Detection は OpenCV の CascadeClassifierモジュールを使用。Face Recognition は scikit-learn を用いて適当に実装。( 実は OpenCV にも )

Page 6: Face Recognition with OpenCV and scikit-learn

実装イメージ

Face Detection

import numpy as npimport cv, cv2

#画像ファイルを読み込んでモノクロ化&輝度を正規化img = cv2.imread(img_file) #imgはndarray型!gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)gray_img = cv2.equalizeHist(gray_img)

#顔検出器を作成cascade_file = “haarcascade_frontalface_default.xml" detector = cv2.CascadeClassifier(cascade_file)

Page 7: Face Recognition with OpenCV and scikit-learn

実装イメージ

Face Detection

#検出を実行flags = cv.CV_HAAR_FIND_BIGGEST_OBJECT | cv.CV_HAAR_DO_ROUGH_SEARCHTrects = detector.detectMultiScale(gray_img, scaleFactor=1.1, minNeighbors=3, minSize=(64, 64), flags=detact_flags)

#戻り値はxy座標、幅、高さ。OpenCVのndarrayは(y,x)の順なので注意x, y, w, h = rects[0]face = np.array(gray_img[y:y+h, x:x+w])

#後のためにリサイズして次元を統一しておくmin_size = (64, 64)face = cv2.resize(face, min_size, interpolation=cv.CV_INTER_AREA)

Page 8: Face Recognition with OpenCV and scikit-learn

実装イメージデータの型変換

def convImgMat(img, mat_type="opencv"): shape = img.shape #まずは32bit floatに変換 img = np.asanyarray(img, dtype=np.float32) if mat_type == "opencv" and len(shape) == 1: size = int(math.sqrt(img.size)) img = np.array(img.reshape((size, size)) * 255.0, dtype=np.uint8) #0-255を0-1に正規化し、1次元に展開する elif mat_type == "numpy" and len(shape) == 2: img = img.flatten() / 255.0 else: raise ValueError("wrong format") return img

OpenCV の関数は通常は 2 次元の 8bit int の配列を返してくる。顔認識に進む前に 32bit float の 1 次元配列に変換しておく。

Page 9: Face Recognition with OpenCV and scikit-learn

実装イメージFace Recognition( 学習編 )

import numpy as npfrom sklearn.decomposition import PCA

class FaceRecognizer():

def fit(face_imgs, labels)#トランスフォーマーを作成self.transformer = PCA(n_components=0.9)

#係数を学習self.transformer.fit(face_imgs)

#特徴量とラベルをセットself.features = self.transformer.transform(face_imgs)self.labels = np.array(labels)

Page 10: Face Recognition with OpenCV and scikit-learn

実装イメージFace Recognition( 予測編 )

from scipy.spatial import distance

class FaceRecognizer():…def predict(face_img)

#特徴量を計算feature = self.transformer.transform(face_imgs)

#距離を計算し、最も近いものを選ぶ distances = distance.cdist(self.features, [feature]).flatten()

idx = distances.argmin()

#もし距離がしきい値以上だったら未知人物を返すif distances[idx] > MAX_DISTANCE:

return UNKNOWN_PERSONelse:

return self.labels[idx]

Page 11: Face Recognition with OpenCV and scikit-learn

システム化今回作った顔認識システムの構成

-顔検出 Haar Cascade Classifier (OpenCV)-顔認識 LaplacianFace (scikit-learn独自レポジトリ )- DB Redis (redis-py経由 )- HTTPD Lighttpd (cgiは python)

学習した係数や顔画像、射影した特徴量はndarray としてRedis に保存。その際にはtostringメソッドで変換する。取り出すときには逆に np.fromstringを使用。

Page 12: Face Recognition with OpenCV and scikit-learn

システム化

追加学習時には LPP 係数は学習せず、射影した特徴量のみを計算して Redis に追加。

予測時には Redis から特徴量をすべて引っ張ってきて最近傍探索を行う。

精度はまだあまりよくない ...

Page 13: Face Recognition with OpenCV and scikit-learn

おわりおすすめの本Mastering Opencv with Practical Computer Vision Projects  Chapter 8 が OpenCV を利用した顔認識。性能を大きく左右する前処理についても詳しく解説されている。Android や iOS で OpenCV を利用したプログラム開発もある!

Page 14: Face Recognition with OpenCV and scikit-learn

おわり

今回使用作成したコード

LPP を実装した scikit-learn のレポジトリ ( そのうち本家にマージします )https://github.com/lucidfrontier45/scikit-learn/tree/lpp

PyFace レポジトリhttps://github.com/lucidfrontier45/PyFace