カメラ起動→顔、瞳検出し顔画像のみ抜き出す→性別判断→年代推測

#概要
UTKFaceデータセットを使って
・性別判断
・年代を推測（１０代、２０代、３０代...）
する学習モデルを作成しました。

環境が変わリまして
Google Colaboratory（GPU）　→　PyCharm (GCPのクラウドGPU)
にて学習モデルを作成しました。
Colaboratoryの超便利GPUが使えなくなってきたため、様々模索しこの形に。
この環境を作るのにかなり時間がかかりました。

これらを利用し、カメラに写った人物の顔画像のみを抜き出し、この画像を学習モデルにインプットし、その結果（性別と年代）をファイル名にして顔画像を保存していきます。
今回の処理はGPUを使わずに実行可能です。

```csharp
from tensorflow.python.keras.models import load_model

model = load_model('./Gender_judgment_model.h5', compile=False)
model_men = load_model('./men_Age_judgment_model.h5', compile=False)
model_women = load_model('./women_Age_judgment_model.h5', compile=False)


import cv2
import numpy as np

face_cascade_path = './opencv/haarcascade_frontalface_default.xml'
eye_cascade_path = './opencv/haarcascade_eye.xml'
face_cascade = cv2.CascadeClassifier(face_cascade_path)
eye_cascade = cv2.CascadeClassifier(eye_cascade_path)
```

作成した学習済モデル
Gender_judgment_model　性別を判定するモデル　男性は「０」、女性は「１」にて学習
men_Age_judgment_model　男性の年齢（年代）を導くモデル
women_Age_judgment_model　女性の年齢（年代）を導くモデル
１０代だと「０」、２０代だと「１」、３０代だと「２」、４０代だと「３」...にて学習
それぞれロードします。

また、OpenCVの評価器である
haarcascade_frontalface_default.xml　顔を検出してくれます
haarcascade_eye.xml　瞳を検出してくれます
これらを使用する準備をします。

```csharp
n = 0
eyes = None

cap = cv2.VideoCapture(0)
while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
```
カメラを起動し、まずは顔の検出を待ちます。
顔を検出しなければ何もしません。

```csharp
    for x, y, w, h in faces:
        facecut = img[y - 100: y + h + 100, x - 50: x + w + 50]
        face_gray = gray[y: y + h, x: x + w]
        eyes = eye_cascade.detectMultiScale(face_gray)
```
顔が検出されたら、顔の周辺を抜き出し、この画像から瞳の検出をします。

```csharp
        if len(eyes) != 0:
            for (ex, ey, ew, eh) in eyes:
                facecut2 = cv2.resize(facecut, (299, 299))
                facecut2 = np.asarray(facecut2)
                facecut2 = facecut2[None, ...]
                preds = model.predict(facecut2)
```
瞳が検出されたら、顔画像を性別判断モデルに合うサイズに変更しインプット、男性か女性か予測します。

```csharp
                facecut3 = facecut2.astype('float32') / 255
                if np.argmax(preds) == 0:
                    sex = "men"
                    preds2 = model_men.predict(facecut3)
                else:
                    sex = "women"
                    preds2 = model_women.predict(facecut3)
```
だんだん変数名が雑になってますm（_ _）m
先ほどのモデルが男性なら男性用の年代推測モデルに、女性なら女性用の推測モデルにインプットし、年代を予測します。

```csharp
                if preds2 < 0.8:
                    age = "10代"
                elif preds2 < 1.8:
                    age = "20代"
                elif preds2 < 2.8:
                    age = "30代"
                elif preds2 < 3.8:
                    age = "40代"
                elif preds2 < 4.8:
                    age = "50代"
                elif preds2 < 5.8:
                    age = "70代"
                elif preds2 < 6.8:
                    age = "80代"
                elif preds2 < 7.8:
                    age = "90代"
                cv2.imwrite('{}_{}.{}'.format('data/temp/' + sex + age , n, "jpg"), facecut)
                n += 1
                eyes = None
                cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
    cv2.imshow('video image', img)

    key = cv2.waitKey(10)
    if key == 27:  # ESCキーで終了
        break

cap.release()
cv2.destroyAllWindows()

```
性別、年代をファイル名として顔画像を指定のディレクトリに保存します。
これまでの処理はESCキーを押すまで続けられます。


検出し処理されたタイミングが分かるようにcv2.rectangleにて矩形を表示させるようにしています。