LoginSignup
2
3

More than 3 years have passed since last update.

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

Last updated at Posted at 2021-02-18

概要

UTKFaceデータセットを使って
・性別判断
・年代を推測(10代、20代、30代...)
する学習モデルを作成しました。

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

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

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 性別を判定するモデル 男性は「0」、女性は「1」にて学習
men_Age_judgment_model 男性の年齢(年代)を導くモデル
women_Age_judgment_model 女性の年齢(年代)を導くモデル
10代だと「0」、20代だと「1」、30代だと「2」、40代だと「3」...にて学習
それぞれロードします。

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

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)

カメラを起動し、まずは顔の検出を待ちます。
顔を検出しなければ何もしません。

    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)

顔が検出されたら、顔の周辺を抜き出し、この画像から瞳の検出をします。

        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)

瞳が検出されたら、顔画像を性別判断モデルに合うサイズに変更しインプット、男性か女性か予測します。

                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
先ほどのモデルが男性なら男性用の年代推測モデルに、女性なら女性用の推測モデルにインプットし、年代を予測します。

                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にて矩形を表示させるようにしています。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3