金子邦彦研究室人工知能人工知能の実行(Python を使用)(Windows 上)Dlib を用いて,顔検出,顔のランドマーク検知(68 ランドマーク法),表情判定を行う(Windows 上)

Dlib を用いて,顔検出,顔のランドマーク検知(68 ランドマーク法),表情判定を行う(Windows 上)

目次

  1. 前準備
  2. Dlib のインストールと関連ファイルのダウンロード
  3. ezgiakcora/Facial-Expression-Keras のインストール

サイト内の関連ページ

説明資料: Dlib の機能概要 [PDF], [パワーポイント]

関連する外部ページ

dlib の Web ページ: http://dlib.net/

前準備

Git のインストール(Windows 上)

Gitは,バージョン管理システム.ソースコードの管理や複数人での共同に役立つ.

サイト内の関連ページ

Windows での Git のインストール: 別ページ »で説明している.

関連する外部ページ

Git の公式ページ: https://git-scm.com/

7-Zip のインストール(Windows 上)

7-Zipは,ファイル圧縮・展開(解凍)ツール

  1. Windows で,コマンドプロンプト管理者として実行

    コマンドプロンプトを管理者として実行: 別ページ »で説明

  2. 次のコマンドを実行

    次のコマンドは,7-Zip圧縮・展開(解凍)ツールをインストールするものである.

    winget install --scope machine 7zip.7zip
    powershell -command "$oldpath = [System.Environment]::GetEnvironmentVariable(\"Path\", \"Machine\"); $oldpath += \";c:\Program Files\7-Zip\"; [System.Environment]::SetEnvironmentVariable(\"Path\", $oldpath, \"Machine\")"
    

関連する外部ページ

Python のインストール(Windows 上)

サイト内の関連ページ

関連する外部ページ

Python の公式ページ: https://www.python.org/

Build Tools for Visual Studio 2022 (ビルドツール for Visual Studio 2022),Visual Studio 2022 のインストール(Windows 上)

Build Tools for Visual Studio 2022(ビルドツール for Visual Studio 2022)のインストールは,Visual Studio を使う予定がある場合(よく分からない場合を含む)と,使う予定がない場合(使う予定が無いことが確実な場合)で方法が分かれる.

Dlib のインストールと関連ファイルのダウンロード

Dlib および関連ソフトウェアのインストール

  1. Windows で,コマンドプロンプト管理者として実行

    Windowspip を実行するときは,コマンドプロンプト管理者として開き,それを使って pip を実行することにする.

    コマンドプロンプトを管理者として実行: 別ページ »で説明

  2. 次のコマンドを実行する.
    python -m pip install --ignore-installed -U dlib imutils numpy==1.23.4
    

Dlib 関連ファイルのダウンロード

  1. Windows で,コマンドプロンプト管理者として実行

    コマンドプロンプトを管理者として実行: 別ページ »で説明

  2. Dlib のソースコード等のダウンロード

    次のコマンドを実行.

    cd C:\
    rmdir /s /q dlib
    git clone https://github.com/davisking/dlib
    
  3. Dlib の学習済みモデルのダウンロード

    次のコマンドを実行.

    cd C:\dlib
    cd python_examples
    curl -O http://dlib.net/files/mmod_human_face_detector.dat.bz2
    curl -O http://dlib.net/files/dlib_face_recognition_resnet_model_v1.dat.bz2
    curl -O http://dlib.net/files/shape_predictor_5_face_landmarks.dat.bz2
    curl -O http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
    "c:\Program Files\7-Zip\7z.exe" x mmod_human_face_detector.dat.bz2
    "c:\Program Files\7-Zip\7z.exe" x dlib_face_recognition_resnet_model_v1.dat.bz2
    "c:\Program Files\7-Zip\7z.exe" x shape_predictor_5_face_landmarks.dat.bz2
    "c:\Program Files\7-Zip\7z.exe" x shape_predictor_68_face_landmarks.dat.bz2
    del mmod_human_face_detector.dat.bz2
    del dlib_face_recognition_resnet_model_v1.dat.bz2
    del shape_predictor_5_face_landmarks.dat.bz2
    del shape_predictor_68_face_landmarks.dat.bz2
    

ezgiakcora/Facial-Expression-Keras のインストール

GitHub の ezgiakcora/Facial-Expression-Keras で公開されているプログラムを試してみる. これは Dlibを使う表情認識のプログラムである

  1. Windows で,コマンドプロンプト管理者として実行

    コマンドプロンプトを管理者として実行: 別ページ »で説明

  2. インストール
    cd %HOMEPATH%
    rmdir /s /q Facial-Expression-Keras
    

    [image]

    cd %HOMEPATH%
    git clone https://github.com/ezgiakcora/Facial-Expression-Keras
    cd Facial-Expression-Keras
    

    [image]
  3. Dlib 関連のファイルをコピーして使う
    cd %HOMEPATH%\Facial-Expression-Keras
    copy C:\dlib\python_examples\shape_predictor_68_face_landmarks.dat .
    

    [image]
  4. 表情判定のプログラムを動かしてみる

    USB接続できるビデオカメラを準備し,パソコンに接続しておく.

    1. Windowsコマンドプロンプトを開く
    2. Python プログラムの実行

      Python プログラムの実行: 別ページ »で説明

      Python のまとめ: 別ページ »にまとめ

      コマンドプロンプトで次を実行

      cd %HOMEPATH%\Facial-Expression-Keras
      python demo.py 
      

      [image]

      [image]

      ※ 途中で止めたいとき,右上の「x」をクリックしない.画面の中をクリックしてから,「q」のキーを押して閉じる

    3. demo.py を少し書き変えて動かす
      import numpy as np
      import cv2
      from tensorflow.keras.preprocessing import image
      import dlib
      from imutils import face_utils
      import imutils
      from sklearn import preprocessing
      import math
      from keras.models import model_from_json
      #-----------------------------
      #opencv initialization
      face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
      cap = cv2.VideoCapture(0)
      
      #-----------------------------
      #face expression recognizer initialization
      # Using pretrained model
      model = model_from_json(open("model/model.json", "r").read())
      model.load_weights('model/model.h5') #load weights
      
      #-----------------------------
      
      emotions = ( 'Angry' , 'Disgust' , 'Fear' , 'Happy'  , 'Neutral' ,  'Sad' , 'Surprise')
      # initialize dlib's face detector and create a predictor
      detector = dlib.get_frontal_face_detector()
      predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
      
      
      def detect_parts(image):
          distances = []
          # resize the image, and convert it to grayscale
          image = imutils.resize(image, width=200, height=200)
          
          gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
          # detect faces in the grayscale image
          rects = detector(gray, 1)
          
          # loop over the face detections
          for (i, rect) in enumerate(rects):
              shape = predictor(gray, rect)
              shape = face_utils.shape_to_np(shape)
              distances = euclidean_all(shape)
              # visualize all facial landmarks with a transparent overlay
              #output = face_utils.visualize_facial_landmarks(image, shape)
              #cv2.imshow("Image", output)
              #cv2.waitKey(0)    
          return distances
      
      def euclidean(a, b):
          dist = math.sqrt(math.pow((b[0] - a[0]), 2) + math.pow((b[1] - a[1]), 2))
          return dist 
      
      # calculates distances between all 68 elements
      def euclidean_all(a):  
          distances = ""
          for i in range(0, len(a)):
              for j in range(0, len(a)):
                  dist = euclidean(a[i], a[j])
                  dist = "%.2f" % dist;
                  distances = distances + " " + str(dist)
          return distances
      
      
      def box_label(bgr, x1, y1, x2, y2, label): 
          cv2.rectangle(bgr, (x1, y1), (x2, y2), (255, 0, 0), 1, 1)
          cv2.rectangle(bgr, (int(x1), int(y1-25)), (x2, y1), (255,255,255), -1)
          cv2.putText(bgr, label, (x1, int(y1-5)), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0,0,0), 1)
      
      
      while(True):
          ret, img = cap.read()
          gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
          faces = face_cascade.detectMultiScale(gray, 1.3, 5)
          for (x,y,w,h) in faces:
              detected_face = img[int(y):int(y+h), int(x):int(x+w)] #crop detected face
              distances = detect_parts(detected_face)
              if(len(distances)!=0):
                  val = distances.split(" ")[1:]
                  val = np.array(val)
                  val = val.astype(np.float)
                  val = np.expand_dims(val, axis = 1)            
                  minmax = preprocessing.MinMaxScaler()
                  val = minmax.fit_transform(val)
                  val = val.reshape(1,4624)
                  predictions = model.predict(val) #store probabilities of 6 expressions
              #find max indexed array ( 'Angry' , 'Disgust' , 'Fear' , 'Happy'  , 'Neutral' ,  'Sad' , 'Surprise')
                  print ("Angry: %", predictions[0][0]/1.0 * 100)
                  print ("Disgust: %", predictions[0][1]/1.0 * 100)
                  print ("Fear: %", predictions[0][2]/1.0 * 100)
                  print ("Happy: %", predictions[0][3]/1.0 * 100)
                  print ("Neutral: %", predictions[0][4]/1.0 * 100)
                  print ("Sad: %", predictions[0][5]/1.0 * 100)    
                  print ("Surprised: %", predictions[0][6]/1.0 * 100)        
                  print ("----------------------"    )    
                  max_index = np.argmax(predictions[0])
                  emotion = emotions[max_index]
                  #write emotion text above rectangle
              box_label(img, x, y, x+w, y+h, emotion+":"+'{:2.2f}'.format(np.max(predictions[0])/1.0 * 100))
          cv2.imshow('img',img)
          if cv2.waitKey(1) & 0xFF == ord('q'): #press q to quit
              break
      
      #kill open cv things        
      cap.release()
      cv2.destroyAllWindows()
      

      ※ 途中で止めたいとき,右上の「x」をクリックしない.画面の中をクリックしてから,「q」のキーを押して閉じる

      [image]