https://www.cnblogs.com/31415926535x/p/11001669.html

基于卷积神经网络的人脸识别项目_使用Tensorflow-gpu+dilib+sklearn

概述

学期末了啊,,,最后这个人脸识别的项目弄完了,,有很多的不足,,很多东西都是只知道怎么用,但是不知道其背后的逻辑,,感觉自己学习东西对于那些潜意识优先级不高的就放弃了,,,emmm

这篇文章主要是大致介绍一下我们最后弄出来的人脸识别项目的成果吧,,整个项目放到了我的github,,可以直接下载运行的,,不过这也只是一个我们的思路,,这块东西还是多阅读别人的项目代码,,然后自己写一下好些,,根据自己的需求尝试自己写代码,实在不行再看别人的思路,,才能提升自己的思维吧,,,

项目思路

抛开那些花里胡哨的东西,人脸识别的大致流程只有三个: 人脸数据的录入、构建卷积神经网络并训练模型、识别

不过这前要配置好环境,,我用的Anaconda来配置的整体环境,,,可以看我的这篇博客 ,,(到能成功验证环境即可

具体的运行流程:

  • 激活创建的anaconda环境
  • 运行初始化模块(可有可无) python init.py
  • 运行录入人脸模块,此时会提示输入姓名,然后录制视频,按q结束(20几喵即可) python getFaceByCamera.py
  • 运行训练模块,python tensorflow_face.py
  • 等待,,结束后会打印准确度,,
  • 运行识别模块,python tensorflow_face.py ,,,没错还是这个,,第二次运行会调用识别模块的,,,

人脸数据的录入

这部分的代码在这里

这部分我们的大致思路是:

  • 录入待录入者的姓名
  • 录制一段视频
  • 利用dlib人脸检测器以及opencv对图片的操作来裁剪200张相片,,当然也可以使用opencv的人脸检测器,,,不足应该就是准确率不怎么高吧,,但是快些,,,
  • 循环录入所有人的信息

这一部分的代码:

getFaceByCamera.py

  1. import cv2
  2. import os
  3. import dlib
  4. import sys
  5. import random
  6. import shutil
  7. def make_video(name):
  8. # 录制视频
  9. #shutil.rmtree(name)
  10. """使用opencv录像"""
  11. cap = cv2.VideoCapture(0) # 默认的摄像头
  12. # 指定视频代码
  13. fourcc = cv2.VideoWriter_fourcc(*"DIVX")
  14. out = cv2.VideoWriter('233.avi', fourcc, 20.0, (640,480)) # 设置录制的视频的格式
  15. while(cap.isOpened()):
  16. ret, frame = cap.read()
  17. if ret:
  18. out.write(frame)
  19. #
  20. cv2.imshow('frame',frame)
  21. # 等待按键q操作关闭摄像头
  22. if cv2.waitKey(1) & 0xFF == ord('q'):
  23. break
  24. else:
  25. break
  26. cap.release() # 释放摄像头资源
  27. out.release() # 释放文件资源
  28. cv2.destroyAllWindows() # 关闭拍摄窗口
  29. # 改变图片的亮度与对比度
  30. def relight(img, light=1, bias=0):
  31. w = img.shape[1]
  32. h = img.shape[0]
  33. #image = []
  34. for i in range(0,w):
  35. for j in range(0,h):
  36. for c in range(3):
  37. tmp = int(img[j,i,c]*light + bias)
  38. if tmp > 255:
  39. tmp = 255
  40. elif tmp < 0:
  41. tmp = 0
  42. img[j,i,c] = tmp
  43. return img
  44. def getDataByDlib(name):
  45. # 利用dlib来实现
  46. output_dir = name # 使用录入的名字作为文件夹的名字
  47. size = 64 # 相片的大小为64*64
  48. if not os.path.exists(output_dir): # 没有文件夹是主动创建一个
  49. os.makedirs(output_dir)
  50. #使用dlib自带的frontal_face_detector作为我们的特征提取器
  51. detector = dlib.get_frontal_face_detector()
  52. # 打开摄像头 参数为输入流,可以为摄像头或视频文件
  53. #camera = cv2.VideoCapture(0)
  54. camera = cv2.VideoCapture("233.avi") # 相片来自上一步拍摄的视频
  55. index = 1
  56. while True:
  57. if (index <= 200): # 每一段视频只取200张
  58. print('Being processed picture %s' % index) # 显示处理的过程
  59. # 从摄像头读取照片
  60. success, img = camera.read() # 从视频流中读取照片
  61. # 转为灰度图片
  62. gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  63. # 使用detector进行人脸检测
  64. dets = detector(gray_img, 1)
  65. if success == False:
  66. break
  67. for i, d in enumerate(dets):
  68. x1 = d.top() if d.top() > 0 else 0
  69. y1 = d.bottom() if d.bottom() > 0 else 0
  70. x2 = d.left() if d.left() > 0 else 0
  71. y2 = d.right() if d.right() > 0 else 0
  72. face = img[x1:y1,x2:y2]
  73. # 调整图片的对比度与亮度, 对比度与亮度值都取随机数,这样能增加样本的多样性
  74. face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))
  75. # 裁剪出人脸相片,大小为64*64
  76. face = cv2.resize(face, (size,size))
  77. # 显示最后裁剪出的人脸相片
  78. cv2.imshow('image', face)
  79. # 保存到文件下,文件名为1 - 200.jpg
  80. cv2.imwrite(output_dir+'/'+str(index)+'.jpg', face)
  81. index += 1
  82. key = cv2.waitKey(30) & 0xff
  83. if key == 27:
  84. break
  85. else:
  86. print('Finished!')
  87. break
  88. # 删除视频
  89. shutil.rmtree('./233.avi')
  90. def getDataByOpencv2():
  91. # 利用opencv来实现
  92. output_dir = './my_faces'
  93. size = 64
  94. if not os.path.exists(output_dir):
  95. os.makedirs(output_dir)
  96. # 获取分类器
  97. haar = cv2.CascadeClassifier(r'G:\DIP\Anaconda3\envs\test1\Library\etc\haarcascades\haarcascade_frontalface_default.xml')
  98. # 打开摄像头 参数为输入流,可以为摄像头或视频文件
  99. camera = cv2.VideoCapture("233.avi")
  100. n = 1
  101. while 1:
  102. if (n <= 10000):
  103. print('It`s processing %s image.' % n)
  104. # 读帧
  105. success, img = camera.read()
  106. gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  107. faces = haar.detectMultiScale(gray_img, 1.3, 5)
  108. for f_x, f_y, f_w, f_h in faces:
  109. face = img[f_y:f_y+f_h, f_x:f_x+f_w]
  110. face = cv2.resize(face, (64,64))
  111. '''
  112. if n % 3 == 1:
  113. face = relight(face, 1, 50)
  114. elif n % 3 == 2:
  115. face = relight(face, 0.5, 0)
  116. '''
  117. face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))
  118. cv2.imshow('img', face)
  119. cv2.imwrite(output_dir+'/'+str(n)+'.jpg', face)
  120. n+=1
  121. key = cv2.waitKey(30) & 0xff
  122. if key == 27:
  123. break
  124. else:
  125. break
  126. if __name__ == '__main__':
  127. name = input('please input yourename: ') # 获取录入者的名字
  128. name = os.path.join('./image/trainfaces', name) # 生成保存的文件路径名
  129. make_video(name) # 拍摄视频
  130. getDataByDlib(name) # 利用dlib处理裁剪人脸原始相片

构建卷积神经网络,然后训练模型

这一部分大概就是做人脸识别的主要目的了吧,,,

构建卷积神经网络

这一部分几乎网上写的代码的框架都是差不多的,,,所以只要理解每一层是什么意思,,怎么用就行了,,当然可以继续深究下去,,理解每一层为什么这么做,,这么做的方法是什么等等,,

我们之前在这一部分投入的精力也最多,,出现的问题也是很多的,,其中我感觉最印象深刻的就是层数的叠加和那个神奇的 loss=0.69.....

层数的叠加就是说大部分的代码都是做的3层的神经网络,,但是很少有做多层的,,当时找了很多的资料才一点一点的大致会算怎么计算下一层

关于那一个神奇的 loss=0.69 ,,貌似不同的网络、需求下可能不会出现这种情况,,,但是如果出现不管比怎么调参出来的loss都保持在0.69附近的话,,可以试着查一下这一个问题,,我们最后的解决方法是再添加一层 batch nomalization层 ,,具体干什么的网上有很多讲解的,,,加了它就可以使loss快速收敛,,,

训练模型

这一部分的框架都是差不多的,,变化可能有参数的变化,,优化器的不同等等

代码:

  1. #!/usr/bin/python
  2. #coding=utf-8
  3. ''' face detect convolution'''
  4. # pylint: disable=invalid-name
  5. import os
  6. import sys
  7. import logging as log
  8. import matplotlib.pyplot as plt
  9. import common
  10. import numpy as np
  11. from tensorflow.examples.tutorials.mnist import input_data
  12. import tensorflow as tf
  13. import cv2
  14. from sklearn.model_selection import train_test_split
  15. import random
  16. SIZE = 64
  17. x = tf.placeholder(tf.float32, [None, SIZE, SIZE, 3])
  18. y_ = tf.placeholder(tf.float32, [None, None])
  19. keep_prob_5 = tf.placeholder(tf.float32)
  20. keep_prob_75 = tf.placeholder(tf.float32)
  21. def weightVariable(shape):
  22. ''' build weight variable'''
  23. init = tf.random_normal(shape, stddev=0.01)
  24. #init = tf.truncated_normal(shape, stddev=0.01)
  25. return tf.Variable(init)
  26. def biasVariable(shape):
  27. ''' build bias variable'''
  28. init = tf.random_normal(shape)
  29. #init = tf.truncated_normal(shape, stddev=0.01)
  30. return tf.Variable(init)
  31. def conv2d(x, W):
  32. ''' conv2d by 1, 1, 1, 1'''
  33. return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
  34. def maxPool(x):
  35. ''' max pooling'''
  36. return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
  37. def dropout(x, keep):
  38. ''' drop out'''
  39. return tf.nn.dropout(x, keep)
  40. def batch_norm_layer(value,is_training=False,name='batch_norm'):
  41. '''
  42. 批量归一化 返回批量归一化的结果
  43. args:
  44. value:代表输入,第一个维度为batch_size
  45. is_training:当它为True,代表是训练过程,这时会不断更新样本集的均值与方差。当测试时,要设置成False,这样就会使用训练样本集的均值和方差。
  46. 默认测试模式
  47. name:名称。
  48. '''
  49. if is_training is True:
  50. #训练模式 使用指数加权函数不断更新均值和方差
  51. return tf.contrib.layers.batch_norm(inputs=value,decay=0.9,updates_collections=None,is_training = True)
  52. else:
  53. #测试模式 不更新均值和方差,直接使用
  54. return tf.contrib.layers.batch_norm(inputs=value,decay=0.9,updates_collections=None,is_training = False)
  55. def cnnLayer(classnum, isTrue):
  56. ''' create cnn layer'''
  57. # 第一层
  58. W1 = weightVariable([3, 3, 3, 32]) # 卷积核大小(3,3), 输入通道(3), 输出通道(32)
  59. b1 = biasVariable([32])
  60. conv1 = tf.nn.relu(batch_norm_layer(conv2d(x, W1) + b1, isTrue))
  61. pool1 = maxPool(conv1)
  62. # 减少过拟合,随机让某些权重不更新
  63. drop1 = dropout(pool1, keep_prob_5) # 32 * 32 * 32 多个输入channel 被filter内积掉了
  64. # 第二层
  65. W2 = weightVariable([3, 3, 32, 64])
  66. b2 = biasVariable([64])
  67. conv2 = tf.nn.relu(batch_norm_layer(conv2d(drop1, W2) + b2, isTrue))
  68. pool2 = maxPool(conv2)
  69. drop2 = dropout(pool2, keep_prob_5) # 64 * 16 * 16
  70. # 第三层
  71. W3 = weightVariable([3, 3, 64, 64])
  72. b3 = biasVariable([64])
  73. conv3 = tf.nn.relu(conv2d(drop2, W3) + b3)
  74. pool3 = maxPool(conv3)
  75. drop3 = dropout(pool3, keep_prob_5) # 64 * 8 * 8
  76. # 全连接层
  77. Wf = weightVariable([8*8*64,512])
  78. bf = biasVariable([512])
  79. drop3_flat = tf.reshape(drop3, [-1, 8*8*64])
  80. dense = tf.nn.relu(tf.matmul(drop3_flat, Wf) + bf)
  81. dropf = dropout(dense, keep_prob_75)
  82. # 输出层
  83. Wout = weightVariable([512, classnum])
  84. bout = weightVariable([classnum])
  85. #out = tf.matmul(dropf, Wout) + bout
  86. out = tf.add(tf.matmul(dropf, Wout), bout)
  87. return out
  88. # # 第三层
  89. # W3 = weightVariable([3, 3, 64, 128])
  90. # b3 = biasVariable([128])
  91. # conv3 = tf.nn.relu(batch_norm_layer(conv2d(drop2, W3) + b3, True))
  92. # pool3 = maxPool(conv3)
  93. # drop3 = dropout(pool3, keep_prob_5) # 128 * 8 * 8
  94. # # 第四层
  95. # W4 = weightVariable([3, 3, 128, 512])
  96. # b4 = biasVariable([512])
  97. # conv4 = tf.nn.relu(batch_norm_layer(conv2d(drop3, W4) + b4, True))
  98. # pool4 = maxPool(conv4)
  99. # drop4 = dropout(pool4, keep_prob_5) # 512 * 4 * 4
  100. # # 第五层
  101. # W5 = weightVariable([3, 3, 512, 1024])
  102. # b5 = biasVariable([1024])
  103. # conv5 = tf.nn.relu(batch_norm_layer(conv2d(drop4, W5) + b5, True))
  104. # pool5 = maxPool(conv5)
  105. # drop5 = dropout(pool5, keep_prob_5) # 1024 * 2 * 2
  106. # # 第六层
  107. # W6 = weightVariable([3, 3, 1024, 1024])
  108. # b6 = biasVariable([1024])
  109. # conv6 = tf.nn.relu(conv2d(drop5, W6) + b6)
  110. # pool6 = maxPool(conv6)
  111. # drop6 = dropout(pool6, keep_prob_5) # 2048 * 1 * 1
  112. # # 全连接层
  113. # Wf = weightVariable([1*1*1024, 2048])
  114. # bf = biasVariable([2048])
  115. # drop3_flat = tf.reshape(drop6, [-1, 1*1*1024])
  116. # dense = tf.nn.relu(tf.matmul(drop3_flat, Wf) + bf)
  117. # # dense = tf.nn.relu(tf.matmul(max_pool22_flat, Wf) + bf)
  118. # dropf = dropout(dense, keep_prob_75)
  119. # # 输出层
  120. # Wout = weightVariable([2048, classnum])
  121. # bout = weightVariable([classnum])
  122. # #out = tf.matmul(dropf, Wout) + bout
  123. # out = tf.add(tf.matmul(dropf, Wout), bout)
  124. # #return out
  125. def train(train_x, train_y, tfsavepath):
  126. ''' train'''
  127. ##### log.debug('train')
  128. # 随机划分测试集与训练集
  129. train_x,test_x,train_y,test_y = train_test_split(train_x, train_y, test_size=0.05, random_state=random.randint(0,100))
  130. # 得到卷积结果
  131. out = cnnLayer(train_y.shape[1],True)
  132. # 参数:图片数据的总数,图片的高、宽、通道
  133. train_x = train_x.reshape(train_x.shape[0], SIZE, SIZE, 3)
  134. test_x = test_x.reshape(test_x.shape[0], SIZE, SIZE, 3)
  135. print('train size:%s, test size:%s' % (len(train_x), len(test_x)))
  136. sys.stdout.flush()
  137. # 图片块,每次取32张图片
  138. batch_size = 32
  139. num_batch = len(train_x) // batch_size
  140. # 交叉熵
  141. cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=out, labels=y_))
  142. # Adam优化器,学习速率:0.001
  143. train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
  144. # train_step = tf.train.AdadeltaOptimizer(0.001).minimize(cross_entropy)
  145. # 比较标签是否相等,再求的所有数的平均值,tf.cast(强制转换类型)
  146. # 准确率计算公式
  147. accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(out, 1), tf.argmax(y_, 1)), tf.float32))
  148. # 将loss与accuracy保存以供tensorboard使用
  149. tf.summary.scalar('loss', cross_entropy)
  150. tf.summary.scalar('accuracy', accuracy)
  151. merged_summary_op = tf.summary.merge_all()
  152. # 数据保存器的初始化
  153. saver = tf.train.Saver()
  154. with tf.Session() as sess:
  155. # tensorflow初始化
  156. sess.run(tf.global_variables_initializer())
  157. # tensorboard数据保存
  158. summary_writer = tf.summary.FileWriter('./tmp', graph=tf.get_default_graph())
  159. # 迭代80次
  160. for n in range(80):
  161. # 每次取32(batch_size)张图片
  162. for i in range(num_batch):
  163. # 训练集、测试集分块
  164. batch_x = train_x[i*batch_size : (i+1)*batch_size]
  165. batch_y = train_y[i*batch_size : (i+1)*batch_size]
  166. # 开始训练数据,同时训练三个变量,返回三个数据
  167. _,loss,summary = sess.run([train_step, cross_entropy, merged_summary_op],
  168. feed_dict={x:batch_x,y_:batch_y, keep_prob_5:0.5,keep_prob_75:0.75})
  169. # tensorboard记录数据
  170. summary_writer.add_summary(summary, n*num_batch+i)
  171. # 打印损失
  172. print(n*num_batch+i, loss)
  173. sys.stdout.flush()
  174. # if (n*num_batch+i) % batch_size == 0:
  175. # # 获取测试数据的准确率
  176. # acc = accuracy.eval({x:test_x, y_:test_y, keep_prob_5:1.0, keep_prob_75:1.0})
  177. # print(n*num_batch+i, acc, '--', n)
  178. # accc = acc
  179. # # 准确率大于0.98时保存并退出
  180. # if acc > 0.95 and n > 2:
  181. # # saver.save(sess, './train_faces.model', global_step=n*num_batch+i)
  182. # saver.save(sess, tfsavepath)
  183. # # saver.save(sess, tfsavepath)
  184. # sys.exit(0)
  185. # # saver.save(sess, './train_faces.model', global_step=n*num_batch+i)
  186. # # saver.save(sess, tfsavepath)
  187. # print('accuracy less 0.98, exited!')
  188. # 准确率计算表达式
  189. acc = accuracy.eval({x:test_x, y_:test_y, keep_prob_5:1.0, keep_prob_75:1.0})
  190. print('after 80 times run: accuracy is ', acc)
  191. sys.stdout.flush()
  192. # 模型保存
  193. saver.save(sess, tfsavepath)
  194. if __name__ == '__main__':
  195. pass

识别

这部分就是将训练好的模型加载,,然后实时的获取每一张相片处理等等,,,

tensorflow_face.py 这部分代码第一次运行会给每一个人创建一个标签,,获得标签集,,然后和训练集一同训练,,,而第二次运行就是识别,,,

  1. import os
  2. import logging as log
  3. import matplotlib.pyplot as plt
  4. import common
  5. import numpy as np
  6. from tensorflow.examples.tutorials.mnist import input_data
  7. import tensorflow as tf
  8. import cv2
  9. # import convert as myconv
  10. import tensorflow_face_conv as myconv
  11. import dlib
  12. import random
  13. from sklearn.model_selection import train_test_split
  14. import time
  15. import sys
  16. # rm
  17. import shutil
  18. def createdir(*args): # 创建一个文件夹
  19. ''' create dir'''
  20. for item in args:
  21. if not os.path.exists(item):
  22. os.makedirs(item)
  23. IMGSIZE = 64
  24. SIZE = 64
  25. rootpath = 'G:\\DIP\\mine'
  26. def getpaddingSize(shape): # 将相片两侧填充为正方形
  27. ''' get size to make image to be a square rect '''
  28. h, w = shape
  29. longest = max(h, w)
  30. result = (np.array([longest]*4, int) - np.array([h, h, w, w], int)) // 2
  31. return result.tolist()
  32. def dealwithimage(img, h=64, w=64): # 裁剪出人脸的图片
  33. ''' dealwithimage '''
  34. #img = cv2.imread(imgpath)
  35. top, bottom, left, right = getpaddingSize(img.shape[0:2])
  36. img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[0, 0, 0])
  37. img = cv2.resize(img, (h, w))
  38. return img
  39. def relight(imgsrc, alpha=1, bias=0): # 更改图片为二值图
  40. '''relight'''
  41. imgsrc = imgsrc.astype(float)
  42. imgsrc = imgsrc * alpha + bias
  43. imgsrc[imgsrc < 0] = 0
  44. imgsrc[imgsrc > 255] = 255
  45. imgsrc = imgsrc.astype(np.uint8)
  46. return imgsrc
  47. def getfilesinpath(filedir): # 得到一个文件夹下的所有文件
  48. ''' get all file from file directory'''
  49. for (path, dirnames, filenames) in os.walk(filedir):
  50. for filename in filenames:
  51. if filename.endswith('.jpg'):
  52. yield os.path.join(path, filename)
  53. for diritem in dirnames:
  54. getfilesinpath(os.path.join(path, diritem)) # 递归调用得到改文件夹下的文件
  55. def readimage(pairpathlabel): # 得到一个文件夹下的照片文件名和标记labels, 返回一个列表
  56. '''read image to list'''
  57. imgs = []
  58. labels = []
  59. for filepath, label in pairpathlabel:
  60. for fileitem in getfilesinpath(filepath):
  61. img = cv2.imread(fileitem)
  62. imgs.append(img)
  63. labels.append(label)
  64. return np.array(imgs), np.array(labels)
  65. def onehot(numlist): # 用于得到一个人的标签
  66. ''' get one hot return host matrix is len * max+1 demensions'''
  67. b = np.zeros([len(numlist), max(numlist)+1])
  68. b[np.arange(len(numlist)), numlist] = 1
  69. return b.tolist()
  70. def getfileandlabel(filedir): # 用字典保存一个人名的照片和对应的labels
  71. ''' get path and host paire and class index to name'''
  72. dictdir = dict([[name, os.path.join(filedir, name)] \
  73. for name in os.listdir(filedir) if os.path.isdir(os.path.join(filedir, name))])
  74. #for (path, dirnames, _) in os.walk(filedir) for dirname in dirnames])
  75. dirnamelist, dirpathlist = dictdir.keys(), dictdir.values()
  76. indexlist = list(range(len(dirnamelist)))
  77. return list(zip(dirpathlist, onehot(indexlist))), dict(zip(indexlist, dirnamelist))
  78. def main(_):
  79. ''' main '''
  80. '''
  81. 人脸识别项目主main函数
  82. + 在第一次运行该文件时,会将上一次拍照保存的多个人的照片数据进行处理,卷积、训练等得到一个适合的模型
  83. + 在第二次运行该文件时,会打开摄像头获取一个照片,然后根据上一步得到的模型处理后分类(识别)出照片上出现的人脸是之前录入的所有人中哪一个
  84. + 目前无法判断其他未录入人的人脸,即others
  85. '''
  86. #shutil.rmtree('./checkpoint')
  87. savepath = './checkpoint/face.ckpt' # 记录下模型的索引路径
  88. isneedtrain = False # 不存在时认为时第一次运行,即进行卷积训练
  89. if os.path.exists(savepath+'.meta') is False:
  90. isneedtrain = True
  91. # 根据录入保存的照片得到一个label和字典的路径的列表
  92. pathlabelpair, indextoname = getfileandlabel(rootpath + '\\image\\trainfaces')
  93. print(indextoname)
  94. sys.stdout.flush()
  95. print(pathlabelpair)
  96. sys.stdout.flush()
  97. # 得到训练集、测试集的照片和labels的列表
  98. train_x, train_y = readimage(pathlabelpair)
  99. # 将数据集归一化 ???
  100. train_x = train_x.astype(np.float32) / 255.0
  101. #### log.debug('len of train_x : %s', train_x.shape)
  102. if isneedtrain:
  103. # first generate all face
  104. # 调用另一文件进行卷积训练模型
  105. myconv.train(train_x, train_y, savepath)
  106. #### # log.debug('training is over, please run again')
  107. else:
  108. # second recognize faces
  109. # 调用下面的函数进行实时识别
  110. testfromcamera(train_x, train_y, savepath)
  111. #print(np.column_stack((out, argmax)))
  112. def testfromcamera(train_x, train_y, chkpoint):
  113. # 打开默认摄像头
  114. camera = cv2.VideoCapture(0)
  115. #haar = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
  116. pathlabelpair, indextoname = getfileandlabel(rootpath + '\\image\\trainfaces')
  117. # 得到预测值
  118. output = myconv.cnnLayer(len(pathlabelpair),False)
  119. predict = output
  120. # 得到dlib的人脸检测器
  121. detector = dlib.get_frontal_face_detector()
  122. # 加载模型
  123. saver = tf.train.Saver()
  124. with tf.Session() as sess:
  125. #sess.run(tf.global_variables_initializer())
  126. saver.restore(sess, chkpoint)
  127. n = 1
  128. while 1:
  129. if (n <= 20000):
  130. print('It`s processing %s image.' % n)
  131. sys.stdout.flush()
  132. # 间隔0.2s
  133. time.sleep(0.2)
  134. # 读帧
  135. success, img = camera.read()
  136. # 得到灰度图
  137. gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  138. # 使用detector进行人脸检测
  139. faces = detector(gray_img, 1)
  140. #faces = haar.detectMultiScale(gray_img, 1.3, 5)
  141. for i, d in enumerate(faces):
  142. x1 = d.top() if d.top() > 0 else 0
  143. y1 = d.bottom() if d.bottom() > 0 else 0
  144. x2 = d.left() if d.left() > 0 else 0
  145. y2 = d.right() if d.right() > 0 else 0
  146. face = img[x1:y1,x2:y2]
  147. face = cv2.resize(face, (IMGSIZE, IMGSIZE))
  148. #could deal with face to train
  149. test_x = np.array([face])
  150. test_x = test_x.astype(np.float32) / 255.0
  151. res = sess.run([predict, tf.argmax(output, 1)],\
  152. feed_dict={myconv.x: test_x,\
  153. myconv.keep_prob_5:1.0, myconv.keep_prob_75: 1.0})
  154. print(res, indextoname[res[1][0]], res[0][0][res[1][0]])
  155. sys.stdout.flush()
  156. # 得到一组随机的颜色值
  157. r = random.randint(0, 255)
  158. g = random.randint(0, 255)
  159. b = random.randint(0, 255)
  160. # 绘制检测到的人脸的方框
  161. cv2.rectangle(img, (x2,x1),(y2,y1), (r, g, b),3)
  162. # if res[0][0][res[1][0]] >= 500:
  163. # cv2.putText(img, 'others', (x1, y1 + 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (col, col, col), 2) #显示名字
  164. # else:
  165. # cv2.putText(img, indextoname[res[1][0]], (x1, y1 - 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (col, col, col), 2) #显示名字
  166. cv2.putText(img, indextoname[res[1][0]], (x2 + 25, y1 + 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (r, g, b), 2) #显示名字
  167. n+=1
  168. cv2.imshow('img', img)
  169. key = cv2.waitKey(30) & 0xff
  170. if key == 27:
  171. break
  172. else:
  173. break
  174. camera.release()
  175. cv2.destroyAllWindows()
  176. if __name__ == '__main__':
  177. # first generate all face
  178. main(0)
  179. #onehot([1, 3, 9])
  180. #print(getfileandlabel('./image/trainimages'))
  181. #generateface([['./image/trainimages', './image/trainfaces']])

总结

最后的模型的准确度还行,,但是不能识别未录入者,,它会认为是与已录入者最接近的人,,,

acc:

loss:

这个数据是通过tensorboard生成的,,

项目里还有一个简单的gui的实现,,因为没有时间了,,所有没有好好的优化一下,,,

(end 困。。。。)

基于卷积神经网络的人脸识别项目_使用Tensorflow-gpu+dilib+sklearn的更多相关文章

  1. Pytorch实现基于卷积神经网络的面部表情识别(详细步骤)

    文章目录 一.项目背景 二.数据处理 1.标签与特征分离 2.数据可视化 3.训练集和测试集 三.模型搭建 四.模型训练 五.完整代码 一.项目背景数据集cnn_train.csv包含人类面部表情的图 ...

  2. 基于卷积神经网络的面部表情识别(Pytorch实现)----台大李宏毅机器学习作业3(HW3)

    一.项目说明 给定数据集train.csv,要求使用卷积神经网络CNN,根据每个样本的面部图片判断出其表情.在本项目中,表情共分7类,分别为:(0)生气,(1)厌恶,(2)恐惧,(3)高兴,(4)难过 ...

  3. 深度学习项目——基于卷积神经网络(CNN)的人脸在线识别系统

    基于卷积神经网络(CNN)的人脸在线识别系统 本设计研究人脸识别技术,基于卷积神经网络构建了一套人脸在线检测识别系统,系统将由以下几个部分构成: 制作人脸数据集.CNN神经网络模型训练.人脸检测.人脸 ...

  4. 硕毕论文_基于 3D 卷积神经网络的行为识别算法研究

    论文标题:基于 3D 卷积神经网络的行为识别算法研究 来源/作者机构情况: 中  国  地  质  大  学(北京),计算机学院,图像处理方向 解决问题/主要思想贡献: 1. 使用张量CP分解的原理, ...

  5. Github开源人脸识别项目face_recognition

    Github开源人脸识别项目face_recognition 原文:https://www.jianshu.com/p/0b37452be63e 译者注: 本项目face_recognition是一个 ...

  6. 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【三】VGG网络进行特征提取

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  7. 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【二】人脸预处理

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  8. 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【一】如何配置caffe属性表

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  9. 基于深度学习的人脸识别系统系列(Caffe+OpenCV+Dlib)——【四】使用CUBLAS加速计算人脸向量的余弦距离

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

随机推荐

  1. comlink 是来自google chrome 团队的简化webwokers 开发的类库

    comlink 可以帮助我们简单webworkers 的开发,同时很小(1.1kb),具体使用我们可以看下面 一张图  说明 comlink 使用起来也比较方便,官方也提供了完整的api 文档 参考资 ...

  2. /etc/rc.local

    /etc/rc.local是/etc/rc.d/rc.local的软连接 应用于指定开机启动的进程 开机启动不生效,则首先需要检查下/etc/rc.d/rc.local是否具有可执行权限 在配置文件中 ...

  3. 记一次CDH集群日志数据清理

    背景 集群运行一段时间(大概一月多)后,cloudera manager管理界面出现爆红,爆红的组件有hdfs.zookeeper. 发现问题 点击详细内容查看,报日志空间不够的错误.初步判断是各个组 ...

  4. React中兄弟组件传值

    兄弟组件传值 实际上是间接的通过第三方来实现传值,举例,第一个儿子把值传给父亲,父亲在把这个值传给第二个儿子,这样就实现了兄弟组件传值 来看代码: 父组件代码 import React from 'r ...

  5. Win10系统下安装ubuntu16.04双系统-常见问题解答

    Win10系统下安装ubuntu16.04双系统-常见问题解答 1. 安装ubuntu16.04.2系统 磁盘分区形式有两种:GPT和MBR,关系到设置引导项.在win10下压缩出500GB空间给ub ...

  6. 20189220 余超《Linux内核原理与分析》第八周作业

    Linux内核如何装载和启动一个可执行程序 本章知识点 ELF(Executable and Linking Format)是一种对象文件的格式,用于定义不同类型的对象文件(Object files) ...

  7. 软件工程--团队项目选择与NABCD

    目录 Part1:项目说明 项目基础 我们的目标 Part2:项目NABCD Need Approach Benefit Competitors Delivery & Data Deliver ...

  8. 第10组 Beta冲刺(4/5)

    链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 将数据分析以可视化形式展示出来 新增数据分析展示等功能API 服务器后端部署, ...

  9. Java_jdbc 基础笔记之十一数据库连接 (通用的查询方法)

    鉴于之前的查询方法,在这里我们可以写一个通用的方法 /** * 鉴于 student.和customer查询的方法有好多相同之处,在此可以写一个通用的方法 */ public <T> T ...

  10. php常用命令

    --------------------------------------------------------------- 重启phpservice php-fpm restart ------- ...