トップページ -> 最新情報技術の実習と研究ツール -> 顔検出、顔識別 -> Dlib で,顔検出,顔のランドマーク検知(68ランドマーク法),表情判定を行ってみる
[サイトマップへ]

Dlib で,顔検出,顔のランドマーク検知(68ランドマーク法),表情判定を行ってみる

Dlibは,機械学習のアルゴリズムやトールの機能を持つソフトウエア.

Dlib の次の機能を使います

利用条件などは利用者において確認してください

サイト内の関連Webページ:

先人に感謝

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


前準備

Anaconda, git のインストール

前準備として,Python 開発環境のAnaconda, git のインストールが終わっていること.

隔離された Python 環境の作成.spyder, Tensorflow, Keras, Dlib, scikit-image, scikit-learn のインストール

Windows での 手順は、 「Windows で,隔離された Python 環境 + Keras + TensorFlow + OpenCV + spyder + Dlib 環境を作る(Anaconda を利用)」の Web ページに記載しています

以下,Windows での Anaconda と git をインストール済み, 隔離された Python 環境(名前は ai)に、spyder, Tensorflow, Keras, Dlib, scikit-image, scikit-learn をインストール済みであるものとして説明を続けます.

Dlib は C:\pytools\dlib にインストールされているとします


学習済みのモデルデータのダウンロードと展開(解凍)

次の3つの「学習済みのモデルデータ」をダウンロードする

  1. Web ブラウザで次の URL を開く

    http://dlib.net/files

  2. 次の3つのファイルをダウンロードする

  3. ダウンロードした3つのファイルを展開(解凍)する.

    ※ Windows での展開(解凍)のためのソフトは「7-Zip」をおすすめ.

  4. 展開(解凍)してできたファイルを確認する.

  5. このファイルを3つとも,先ほど作成した C:\pytools\dlib (Dlib のディレクトリ)の下の「python-example」にコピー

    ※ 「C:\pytools\dlib」は,Dlib をインストールしたディレクトリに読み替えること。

    ※ まだ Dlib のインストールを行っていないときは、 「Windows で,隔離された Python 環境 + Keras + TensorFlow + OpenCV + spyder + Dlib 環境を作る(Anaconda を利用)」の Web ページ の「Dlib のインストール」を見て、Dlib のインストールを行うこと


dlib サンプルプログラムのいくつかを実行してみる.

  1. Windows のコマンドプロンプトを開く

  2. コマンドプロンプトで次のように実行

    「activate ai 」は Python 環境(名前はai)を有効にするためのコマンド(各自の環境の名前にあわせること

    activate ai
    

    「Could not find conda environment: ai」というメッセージが出たときは、 隔離された Python 環境の作成(名前は ai) を行う.

  3. カレントディレクトリの移動

    C:\pytools\dlib」は,Dlib のディレクトリ

    cd C:\pytools\dlib\python_examples
    

    ※ 「C:\pytools\dlib」は,Dlib をインストールしたディレクトリに読み替えること。

    ※ まだ Dlib のインストールを行っていないときは、 「Windows で,隔離された Python 環境 + Keras + TensorFlow + OpenCV + spyder + Dlib 環境を作る(Anaconda を利用)」の Web ページ の「Dlib のインストール」を見て、Dlib のインストールを行うこと

  4. 顔検出 (face detector) のサンプルプログラムを実行してみる

    顔検出が行われ,顔を囲むようなバウンディングボックス (bounding box) が表示される. そして,バウンディングボックスの座標値が数値データとして得られていることが,画面表示で確認できる.

    python face_detector.py ..\examples\faces\2007_007763.jpg
    
  5. 顔のランドマークの検知 (face landmark detector) のサンプルプログラムを実行してみる

    顔ごとに,最大で 68 のランドマーク (68 landmarks) が得られる.

    python face_landmark_detection.py shape_predictor_68_face_landmarks.dat ..\examples\faces\
    

ezgiakcora/Facial-Expression-Keras を動かしてみる

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

  1. Windows のコマンドプロンプトを管理者として実行する.

  2. インストール
    mkdir c:\pytools
    cd c:\pytools
    rmdir /s /q Facial-Expression-Keras
    

    cd c:\pytools
    git clone https://github.com/ezgiakcora/Facial-Expression-Keras 
    cd Facial-Expression-Keras
    

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

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

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

    1. Windows のコマンドプロンプトを開く

    2. コマンドプロンプトで次のように実行

      「activate ai 」は Python 環境(名前はai)を有効にするためのコマンド(各自の環境の名前にあわせること

      activate ai
      

    3. プログラムの実行
      cd c:\pytools\Facial-Expression-Keras
      python demo.py 
      

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

    4. demo.py を少し書き変えて動かす
      import numpy as np
      import cv2
      from 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('C:/pytools/Facial-Expression-Keras/haarcascade_frontalface_default.xml')
      cap = cv2.VideoCapture(0)
      
      #-----------------------------
      #face expression recognizer initialization
      # Using pretrained model
      model = model_from_json(open("C:/pytools/Facial-Expression-Keras/model/model.json", "r").read())
      model.load_weights('C:/pytools/Facial-Expression-Keras/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("C:/pytools/Facial-Expression-Keras/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」のキーを押して閉じる