【顔認識入門】haar cascadesで遊んでみた♪

今日は、今更感があるが「ウワンさんこんにちわ」と言ってほしくて、まず顔認識で遊んでみた。
Opencvのhaar cascadesを使った顔認識やってみた。
コードは、最初は参考②のものが見やすいので、まんま利用させていただいた。
解説は参考①が詳しい。
【参考】
①[【入門者向け解説】openCV顔検出の仕組と実践(detectMultiScale)](https://qiita.com/FukuharaYohei/items/ec6dce7cc5ea21a51a82)
②[python+OpenCVで顔認識をやってみる](https://qiita.com/wwacky/items/98d8be2844fa1b778323)
####やったこと
・とりあえず動かしてみる
・動画に適用する
###・とりあえず動かしてみる
上記の参考コードをとりあえず、動かしてみました。
その結果、以下のような画像が得られます。

| 元画像 ||生成画像|
|:-:|:-:|:-:|
|![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/37f5f99c-09a4-c1d2-aaca-7089c898ed01.jpeg)|➡| ![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/00203f93-9552-919b-e5b9-5b07ca9ebf3c.jpeg)|
###・動画に適用する
Opencvには以下のような動画適用がありますが、ちょっと読みにくいコードなので、上記の簡単な静止画アプリを改変することとする。
[opencv/samples/python/facedetect.py](https://github.com/opencv/opencv/blob/master/samples/python/facedetect.py)
その結果、以下のようなコードを作成できる。
[face_recognition/face_recognition_doga.py](https://github.com/MuAuan/face_recognition/blob/master/face_recognition_doga.py)

####コード解説
利用するLibはcv2とtimeだけです。

```py
import cv2
from time import sleep
```
以下は顔認識に利用するxmlです。そして、動画のためのfourccを定義します。

```py
cascade_path = "./models/haarcascade_frontalface_default.xml"

def cv_fourcc(c1, c2, c3, c4):
        return (ord(c1) & 255) + ((ord(c2) & 255) << 8) + \
            ((ord(c3) & 255) << 16) + ((ord(c4) & 255) << 24)
```
cascade分類器を定義します。

```py
def main():
    #カスケード分類器の特徴量を取得する
    cascade = cv2.CascadeClassifier(cascade_path)
    color = (255, 255, 255) #白
```
動画のファイル名等を定義する。

```py
    OUT_FILE_NAME = "./outputs/face_recognition.avi"
    FRAME_RATE=1
    w=224 #1280
    h=224 #960
    out = cv2.VideoWriter(OUT_FILE_NAME, \
          cv_fourcc('M', 'P', '4', 'V'), \
          FRAME_RATE, \
         (w, h), \
         True)    
```
カメラ入力を定義

```py
    cap = cv2.VideoCapture(1)
    is_video = 'False'
    s=0.1
```
動画は１フレームずつ撮影保存しています。
fpsを計測して、動画に貼り付けます。

```py
    while True:
        timer = cv2.getTickCount()
        ret, frame = cap.read()
        sleep(s)
        fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer);
        # Display FPS on frame
        cv2.putText(frame, "FPS : " + str(int(1000*fps)), (100,50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50,170,50), 2);
```
取得した画像をグレースケールに変換して、それに基づいて顔検出を行います。

```py
        #グレースケール変換
        image_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        #image_gray = cv2.equalizeHist(image_gray)
        facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30))
```
検出した顔に合わせて矩形を作成し、frameに貼り付けます。

```py
        if len(facerect) > 0:
            #検出した顔を囲む矩形の作成
            for rect in facerect:
                cv2.rectangle(frame, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), color, thickness=2)
```
frameを表示します。

```py
        cv2.imshow('test',frame)
```
動画に一枚ずつ保存していきます。

```py
        key = cv2.waitKey(0)&0xff
        if is_video=="True":
            img_dst = cv2.resize(frame, (int(224), 224))
            out.write(img_dst)
            print(is_video)
```
以下のキー入力で動画のfpsを変更できます。
あるいは、qで終了します。

```py
        if key == ord('q'):
            #cv2.destroyAllWindows()
            break
        elif key == ord('p'):
            s=0.5
            is_video = "True"
        elif key == ord('s'):
            s=0.1
            is_video = "False"    
if __name__ == '__main__':
    main()
```
###結果
上記のコードで一応顔認識しつつ動画が動きました。
ちょうと映っていたTVの画面の中の顔認識をしてくれました。
[face recognition](https://youtu.be/Fi4eeY4UK1Q)
<a href="http://www.youtube.com/watch?feature=player_embedded&v=Fi4eeY4UK1Q" target="_blank"><img src="http://img.youtube.com/vi/Fi4eeY4UK1Q/0.jpg"  </a>
※画像をクリックするとYouTube動画につながります
###まとめ
・haar cascadesを動かしてみた
・動画像に対して顔認識してみた

・顔認識しつつ人物認識を実施したい