17. AI TensorFlowで顔認識のお試し

使わずお蔵入りになっていたUSB webカメラ(Microsoft LifeCam VX-800)が有ったので、チョッと気になっていたAI TensorFlowでの顔認識と云うのを試してみたくなり、ネットで参考になる情報を探して作ってみた。
結果として、画面が明るいと認識正解率は高いが、少し暗めだと誤認識が多かった。(自分よりルックスの良い人に間違われるとチョッと嬉しかったりして(^^)逆も有るけど…) 学習データが少なかった所為も有るかと思いますが、平均すると70%ぐらいの識別率かな。
TensorFlowの理解はまだ十分に出来ていませんが、今回利用させて頂いたサンプルプログラムやTensorFlowのTutorialでも、お試し程度なら少ないステップ数で出来上がるので驚いた。
また、「学習」処理において、学習プログラム(train.py)以外のエディタやブラウザ等のプログラムが起動しているとraspbianがダウンしたり、SDカードの空き容量が十分に無いとプログラムがエラー終了したりした。更に、処理時間が、合計191画像で約43分掛かっており、画像量が多いと、やはり、RaspberryPiではチョッと重荷なので高性能なPCを利用した方が良さそう。

《お試し手順》

基本的には参考サイト(本ページ末尾記載)に従って行った。
  1. 環境構築
    
    ●raspbianインストール
    真っ新な状態から行うため、OSの導入から行った。
     SDカード(16GB)にOS導入 → パッケージupdate/upgrade → samba導入
    
    ●OpenCVインストール(画像処理用)
    (参考サイトでは3.4.0でしたが、3.4.5が出ていたので)
    $ wget https://github.com/mt08xx/files/raw/master/opencv-rpi/libopencv3_3.4.5-20181227.1_armhf.deb
    $ sudo apt install -y ./libopencv3_3.4.5-20181227.1_armhf.deb
    $ sudo ldconfig
    
    ●TensorFlow + Kerasインストール
    (参考サイトではTensorFlowの1.4.1でしたが、1.12.0が出ていたので)
    $ sudo pip3 install numpy
    $ sudo apt-get install libblas-dev liblapack-dev python3-dev libatlas-base-dev gfortran python3-setuptools
    $ sudo pip3 install https://github.com/lhelontra/tensorflow-on-arm/releases/download/v1.12.0/tensorflow-1.12.0-cp35-none-linux_armv7l.whl
     *TensorFlowがRaspberry Piに正式対応されて、"pip3 install tensorflow"で導入できるが、バージョンが1つ古かった(1.11.0)ので直接githubから新しい物を導入した
    $ sudo apt-get install python3-h5py
    $ sudo pip3 install keras
    
    ●python3関連ライブラリのインストール
    sudo apt-get install python3-pandas -y
    

  2. 参考サイト作者("からあげ"さん)のgithubからサンプルプログラムの入手
    
    $ cd /xxx   # xxxダウンロードしたいフォルダへ移動
    $ git clone https://github.com/karaage0703/tensorflow-pi
    $ cd tensorflow_pi
    *"/xxx/tensorflow_pi"と云うフォルダにダウンロードされる
    
    サンプルでは、Python2でRaspberryPiカメラを使用していたが、Python3のUSB Webカメラ用に以降で修正していく。

  3. 顔の切り出し
    1. 顔写真データの準備
      顔写真は、自分の物と「Labeled Faces in the Wild」からブッシュさんとAxxさんのファイルをダウウンロードし適当に1名辺り50画像ぐらいが集まるような2名の選別と、未登録者の検知用として色々な人の画像をごちゃ混ぜにした約50画像を集めてみた。自分の物と合わせて3名+未登録者用1の4件を各人の名前(未登録者用は適当な名前)で作成したフォルダ内に準備した。(画像合計は191になった)

    2. 切り出し用プログラムを参考サイト作者(これも"からあげ"さん)のgithubからダウンロード
      
       $ cd /xxx   # xxxダウンロードしたいフォルダへ移動
       $ git clone https://github.com/karaage0703/python-image-processing
       $ cd python-image-processing
       *"/xxx/python-image-processing"と云うフォルダにダウンロードされる
      

    3. 切り出し用プログラムをpython3用に修正と入力画像データをパス指定出来るように改造(オリジナルは対象画像フォルダに移動してから実行)
      
      *face_crop.py
          # pathとfilenameを分離 追加
          imgpath,filename = path.split(filename)
      
          frame[(hypot - rows) * 0.5:(hypot + rows) * 0.5, (hypot - cols) * 0.5:(hypot + cols) * 0.5] = gray
         ↓ python3対応
          frame[int((hypot - rows) * 0.5):int((hypot + rows) * 0.5), int((hypot - cols) * 0.5):int((hypot + cols) * 0.5)] = gray
      
              print deg, len(faces)
             ↓ python3対応
              print (deg, len(faces))
      
                  eyes = filter(lambda e: (e[0] > w / 2 or e[0] + e[2] < w / 2) and e[1] + e[3] < h / 2, eyes)
               ↓ python3対応
                  eyes = list(filter(lambda e: (e[0] > w / 2 or e[0] + e[2] < w / 2) and e[1] + e[3] < h / 2, eyes))
      
                          cv2.imwrite(str("{0:02d}".format(numb)) + "_face_" + filename, output_img)
                      ↓ path指定追加
                          cv2.imwrite(imgpath + str("/image_data/{0:02d}".format(numb)) + "_face_" + filename, output_img)
      
      *face_crop-all.sh
      for f in *.JPG
       ↓ 指定path追加 
      for f in $1/*.JPG
      

    4. 顔の切り出し実施
      
      各人の画像フォルダ内に"image_data"と云うフォルダを作成してから以下実施
      
      $ ./face_crop-all.sh <対象フォルダ名>
      
      **各人フォルダ/image_dataに作成された切り出し画像ファイルを下記へ移動
        /xxx/tensorflow-pi/data/image_data/各人名前フォルダ
      

  4. データのN増し
    必要に応じて実施すると既存の画像にノイズを載せたりした物が作成される。 1人の写真は50枚ぐらい有ればそこそこできるようなので今回は未実施。
    
    $ cd /xxx/tensorflow-pi/data/image_data/各人名前フォルダ
    $ ../../increase_picture-all.sh
    

  5. ラベル作成
    1. 実施にあたり、プログラムをpython3用に修正した。
      
      *make_train_data.py
      import commands
       ↓ python3対応(コメントアウト、または削除)  
      #import commands
      
      return commands.getoutput(cmd)
         ↓ python3対応
      return subprocess.getoutput(cmd)
      

    2. ラベル作成実施
      
      $ cd /xxx/tensorflow-pi/data   ← 切り抜いた顔写真を集めたフォルダに移動
      $ python3 make_train_data.py image_data
      

  6. 学習
    1. プログラムをpython3用に修正
      
      *train.py
                  for i in range(len(train_image)/FLAGS.batch_size):
                    ↓ python3対応
                  for i in range(int(len(train_image)/FLAGS.batch_size)):
      

    2. 学習の実施
      
      $ cd /xxx/tensorflow-pi
      $ python3 train.py
      
      ※学習時のメッセージ(全画像191件で、2593秒≒43分掛かった)
      
      /tmp/tensorflow_pi/train.txt
      loading /tmp/tensorflow_pi/images/image0000000.jpg
      loading /tmp/tensorflow_pi/images/image0000001.jpg
      loading /tmp/tensorflow_pi/images/image0000002.jpg
       :
      loading /tmp/tensorflow_pi/images/image0000189.jpg
      loading /tmp/tensorflow_pi/images/image0000190.jpg
      loading /tmp/tensorflow_pi/images/image0000191.jpg
      2019-02-12 15:12:36.344093: W tensorflow/core/framework/allocator.cc:122] Allocation of 16777216 exceeds 10% of system memory.
       :
      2019-02-12 15:12:36.604683: W tensorflow/core/framework/allocator.cc:122] Allocation of 16777216 exceeds 10% of system memory.
      step 0, training accuracy 0.207792, loss 1201.82
      step 1, training accuracy 0.292208, loss 793.028
      step 2, training accuracy 0.292208, loss 548.811
       :
      step 197, training accuracy 1, loss 2.95055
      step 198, training accuracy 1, loss 2.82255
      step 199, training accuracy 0.993506, loss 3.0346
      elapsed_time:2593.230695962906[sec]
      test accuracy 0.98
      

  7. 判別テスト
    3項で切り抜いた顔写真を使って判別できるかのテスト
    
    $ cd /xxx/tensorflow-pi
    $ python3 predict.py <テスト用jpgファイル名>
    
    ※実行直後、以下の警告メッセージが表示されたが正しく認識した
    
    2019-02-12 16:09:51.662938: W tensorflow/core/framework/allocator.cc:122] Allocation of 16777216 exceeds 10% of system memory.
    2019-02-12 16:09:52.063150: W tensorflow/core/framework/allocator.cc:122] Allocation of 16777216 exceeds 10% of system memory.
    2019-02-12 16:09:52.134962: W tensorflow/core/framework/allocator.cc:122] Allocation of 16777216 exceeds 10% of system memory.
    

  8. カメラで顔認識
    1. プログラムをUSB webカメラ用に改造
      
      *face_recog_pi.py
      cascades_dir ='/usr/share/opencv/haarcascades'
         ↓「cascade_f.detectMultiScale」でエラーになるので"face_crop.py"のものを利用
      cascades_dir = path.normpath(path.join(cv2.__file__, '..', '..', '..', '..', 'share', 'OpenCV', 'haarcascades'))
       :
      "shutter"関数削除
       :
          cap = cv2.VideoCapture(0)    # 追加
      
          try:
              while True:
      #            shutter()    # 削除
      #---- "shutter()"の代わりに以下追加
                  while(cap.isOpened()):
                      print('capture process')
                      cap.read()
                      r, img = cap.read()
                      cv2.waitKey(1000)
                      if(r == True):
                          break;
                  rimg = cv2.resize(img,(640,480))
                  cv2.imwrite(face_filename, rimg)
      #---- 以上追加
       :
          finally:
              print("program terminated")
              sess.close()
              cap.release()    # 追加
      

    2. 実行
      
      $ cd /xxx/tensorflow-pi
      $ python3 face_recog_pi.py
      
      ※実行直後のメッセージ
      
      <_io.TextIOWrapper name='/home/pi/tensorflow-pi/data/model/labels.txt' mode='r' encoding='UTF-8'>
      2019-02-12 19:15:52.827692: W tensorflow/core/framework/allocator.cc:122] Allocation of 16777216 exceeds 10% of system memory.
      2019-02-12 19:15:53.214084: W tensorflow/core/framework/allocator.cc:122] Allocation of 16777216 exceeds 10% of system memory.
      2019-02-12 19:15:53.284530: W tensorflow/core/framework/allocator.cc:122] Allocation of 16777216 exceeds 10% of system memory.
      capture process
      

      **実行結果 被写体が暗いと誤認識するが、明るければ正しく認識し、未登録者は未登録として認識できた。
【参考】
  1. Raspberry Pi上でTensorFlowで簡単にディープラーニングを試せるツール「tensorflow-pi」でロボホンの幻の顔認識機能に挑戦してみた ←ソースを利用させて頂きました、有難う御座います。
  2. tensorflow-on-arm
  3. Python3におけるmap/filterの使い方
  4. 「TypeError: slice indices must be integers or None or have an __index__ method」のエラーで困っています。
  5. TensorFlowでTypeErrorが出て頭を抱えた
  6. バージョン 2.6 で撤廃: commands モジュールは Python 3 で削除されました。
  7. error: (-215) !empty() in function detectMultiScale

2019/03/02