# 芸能人の顔を機械学習で分類してみた（その５）

### 引数で与えた画像の分類

<使ったデータ>
trainデータ：石原さとみ(100枚), 西島秀俊(100枚)
testデータ ：石原さとみ(30枚), 西島秀俊(30枚)

<ラベル>
0：西島秀俊
1：石原さとみ

FaceType1.py
```#!/usr/bin/env python
#! -*- coding: utf-8 -*-

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

NUM_CLASSES = 2
IMAGE_SIZE = 28
IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE*3
#カスケード分類器ロード

def inference(images_placeholder, keep_prob):
""" モデルを作成する関数

引数:
images_placeholder: inputs()で作成した画像のplaceholder
keep_prob: dropout率のplace_holder

返り値:
cross_entropy: モデルの計算結果
"""
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)

def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)

def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],

x_image = tf.reshape(images_placeholder, [-1, 28, 28, 3])

with tf.name_scope('conv1') as scope:
W_conv1 = weight_variable([5, 5, 3, 32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)

with tf.name_scope('pool1') as scope:
h_pool1 = max_pool_2x2(h_conv1)

with tf.name_scope('conv2') as scope:
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)

with tf.name_scope('pool2') as scope:
h_pool2 = max_pool_2x2(h_conv2)

with tf.name_scope('fc1') as scope:
W_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

with tf.name_scope('fc2') as scope:
W_fc2 = weight_variable([1024, NUM_CLASSES])
b_fc2 = bias_variable([NUM_CLASSES])

with tf.name_scope('softmax') as scope:
y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

return y_conv

# 顔検出器
# detector = dlib.simple_object_detector("detector.svm")

images_placeholder = tf.placeholder("float", shape=(None, IMAGE_PIXELS))
labels_placeholder = tf.placeholder("float", shape=(None, NUM_CLASSES))
keep_prob = tf.placeholder("float")

logits = inference(images_placeholder, keep_prob)
sess = tf.InteractiveSession()

saver = tf.train.Saver()
sess.run(tf.global_variables_initializer())
saver.restore(sess, "model.ckpt")

if __name__ == '__main__':
test_image = []
for i in range(1, len(sys.argv)):
#グレースケール変換
image_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

#カスケード分類器の特徴量を取得する

#物体認識（顔認識）の実行
facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=1, minSize=(1, 1))

if len(facerect) == 1:
print ("顔認識に成功しました。")
print (facerect)

#検出した顔の処理
for rect in facerect:
#顔だけ切り出して保存
x = rect[0]
y = rect[1]
width = rect[2]
height = rect[3]
dst = img[y:y+height, x:x+width]
new_image_path = "./result/" + sys.argv[1]
cv2.imwrite(new_image_path, dst)

elif len(facerect) > 1:
# 複数顔が検出された場合はスキップ
print ("顔が複数認識されました")
print (facerect)

if len(facerect) > 0:
color = (255, 255, 255) #白
for rect in facerect:
#検出した顔を囲む矩形の作成
cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2] + rect[2:4]), color, thickness=2)
quit()

else:
# 顔検出に失敗した場合もスキップ
print ("顔が認識できません。")
quit()

#形式を変換
dst = cv2.resize(dst, (28, 28))
test_image.append(dst.flatten().astype(np.float32)/255.0)
test_image = np.asarray(test_image)

for i in range(len(test_image)):
result = []
result = logits.eval(feed_dict={images_placeholder: [test_image[i]],keep_prob: 1.0 })
print ("result")
print (result)
print ("小数第3桁で四捨五入")
print (np.round(result,3))
```

### 結果

```\$ python3 FaceType1.py fc0c597d5dad95acf207adff0b2f7c8a44f3383caf16f6b82a75ba8412459de0.jpg
[ INFO:0] Initialize OpenCL runtime...

[[107  74 164 164]]
result
[[9.9965370e-01 3.4631684e-04]]

[[1. 0.]]
```

99.965%西島さんに分類されました。

それでは前回失敗してた画像を使ってみます。

```\$ python3 FaceType1.py f61a4affa931e919b890d752d858a12500d168780e3b74835779033e590e009a.jpg
[ INFO:0] Initialize OpenCL runtime...

[[175 138 195 195]]
result
[[9.999999e-01 6.105071e-08]]

[[1. 0.]]
```

f61a4affa931e919b890d752d858a12500d168780e3b74835779033e590e009a.jpg

99.999%西島さんという結果が出ました〜。よかった。
というのも、計算させるときに切り出した顔のデータ出なく、引数に与えたデータそのまま使ってました(苦笑いしかない...)

fe08c1be52084dfc0781eae08d00678cc7230deefb80b575a89e6f344d735797.jpg

```\$ python3 FaceType1.py fe08c1be52084dfc0781eae08d00678cc7230deefb80b575a89e6f344d735797.jpg
[ INFO:0] Initialize OpenCL runtime...

[[160 208 455 455]]
result
[[3.1513974e-08 1.0000000e+00]]

[[0. 1.]]
```

100%石原さとみでした。

もう一枚くらいやってみる。

```\$ python3 FaceType1.py ffb73a7d766e5da2d488eafad0761d88a8b4313937924993ec7e1ddc10e0d7dc.jpg
[ INFO:0] Initialize OpenCL runtime...

[[ 67 115 221 221]]
result
[[1.4139876e-09 1.0000000e+00]]

[[0. 1.]]
```

こちらも100%石原さとみでした。

### ちなみに

もういちど自分の顔使ってみました。

IMG_6154.JPG

```\$ python3 FaceType1.py IMG_6154.JPG
[ INFO:0] Initialize OpenCL runtime...

[[ 42  67 144 144]]
result
[[2.2511498e-05 9.9997747e-01]]

[[0. 1.]]
```

99.998%石原さとみだそうです。よろこび。
めでたしめでたし。