LoginSignup
0
0

More than 5 years have passed since last update.

TensorFlowを使ってDir en greyの顔分類器を作ってみた - ⑩顔分類試験編

Last updated at Posted at 2017-05-31

はじめに

  • いよいよお楽しみのときです。

プログラム

eval.py
#!/usr/local/bin/python
#! -*- coding: utf-8 -*-

import sys
import numpy as np
import cv2
import tensorflow as tf
import os
import random
import main

# OpenCVのデフォルトの顔の分類器のpath
cascade_path = '/usr/local/Cellar/opencv3/3.2.0/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml'
faceCascade = cv2.CascadeClassifier(cascade_path)

# 識別ラベルと各ラベル番号に対応する名前
HUMAN_NAMES = {
  0: u"京",
  1: u"薫",
  2: u"Shinya"
}

#指定した画像(img_path)を学習結果(ckpt_path)を用いて判定する
def evaluation(img_path, ckpt_path):
  # GraphのReset(らしいが、何をしているのかよくわかっていない…)
  tf.reset_default_graph()

  # ファイルを開く
  f = open(img_path, 'r')
  img = cv2.imread(img_path, cv2.IMREAD_COLOR)

  # モノクロ画像に変換
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  face = faceCascade.detectMultiScale(gray, 1.1, 3)

  if len(face) > 0:
    for rect in face:
      # 加工した画像に何でもいいので適当な名前をつけたかった。日付秒数とかでいいかも
      random_str = str(random.random())

      # 顔部分を赤線で書こう
      cv2.rectangle(img, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), (0, 0, 255), thickness=2)

      # 顔部分を赤線で囲った画像の保存先
      face_detect_img_path = '{ディレクトリパス}' + random_str + '.jpg'

      # 顔部分を赤線で囲った画像の保存
      cv2.imwrite(face_detect_img_path, img)
      x = rect[0]
      y = rect[1]
      w = rect[2]
      h = rect[3]

      # 検出した顔を切り抜いた画像を保存
      cv2.imwrite('{ディレクトリパス}' + random_str + '.jpg', img[y:y+h, x:x+w])

      # TensorFlowへ渡す切り抜いた顔画像
      target_image_path = '{ディレクトリパス}' + random_str + '.jpg'
  else:
    # 顔が見つからなければ処理終了
    print 'image:No Face'
    return
  f.close()
  f = open(target_image_path, 'r')

  # データを入れる配列
  image = []
  img = cv2.imread(target_image_path)
  img = cv2.resize(img, (28, 28))

  # 画像情報を一列にした後、0-1のfloat値にする
  image.append(img.flatten().astype(np.float32)/255.0)
  # numpy形式に変換し、TensorFlowで処理できるようにする
  image = np.asarray(image)

  # 入力画像に対して、各ラベルの確率を出力して返す(main.pyより呼び出し)
  logits = main.inference(image, 1.0)

  # We can just use 'c.eval()' without passing 'sess'
  sess = tf.InteractiveSession()

  # restore(パラメーター読み込み)の準備
  saver = tf.train.Saver()

  # 変数の初期化
  sess.run(tf.global_variables_initializer())

  if ckpt_path:
    # 学習後のパラメーターの読み込み
    saver.restore(sess, ckpt_path)

  # sess.run(logits)と同じ
  softmax = logits.eval()

  # 判定結果
  result = softmax[0]

  # 判定結果を%にして四捨五入
  rates = [round(n * 100.0, 1) for n in result]
  humans = []

  # ラベル番号、名前、パーセンテージのHashを作成
  for index, rate in enumerate(rates):
    name = HUMAN_NAMES[index]
    humans.append({
      'label': index,
      'name': name,
      'rate': rate
    })

  # パーセンテージの高い順にソート
  rank = sorted(humans, key=lambda x: x['rate'], reverse=True)

  # 結果をコンソールんい出力
  print rank

  # 判定結果と加工した画像のpathを返す
  return [rank, os.path.basename(img_path), random_str + '.jpg']

# コマンドラインからのテスト用
if __name__ == '__main__':
  evaluation('{ディレクトリパス}/test.jpg', '{ディレクトリパス}/model2.ckpt')

実行

python eval.py

補足と言い訳

  • model2.ckptといったファイルは実際にはないので、ディレクトリパスはmodel2.ckpt.indexが生成された場所を指せばいいみたいです。
  • 実行後にテスト画像がどれにどれくらいの確率で誰に似ているか結果がでれば成功です。

全ページリンク

0
0
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
0
0