Avance.Lab

技術紹介

第8回 顔認識デバイス Raspberry Pi 4B編 〜画像解析(年齢/性別推定)編 〜

公開日:2022.03.11 更新日:2022.03.11

tag: Raspberry PiIoT

こんにちは!

Kです。

いよいよ最終回となりました。

前回カメラ画像から顔の画像だけを別途保存する処理をしましたが、そこからDNNを使った性別と年齢推定を行う処理を解説します。

前提知識としてOpenCV2ではDNN(Deep Neural Network)Moduleを使用してディープラーニングによる物体推定を行う事ができます。用意するデータはAIの重みづけファイルとDNNのAI構成ファイルが必要です。

それぞれAIフレームワーク(Tensor Flow,Caffe, DarkNet)によって呼び方が少し変わってきます。この辺りはOpenCVの紹介サイトにて解説されていますのでそちらを参照ください。

https://learnopencv.com/deep-learning-with-opencvs-dnn-module-a-definitive-guide/

AI のデータセットにはAdienceのデータセットを使います。下記ページを辿っていきますとダウンロードする事ができます。

https://github.com/spmallick/learnopencv/tree/master/AgeGender

実装自体は比較的簡単で、readNetにデータモデルと構成ファイルを読み込むだけ。

# Load network
ageNet = cv2.dnn.readNet(ageModel, ageProto)
genderNet = cv2.dnn.readNet(genderModel, genderProto)
faceNet = cv2.dnn.readNet(faceModel, faceProto)

実際の解析処理を見ていきます。

MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)
ageList = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']
genderList = ['Male', 'Female']

def analyze_agegender():
  global analyzing_agegender
  global face_images
  global agegenders_fordisplay
  global over

  while analyze_agegender_alive:
    if spp.agegenderdetect == 1:
      if face_images is not None:
        analyzing_agegender = True
        agegenders = []

        for face_image in face_images:
          blob = cv2.dnn.blobFromImage(face_image, 1.0, (227, 227), MODEL_MEAN_VALUES, swapRB=False)
          genderNet.setInput(blob)
          genderPreds = genderNet.forward()
          gender = genderList[genderPreds[0].argmax()]
          print("Gender : {}, conf = {:.3f}".format(gender, genderPreds[0].max()))
          ageNet.setInput(blob)
          agePreds = ageNet.forward()
          age = ageList[agePreds[0].argmax()]
          print("Age Output : {}".format(agePreds))
          print("Age : {}, conf = {:.3f}".format(age, agePreds[0].max()))
          agegenders.append((gender, age))

        del face_images
        face_images = []

        # agegenders_fordisplay = agegenders
        if agegenders_fordisplay is None:
          agegenders_fordisplay = agegenders
        else:
          for agegender in agegenders:
            # 直前のものと同じ場合は追加しない
            count = len(agegenders_fordisplay)
            if count > 0:
              if agegender == agegenders_fordisplay[count-1]:
                continue

            #
            agegenders_fordisplay.append(agegender)

            # 最大数を超過した場合は先頭を削除する
            if count > 30:
              agegenders_fordisplay.pop(0)
              over += 1

        analyzing_agegender = False
      # else:
      #   agegenders_fordisplay = None
    else:
      agegenders_fordisplay = None

    time.sleep(0.1)

19行目に顔の切り出し画像を入力します。DNNの推定精度を高くする意図があるため、このまま使用します。

性別推定クラス(genderNet)に画像を入力することで、推定候補がいくつか出てきます。forwardを取り出すことで最有力候補を取得できます。

また、後段の年齢推定も同様の処理が続きます。

如何でしたでしょうか?

スマートフォンアプリから遠隔操作しつつ、顔認識からカメラの首振りとその顔の性別/年齢推定を行う一連の動作を説明して来ました。

AI開発や小型PCなどが一般でも入手しやすくなったことで、Web検索だけでもこのような情報が手に入るようになりました。セキュリティの観点からまだまだ敷居が高いと思いますが、それもまたネットワークインフラが整って来つつあるので業務ベースで応用出来ることも難しい話ではないのかも知れません。

実際にご覧になりたい場合はぜひ弊社にお問い合わせください!

ではまた別のシリーズにてお会いしましょう!

K
K

クラウド,IoT,小型PC,スマートフォンなど環境問わず担当しています。
最近はROS2に興味があります。

関連記事