我们需要调用保存的训练模型来识别人脸,话不多说直接上代码。
新建 识别出我.py
import tensorflow as tf
import cv2
import numpy as np
import os
import random
import sys
from sklearn.model_selection import train_test_split
my_faces_path = '/home/dong/PycharmProjects/untitled/人脸识别/data/me'
other_faces_path = '/home/dong/PycharmProjects/untitled/人脸识别/data/zhang'
size = 64
imgs = []
labs = []
def getPaddingSize(img):
h, w, _ = img.shape
top, bottom, left, right = (0, 0, 0, 0)
longest = max(h, w)
if w < longest:
tmp = longest - w
# //表示整除符号
left = tmp // 2
right = tmp - left
elif h < longest:
tmp = longest - h
top = tmp // 2
bottom = tmp - top
else:
pass
return top, bottom, left, right
def readData(path , h=size, w=size):
for filename in os.listdir(path):
if filename.endswith('.jpg'):
filename = path + '/' + filename
img = cv2.imread(filename)
top,bottom,left,right = getPaddingSize(img)
# 将图片放大, 扩充图片边缘部分
img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[0,0,0])
img = cv2.resize(img, (h, w))
imgs.append(img)
labs.append(path)
readData(my_faces_path)
readData(other_faces_path)
# 将图片数据与标签转换成数组
imgs = np.array(imgs)
labs = np.array([[0,1] if lab == my_faces_path else [1,0] for lab in labs])
# 随机划分测试集与训练集
train_x,test_x,train_y,test_y = train_test_split(imgs, labs, test_size=0.05, random_state=random.randint(0,100))
# 参数:图片数据的总数,图片的高、宽、通道
train_x = train_x.reshape(train_x.shape[0], size, size, 3)
test_x = test_x.reshape(test_x.shape[0], size, size, 3)
# 将数据转换成小于1的数
train_x = train_x.astype('float32')/255.0
test_x = test_x.astype('float32')/255.0
print('train size:%s, test size:%s' % (len(train_x), len(test_x)))
# 图片块,每次取128张图片
batch_size = 128
num_batch = len(train_x) // 128
x = tf.placeholder(tf.float32, [None, size, size, 3])
y_ = tf.placeholder(tf.float32, [None, 2])
keep_prob_5 = tf.placeholder(tf.float32)
keep_prob_75 = tf.placeholder(tf.float32)
def weightVariable(shape):
init = tf.random_normal(shape, stddev=0.01)
return tf.Variable(init)
def biasVariable(shape):
init = tf.random_normal(shape)
return tf.Variable(init)
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')
def maxPool(x):
return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
def dropout(x, keep):
return tf.nn.dropout(x, keep)
def cnnLayer():
# 第一层
W1 = weightVariable([3,3,3,32]) # 卷积核大小(3,3), 输入通道(3), 输出通道(32)
b1 = biasVariable([32])
# 卷积
conv1 = tf.nn.relu(conv2d(x, W1) + b1)
# 池化
pool1 = maxPool(conv1)
# 减少过拟合,随机让某些权重不更新
drop1 = dropout(pool1, keep_prob_5)
# 第二层
W2 = weightVariable([3,3,32,64])
b2 = biasVariable([64])
conv2 = tf.nn.relu(conv2d(drop1, W2) + b2)
pool2 = maxPool(conv2)
drop2 = dropout(pool2, keep_prob_5)
# 第三层
W3 = weightVariable([3,3,64,64])
b3 = biasVariable([64])
conv3 = tf.nn.relu(conv2d(drop2, W3) + b3)
pool3 = maxPool(conv3)
drop3 = dropout(pool3, keep_prob_5)
# 全连接层
Wf = weightVariable([8*16*32, 512])
bf = biasVariable([512])
drop3_flat = tf.reshape(drop3, [-1, 8*16*32])
dense = tf.nn.relu(tf.matmul(drop3_flat, Wf) + bf)
dropf = dropout(dense, keep_prob_75)
# 输出层
Wout = weightVariable([512,2])
bout = biasVariable([2])
out = tf.add(tf.matmul(dropf, Wout), bout)
return out
output = cnnLayer()
predict = tf.argmax(output, 1)
这些代码都和上一篇中的相同
最主要的是接下来的代码。
继续添加
saver = tf.train.Saver()
sess = tf.Session()
saver.restore(sess, tf.train.latest_checkpoint('/home/dong/PycharmProjects/untitled/FaceRecognition-tensorflow/模型'))
def is_my_face(image):
res = sess.run(predict, feed_dict={x: [image/255.0], keep_prob_5: 1.0, keep_prob_75: 1.0})
if res[0] == 1:
return True
else:
return False
cv2.namedWindow("识别")
# 视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头
cap = cv2.VideoCapture("/home/dong/Videos/meimei/13.mp4")
# 告诉OpenCV使用人脸识别分类器
classfier = cv2.CascadeClassifier(
"/home/dong/PycharmProjects/untitled/venv/lib/python3.6/site-packages/cv2/data/haarcascade_frontalface_alt2.xml")
# 识别出人脸后要画的边框的颜色,RGB格式
color = (0, 0, 0)
while cap.isOpened():
ok, frame = cap.read() # 读取一帧数据
if not ok:
break
# 将当前帧转换成灰度图像
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数
faceRects = classfier.detectMultiScale(grey, 1.3, 5)
if len(faceRects) > 0: # 大于0则检测到人脸
for faceRect in faceRects: # 单独框出每一张人脸
x1, y1, w1, h1 = faceRect
face = frame[y1 - 10: y1 + h1 + 10, x1 - 10: x1 + w1 + 10]
faces = cv2.resize(face, (size, size))
print(is_my_face(faces))
b = is_my_face(faces)
cv2.rectangle(frame, (x1 - 10, y1 - 10), (x1 + w1 + 10, y1 + h1 + 10), color, 2)
font = cv2.FONT_HERSHEY_SIMPLEX
if b == True:
cv2.putText(frame, "name:%s" % ("dong"), (x1 + 30, y1 + 30), font, 1, (255, 0, 255), 4)
else:
cv2.putText(frame, "name:%s" % ("tan"), (x1 + 30, y1 + 30), font, 1, (255, 0, 255), 4)
# 显示图像
cv2.imshow("识别", frame)
c = cv2.waitKey(10)
if c & 0xFF == ord('q'): # 如果强制停止执行程序,结束视频放映
break
# 释放摄像头并销毁所有窗口
cap.release()
cv2.destroyAllWindows()
print(faceRects)
sess.close()
如果出现了TypeError: Cannot interpret feed_dict key as Tensor: Can not convert a float into a Tensor.
改错:
查看是否重用了y,x和keep_prob。。。有重用的地方,改另外的变量即可。。