赞
踩
摘 要
人脸识别系统的研究始于20世纪60年代,80年代后随着计算机技术和光学成像技术的发展得到提高,而真正进入初级的应用阶段则在90年后期;最近几年随着以深度学习为主的人工智能技术进步,人脸识别技术得到了迅猛的发展。“人脸识别系统”集成了人工智能、机器识别、机器学习、模型理论、专家系统、视频图像处理等多种专业技术,是综合性比较强的系统工程技术。
本项目着手实现了一个基于卷积神经网络的人脸识别签到打卡系统,该系统人脸注册模块能够进行人脸的注册,采集人脸照片并灰度处理,将不同人脸对应的学号(工号)姓名信息存储于数据库,利用CNN卷积神经网络对人脸数据进行训练;人脸签到模块能实时识别当前人脸,识别成功将自动更改当前对象的签到状态,同时语音播报某学号某同学签到成功,并在系统界面输出显示签到信息;缺勤模块可以查看当前未签到成员信息,可以重置所有成员的签到状态。
关键字:卷积神经网络,人脸识别,opencv,Pyqt5,Tensorflow
目 录
前不久Iphone X发布,革命性的取消了TouchID(指纹识别),而添加了更酷的 FaceID(人脸识别) 模块,FaceID 不只简单的运用在解锁上,还可以在支付,表情等场景中应用,给开发者带来更酷更丰富的应用,Iphone X 在多个硬件传感器的加持下,可以采集3万个点来感知用户的面部特征。
我们知道,深度学习出现后,人脸识别技术真正有了可用性,人脸识别在这几年应用相当广泛,人脸考勤,人脸社交,人脸支付,哪里都有这黑科技的影响,特别这几年机器学习流行,使得人脸识别在应用和准确率更是达到了一个较高的水准。
当前深度学习,识别技术等特别火热,可以利用的资源也非常多,入手门栏低,因此本次信息安全课程设计我毅然决然选择了做一个基于CNN卷积神经网络的人脸识别签到系统,这既顺应了时代发展的方向,又是我激励自己不断学习新技术新知识的好机会。
人脸注册模块实际上就是收集人员的相关信息,包括面部信息和身份信息,将身份信息存入myaql数据库,并用神经网络模型对人脸数据进行训练。这个模块中的模型训练对本系统的实用性有着至关重要的影响,训练模型的选择直接影响到系统对人脸识别的精确度。
人脸识别系统的过程:人脸图像采集及检测、关键点提取、人脸规整(图像处理)、人脸特征提取和人脸识别比对。
人脸图像采集:不同的人脸图像都能通过摄像镜头采集下来,比如静态图像、动态图像、不同的位置、不同表情等方面都可以得到很好的采集。当用户在采集设备的拍摄范围内时,采集设备会自动搜索并拍摄用户的人脸图像。
人脸检测:人脸检测在实际中主要用于人脸识别的预处理,即在图像中准确标定出人脸的位置和大小。
关键点提取(特征提取):人脸识别系统可使用的特征通常分为视觉特征、像素统计特征、人脸图像变换系数特征、人脸图像代数特征等。人脸特征提取就是针对人脸的某些特征进行的。人脸特征提取,也称人脸表征,它是对人脸进行特征建模的过程。人脸特征提取的方法归纳起来分为两大类:一种是基于知识的表征方法;另外一种是基于代数特征或统计学习的表征方法。
人脸规整(预处理):对于人脸的图像预处理是基于人脸检测结果,对图像进行处理并最终服务于特征提取的过程。系统获取的原始图像由于受到各种条件的限制和随机干扰,往往不能直接使用,必须在图像处理的早期阶段对它进行灰度校正、噪声过滤等图像预处理。对于人脸图像而言,其预处理过程主要包括人脸图像的光线补偿、灰度变换、直方图均衡化、归一化、几何校正、滤波以及锐化等。
人脸识别比对(匹配与识别):提取的人脸图像的特征数据与数据库中存储的特征模板进行搜索匹配,通过设定一个阈值,当相似度超过这一阈值,则把匹配得到的结果输出。人脸识别就是将待识别的人脸特征与已得到的人脸特征模板进行比较,根据相似程度对人脸的身份信息进行判断。
人脸识别模块是本系统最主要的功能。人脸识别可以分为两大部分:人脸检测和人脸验证。
关于人脸检测,没有亲自从底层去实现或者优化如何检测人脸。而是采用了opencv和dlib进行人脸检测,在使用过程中发现dlib的识别精度更为高一些,而opencv的识别速度更为快,具体体现在:当Mac摄像头打开后,dlib非常卡顿。
缺勤模块非常简单,查看当前未签到的注册人员;重置所有成员签到状态。实现只需要检索数据库中表示签到状态的值,0为未签到,1为已签到。
能通过摄像头收集需要注册成员的人脸照片,用卷积神经网络进行训练,将人员身份信息存储到mysql数据库;
能通过计算机本地的摄像头,实时检测当前视频流中的人脸,与训练好的卷积神经网络模型中存放的人脸信息进行比对,配对成功则提示成员签到成功并自动修改数据库在的签到状态;
能查看当前未签到成员的名单,能重置成员的签到状态。
操作系统:Windows10
开发语言:Python3.7
开发软件:Pycharm
本课设作品关实现的关键技术是CNN模型和人脸识别。因为熟悉python,我知道这些技术通过python编程是完全可行的:界面实现可以依赖于pyqt5;人脸识别可以结合opencv(摄像头、图片处理),numpy(图片数字化),os(文件的操作和处理);构建神经网络进行模型训练可以利用TensorFlow。
控制摄像头,需要先介绍一下OpenCV计算机视觉开源库:OpenCV是一个跨平台的库,使用它我们可以开发实时的计算机视觉应用程序。 它主要集中在图像处理,视频采集和分析,包括人脸检测和物体检测等功能。使用OpenCV库,可以读取和写入图像;捕获并保存视频;过程图像(过滤,变换);执行功能检测;检测视频或图像中的特定对象,例如脸部,眼睛,汽车;分析视频,即估计其中的运动,减去背景,并跟踪其中的对象。
开启摄像头用到了视觉库中的cv2.VideoCapture(0)方法,一般来说计算机只有1个摄像头,默认编号为0,如果有两个,想要打开第二个摄像头就把cv2.VideoCapture(0)函数的参数0替换为1就可以了。摄像头开启后你会发现摄像头的指示灯会亮。读取摄像头采集到的数据,调用cap.read()会返回两个值,ret为布尔值,Ture为读取成功,False表示读取失败;frame则是返回的一帧图像。如果你不确定是否读取成功,可以像我一样直接把这两个参数打印输出。若读取失败,[ ret frame ]则为[ False None],反之则为[ True [图像数据] ]。
开启摄像头关键代码:
# 初始化摄像头
def PrepCamera(self):
try:
self.camera = cv2.VideoCapture(0)
self.camera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
self.MsgTE.clear()
self.MsgTE.append('摄像头已连接!')
except Exception as e:
self.MsgTE.clear()
self.MsgTE.append(str(e))
摄像头读取图像并保存图片关键代码:
# 从摄像头读取图像
def TimerOutFun(self):
success, img = self.camera.read()
if success:
self.Image = img
self.DispImg()
# 分类保存照片
def __init__(self, imgdir='./test_img/', grayfacedir='./test_img_gray'):
"""
:param imgdir: 采集到的图片的存放路径
:param grayfacedir: 处理后的图片(人脸灰度图)的存放路径
"""
self.imgdir = imgdir
self.grayfacedir = grayfacedir
对图片进行灰度处理的原因:我们识别物体,最关键的因素是梯度(现在很多的特征提取,SIFT,HOG等等本质都是梯度的统计信息),梯度意味着边缘,这是最本质的部分,而计算梯度,自然就用到灰度图像了。颜色本身非常容易受到光照等因素的影响,同类的物体颜色有很多变化。所以颜色本身难以提供关键信息。2010PAMI有colorSIFT的一些工作,本质也是不同通道的梯度。所以我们可以把灰度图像看作图像的强度(Intensity),来求一些梯度特征。比较常用的有 HOG,LBP,SIFT等等。
关键代码:
def facetogray(self, someone='', size=64, waitkey=100):
"""
将指定文件夹中的所有图片转为灰度图,并保存至指定位置
:param someone: 某人姓名,即要处理的图片文件夹
:param size: 将图片压缩的纬度大小
:param waitkey: 延迟时长(ms)
:return: 处理后的灰度图
"""
imgnames = getdata.getimgnames(path=os.path.join(self.imgdir, someone))
# 获取指定文件夹中的所有jpg图片名称
n = len(imgnames) # 图片张数
newpath = os.path.join(self.grayfacedir, someone) # 处理后的灰度图的存放路径
if not os.path.exists(newpath): # 看是否需要创建路径
os.makedirs(newpath)
for i in range(n): # 开始对每张图片进行灰度处理
# img = cv2.imread(imgnames[i]) # 读入图片 无法读取中文路径
img = cv2.imdecode(np.fromfile(imgnames[i], dtype=np.uint8), -1)
results = detect_face(img) # 对图片进行人脸检测,即找到图片中人脸的位置
if results is not (): # 判断图片中有无人脸
faceboxes = results # 提取人脸位置信息
for (x, y, w, h) in faceboxes:
face = img[y:y + h, x:x + w] # 截取图片中的人脸图像
face_gray = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY)
# 转为灰度图片
face_gray = cv2.resize(face_gray, (size, size)) # 压缩成指定大小
# cv2.imwrite(newpath + '/' + str(i) + '.jpg', face_gray)
# 保存检测出的人脸图片 无法读取中文路径
savePath = (newpath + "/%d.jpg" % i)
cv2.imencode('.jpg', face_gray)[1].tofile(savePath)
本系统采用了mysql数据库,创建users表存储注册用户的身份信息,包括id,user_id,user_name,state四个字段:user_id代表学号,user_name代表名字,state标识签到状态,0为未签到,1为已签到,注册的默认值为0。
创建users表sql语句:
create table if not exists users(
id int auto_increment primary key,
user_id varchar(20) not null,
user_name varchar(10) not null,
state int(5) not null
)default charset=utf8;
set global time_zone='+8:00';
创建好并注册过一些用户信息的users表:
id | user_id | user_name | state |
11 | 1600300109 | test | 0 |
14 | 1600300101 | 张三 | 0 |
15 | 1600300102 | test1 | 0 |
先介绍一下神经网络:神经网络,也指人工神经网络(Artificial Neural Networks,简称ANNs),是一种模仿生物神经网络行为特征的算法数学模型,由神经元、节点与节点之间的连接(突触)所构成。人工神经网络可以映射任意复杂的非线性关系,具有很强的鲁棒性、记忆能力、自学习等能力,在分类、预测、模式识别等方面有着广泛的应用。如图3-1:
图3-1 仿生物神经网络
每个神经网络单元抽象出来的数学模型如下,也叫感知器,它接收多个输入(x1,x2,x3...),产生一个输出,这就好比是神经末梢感受各种外部环境的变化(外部刺激),然后产生电信号,以便于转导到神经细胞(又叫神经元)。如图3-2:
图3-2 神经网络单元
单个的感知器就构成了一个简单的模型,但在现实世界中,实际的决策模型则要复杂得多,往往是由多个感知器组成的多层网络,如图3-3,这也是经典的神经网络模型,由输入层、隐含层、输出层构成。
图3-3 神经网络模型
简单了解卷积神经网络(CNN):
卷积神经网络与普通神经网络的区别在于,卷积神经网络包含了一个由卷积层和子采样层(池化层)构成的特征抽取器。在卷积神经网络的卷积层中,一个神经元只与部分邻层神经元连接。在CNN的一个卷积层中,通常包含若干个特征图(featureMap),每个特征图由一些矩形排列的的神经元组成,同一特征图的神经元共享权值,这里共享的权值就是卷积核。卷积核一般以随机小数矩阵的形式初始化,在网络的训练过程中卷积核将学习得到合理的权值。共享权值(卷积核)带来的直接好处是减少网络各层之间的连接,同时又降低了过拟合的风险。子采样也叫做池化(pooling),通常有均值子采样(mean pooling)和最大值子采样(max pooling)两种形式。子采样可以看作一种特殊的卷积过程。卷积和子采样大大简化了模型复杂度,减少了模型的参数。
卷积神经网络通常包含以下几种层:
卷积神经网络的优缺点:
优点
• 共享卷积核,对高维数据处理无压力
• 无需手动选取特征,训练好权重,即得特征分类效果好
缺点
• 需要调参,需要大样本量,训练最好要GPU
• 物理含义不明确(也就说,我们并不知道没个卷积层到底提取到的是什么特征,而且神经网络本身就是一种难以解释的“黑箱模型”)
由于卷积网络模型算法实现原理和计算公式比较复杂,内容较多,时间原因本文不再详述。
人脸检测用到了opencv提供的haarcascade_frontalface_default.xml级联分类器文件,是opencv进行人脸识别的文件。
关键代码:
def detect_face(img):
clf = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 找到符合xml文件里描述的特征区域
objects = clf.detectMultiScale(img)
return objects
识别成功后执行sql语句修改数据库中标识签到状态的字段值。
数据库中标识签到状态的字段值为0(未签到)和1(已签到)。
关键代码:
# 显示缺勤表格
def ShowTable(self):
sql = 'select * from users where state=0'
print(sql)
cursor = mysql_conn.cursor()
cursor.execute(sql)
results = cursor.fetchall()
print(results)
if results:
row = cursor.rowcount
vol = len(results[0])
self.tableWidget.setRowCount(row)
self.tableWidget.setColumnCount(3)
for i in range(row):
for j in range(3):
temp_data = results[i][j + 1] # 临时记录,不能直接插入表格
print(temp_data)
data = QTableWidgetItem(str(temp_data)) # 转换后可插入表格
data.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.tableWidget.setItem(i, j, data)
由于默认的字体比较细,看着不舒服,所以我下载了了微软雅黑Bold.ttf这个字体。
代码实现:
# coding=utf-8
# cv2解决绘制中文乱码
import cv2
import numpy
from PIL import Image, ImageDraw, ImageFont
def cv2ImgAddText(img, text, left, top, textColor=(0, 0, 255), textSize=30):
if (isinstance(img, numpy.ndarray)): # 判断是否OpenCV图片类型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 创建一个可以在给定图像上绘图的对象
draw = ImageDraw.Draw(img)
# 字体的格式
fontStyle = ImageFont.truetype(
"微软雅黑Bold.ttf", textSize, encoding="utf-8")
# 绘制文本
draw.text((left, top), text, textColor, font=fontStyle)
# 转换回OpenCV格式
return cv2.cvtColor(numpy.asarray(img), cv2.COLOR_RGB2BGR)
使用tf创建3层cnn,3 * 3的filter,输入为rgb。
· 第一层的channel是3,图像宽高为64,输出32个filter,maxpooling是缩放一倍
· 第二层的输入为32个channel,宽高是32,输出为64个filter,maxpooling是缩放一倍
· 第三层的输入为64个channel,宽高是16,输出为64个filter,maxpooling是缩放一倍
所以最后输入的图像是8 * 8 * 64,卷积层和全连接层都设置了dropout参数,将输入的8 * 8 * 64的多维度,进行flatten,映射到512个数据上,然后进行softmax,输出到onehot类别上,类别的输入根据采集的人员的个数来确定。
关键代码:
def __init__(self, imgs=train_x, labels=train_y, keep_prob_5=0.5, keep_prob_75=0.75,
modelfile='./temp/train-model'):
tf.reset_default_graph() # 将计算图清零,以免出现代码多次运行时tensor叠加
self.imgs = imgs # 训练集自变量
self.labels = labels # 训练集目标变量
self.size = imgs.shape[1] # 图片宽度
self.outnode = labels.shape[1] # 输出层神经元个数
self.x = tf.placeholder(tf.float32, [None, self.size, self.size, 1],
name='x_data') # 注意给Tensor起的名字"x_data",后续找x就靠它了
self.y_ = tf.placeholder(tf.float32, [None, self.outnode], name='y_data')
self.modelfile = modelfile
self.keep_prob_5 = np.float32(keep_prob_5)
self.keep_prob_75 = np.float32(keep_prob_75)
def weightVariable(self, shape): # 权值数组W
init = tf.random_normal(shape, stddev=0.01)
return tf.Variable(init)
def biasVariable(self, shape): # 偏置项数组b
init = tf.random_normal(shape)
return tf.Variable(init)
def conv2d(self, x, W): # 卷积
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def maxPool(self, x): # max池化
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
def dropout(self, x, keep): # 随机让某些权重不更新,保持某个数
return tf.nn.dropout(x, keep)
def cnnLayer(self):
"""
cnn神经网络结构
:return:
"""
# ===第一次卷积====
W1 = self.weightVariable([3, 3, 1, 32]) # 卷积核/filter大小(3,3,1), 输入通道(1),输出通道(32)
b1 = self.biasVariable([32]) # 偏置项
conv1 = tf.nn.relu(self.conv2d(self.x, W1) + b1) # 卷积
pool1 = self.maxPool(conv1) # 池化
drop1 = self.dropout(pool1, self.keep_prob_5) # 减少过拟合,随机让某些权重不更新
# ===第二次卷积====
W2 = self.weightVariable([3, 3, 32, 64])
b2 = self.biasVariable([64])
conv2 = tf.nn.relu(self.conv2d(drop1, W2) + b2)
pool2 = self.maxPool(conv2)
drop2 = self.dropout(pool2, self.keep_prob_5)
# ===第三次卷积====
W3 = self.weightVariable([3, 3, 64, 64])
b3 = self.biasVariable([64])
conv3 = tf.nn.relu(self.conv2d(drop2, W3) + b3)
pool3 = self.maxPool(conv3)
drop3 = self.dropout(pool3, self.keep_prob_5)
# ===全连接层====
Wf = self.weightVariable([8 * 8 * 64, 512])
bf = self.biasVariable([512])
drop3_flat = tf.reshape(drop3, [-1, 8 * 8 * 64])
dense = tf.nn.relu(tf.matmul(drop3_flat, Wf) + bf)
dropf = self.dropout(dense, self.keep_prob_75)
# ===全连接层====
Wout = self.weightVariable([512, self.outnode])
bout = self.weightVariable([self.outnode])
out = tf.add(tf.matmul(dropf, Wout), bout, name='out')
return out
def cnnTrain(self, maxiter=1000, accu=0.99, batch_size=100):
"""
依据训练样本的模型输出与样本实际值进行模型训练
:param maxiter: 最大迭代次数
:param accu: 精度阈值,当训练精度大于accu时则停止训练
:param batch_size: 每轮训练的样本数
:return: 无返回,但是当模型精度满足要求后会将模型保存
"""
out = self.cnnLayer() # 模型输出/预测
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=out, labels=self.y_))
train_step = tf.train.AdamOptimizer(0.01).minimize(cross_entropy)
# 比较标签是否相等,再求的所有数的平均值,tf.cast(强制转换类型)
accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(out, 1), tf.argmax(self.y_, 1)), tf.float32))
# 将loss与accuracy保存以供tensorboard使用
# tf.summary.scalar('loss', cross_entropy)
# tf.summary.scalar('accuracy', accuracy)
saver = tf.train.Saver() # 数据保存器的初始化
sess = tf.Session() # 启动会话
sess.run(tf.global_variables_initializer())
for n in range(maxiter):
ind = random.sample(range(len(self.imgs)), batch_size) # 每次取batch_size张图片
batch_x = self.imgs[ind]
batch_y = self.labels[ind]
_ = sess.run(train_step, feed_dict={self.x: batch_x, self.y_: batch_y}) # 正式训练
# 打印损失
# print(loss)
if n % 100 == 0: # 每训练100轮输出一次训练精度
acc = sess.run(accuracy, feed_dict={self.x: batch_x, self.y_: batch_y}) # 获取训练精度
process_log = '轮数:' + str(n) + ' 训练精度:' + str(acc)
yield process_log
print('轮数:', n, ' the train accuracy is :', acc)
if acc > accu and n > 499:
saver.save(sess, self.modelfile) # 保存模型
break
elif n == (maxiter - 1):
saver.save(sess, self.modelfile)
sess.close()
def predict(self, test_x=test_x):
"""
预测函数,导入已训练好的模型后再将新样本数据放入,进行模型预测
:param test_x: 测试样本的自变量
:return: 模型对测试样本的预测结果
1: 预测结果(数字标签:0,1,2,3,4,5,...)
pre: 样本属于各类别的概率,形如:[[0.1, 0.1, 0.0, 0.0, 0.0, 0.8]]
"""
out = self.cnnLayer() # 网络输出
with tf.Session() as sess:
saver = tf.train.Saver() # 启动模型保存类Saver
saver.restore(sess, self.modelfile) # 调用之前保存的模型
graph = tf.get_default_graph() # 获取计算图
x = graph.get_tensor_by_name('x_data:0')
# 通过tensor的名称获取相应tensor,注意到底是 x_data 还是x_data_1
pre = sess.run(out, feed_dict={x: test_x}) # 放入测试集样本
return np.argmax(pre, 1), pre
实现主要使用了python提供的 pyttsx3文字转语音库,支持英文,中文,可以调节语速、语调等。
部分关键代码示例:
import pyttsx3
def say(engine,str):
engine.say(str)
engine.runAndWait()
engine = pyttsx3.init()
rate = engine.getProperty('rate')
engine.setProperty('rate', rate - 80) #调节语速
teacher = pyttsx3.init()
voices = teacher.getProperty('voices') #变换语调
for i in voices:
teacher.setProperty('voice', i.id)
teacher.say(msg)
def log_in(self):
if self.name != '':
user_id, user_name, user_state = search_handler(self.name)
if user_state == 1:
self.Msg = '%s %s 同学签到成功.' % (user_id, user_name)
say(engine, "学号%s%s同学签到成功!" % (user_id, user_name)) #语音播报签到情况
elif user_id is None:
self.Msg = '签到失败'
say(engine, "签到失败!")
else:
self.Msg = '未检测到人脸'
启动系统前会检测连接数据库是否成功,若连接失败会弹框和语音提示;连接成功则开始运行系统并语音播报欢迎使用人脸识别签到系统。系统主界面有各个功能的模块按钮,点击相应按钮即可执行对应的任务。成功运行系统的界面如图6-1。
图6-1 系统启动主界面
在系统主界面点击“人脸注册”按钮即可进入到人脸注册界面,进入界面后首先可以看到详细的注册流程的操作提示说明。如图6-2。
图6-2人脸注册界面
点击注册界面的“开启摄像头”按钮,系统会打开计算机内置摄像头,这时摄像头指示灯亮起,系统上方会显示摄像头当前捕捉到的画面。如图6-3。
图6-3 开启摄像头
开启摄像头后,注册人员调整好位置,让摄像头能捕捉到自己的正脸。手动输入正确的学号姓名信息即可进行“人脸拍照”,这里为了防止误输入,对学号的格式进行了检查判断,输入错误格式的学号系统则会同时用语音播报和文字提示“请检查学号姓名是否输入正确”。输入错误格式的学号测试结果如图6-4。格式检查无误后单击“人脸拍照”按钮,摄像头会拍摄分类存储100张当前人脸照片并进行剪裁和灰度处理。正常拍照结果如图6-5。
图6-4输入错误格式的学号拍照测试
图6-5 正常拍照测试
人脸拍照结束后,需要再次填写确认学号姓名身份信息,确认无误后,点击“注册入库”个人信息便会存入mysql数据库中,且默认签到状态为0(未签到)。身份信息注册入库成功如图6-6。
图6-6 身份信息注册入库
卷积神经网络模型会进行1000轮训练,每轮训练100张照片,一次训练下来相当于需要处理十万张照片 ,所以需要较长的时间,对计算机配置也有一定要求。为了节约时间,可以先依次给所有需要注册信息的成员进行“人脸拍照”和“注册入库”,一位成员只需要一分钟左右的时间,全体成员注册完毕后,在选择模型训练。模型训练过程如图6-7、-8、6-9。可以看出系统人脸识别精度(识别成功率)在训练过程中逐渐提升。
图6-7人脸集CNN模型训练
图6-8人脸集CNN模型训练
图6-9人脸集CNN模型训练
完成“人脸注册”和“模型训练”环节后,就可以在系统主界面使用“人脸签到”功能了。开启摄像头后,会实时对画面进行人脸检测,未检测到人脸会提示“未检测的人脸”;检测到人脸会自动和系统注册存储过的人脸比对,配对失败(未在系统注册过)提示“签到失败”,配对成功则提示“某学号某同学签到成功”(语音播报+文字),并自动修改数据库中该同学签到状态为1(已签到)。识别签到成功如图6-10。
图6-10 签到功能测试
点击“缺勤名单”会显示注册过信息且当前未签到的同学名单,“重置”会改变所有成员的签到状态。如图6-11。
图6-11 查看缺勤名单
本系统已经达到需求分析的要求,能对各个功能进行测试成功。并且能正确的处理各个功能所产生的问题和预防各种操作上的错误。总体上来说,本系统的性能表现还是十分良好的。
这次信息安全课程设计的顺利完成,要感谢同学舍友的热情指点和帮助,感谢互联网上提供各种解决问题方案的网友们,同时也特别感谢我的指导老师。
通过此次课程设计,使我更加扎实的掌握了有关计算机视觉方面的知识,在设计过程中虽然遇到了一些问题,但经过一次次的思考,最终找出了原因所在,也暴露出了我在这方面知识的欠缺和经验不足。实践出真知,通过亲自动手实践,使我掌握的知识不再是纸上谈兵。
过而能改,善莫大焉。在课程设计过程中,我不断发现错误,不断改正,不断领悟,不断获取。在今后社会的发展和学习实践过程中,也要不懈努力,不能遇到问题就想到要退缩,要不厌其烦的发现问题所在,然后想办法进行解诀,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永远不可能得到社会及他人对你的认可!
信息安全课程设计对我们来说是一次不可或缺的提升自我的机会,给了我很多专业技能上的提升,给了我莫大的发挥空间。同时,设计让我感触很深。通过这次课程设计,我掌握了opencv人脸识别相关的技术,;熟悉了深度学习神经网络训练的实现原理; 了解了通过分离界面代码和计算代码来提升用户体验方法等等。
在这次课程设计中,不仅培养了我独立思考、动手操作的能力,在各种其它能力上也都有了提高。更重要的是,在这期间,我学会了高效的学习总结知识的方法,而这是日后最实用的,受益匪浅。
回顾起此课程设计,至今我仍感慨颇多,从理论到代码实现,在这段日子里,可以说得是苦多于甜,但是千真万确学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,但可喜的是最终都得到了解决。
此次课程设计也让我明白了思路即出路,有什么不懂不明白的地方要及时请教或上网查询,只要认真钻研,动脑思考,动手实践,就没有弄不懂的知识。
[1] Joe Minichino等著 刘波等译. OpenCV3计算机视觉Python语言实现第二版. 机械工业出版社 2016年
[2] 王硕,孙洋洋著. PyQt5快速开发与实战. 电子工业出版社 2017年
[3] 马春鹏 著. 模式识别与机器学习. 机械工业出版社 2018年
[4] Mark S.Nixon等著 实英等译. 特征提取与图像处理(中译第二版). 电子工业出版社 2010年
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。