大佬教程收集整理的这篇文章主要介绍了我的毕业设计之基于深度学习的人脸识别系统,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
如今在人脸识别领域中c;开始逐步加强对深度学习技术的运用c;这促使人脸识别的相关技术的发展速度得到显著提升c;在此背景下c;人脸识别技术在未来必然会拥有更为广阔的发展前景。
本文主要以卷积神经网络为基础对人脸识别模型进行设计c;使用深度学习框架c;通过Keras完成对卷积神经网络模型进行构建c;使用OpenCV接口识别人脸并处理人脸数据建立数据集c;然后对设立的模型开展训练c;在完成训练后c;运用该模型来实现人脸识别打卡。系统主要分为人脸采集、人脸图像处理、训练人脸模型训练和人脸识别打卡小程序四个模块c;四个模块均能按照预定方式实现相应功能c;整体来看c;系统所具备的性能能够达到预期水平。
关键词 人脸识别 卷积神经网络 OpenCV Keras
5 系统实现
经过前期的需求分析与系统设计c;本章将按照人脸检测收集、人脸处理、模型训练和人脸识别GUI打卡小程序模块c;分别介绍基于深度学习的人脸识别系统的开发的具体过程及实现代码。
5.1 人脸检测收集
设定获取图片后的保存路径save_pathc;然后执行get_face.py中的__name__ == '__main__方法,首先使用OpenCV中的VideoCapture函数调用并启用摄像头c;然后使用OpenCV中的级联分类器(CascadeClassifier)加载人脸识别分类器haarcascade_frontalface_default.xmlc;针对所收集每帧图像中包含的人脸相关信息进行检测c;且把得到的信息保存至特定位置c;同时在视频中标记出人脸框与当前以保存图片张数c;实现效果如图5.1所示。
图5.1 人脸检测收集实现
实现代码如下:def getface(name, cameraid, max_num, path_name): cv2.namedWindow(name) videocap = cv2.VideoCapture(cameraid) data_path = "haarcascade_frontalface_default.xml" classfier = cv2.CascadeClassifier(data_path)#加载OpenCV人脸识别器 color = (0, 255, 0) num = 0 while videocap.isOpened): ok, frame = videocap.read()
if not ok: break grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faceRects = classfier.detectMultiScale(grey, scaleFactor=1.2, @H_535_171@minNeighbors=3, @H_535_171@minSize=(32, 32) if len(faceRects) > 0: #检测到人脸c;对人脸进行加框
for faceRect in faceRects:
x, y, w, h = faceRect img_name = '%s/%d.jpg ' %(path_name, num)#保存人脸到目录 if num > max_num: #如果下载数量完成c;退出
break cv2.rectangle(frame, if num > max_num: break cv2.imshow(name, frame) c = cv2.waitKey(10) if c & 0xFF == ord('q'): break videocap.release() cv2.destroyAllWindows()
5.2 人脸处理
首先设置图像大小参数IMAGE_SIZEc;对图像尺寸进行调整。若图片初始长宽存在差异c;先确定哪一个边的长度是最长的c;之后对其跟短边的差距进行计算c;以明确短边对应的像素宽度需增加的具体数值c;给图像增加边界c;然后使用OpenCV中的cv2.copymakeBorder函数进行边缘填充c;最后使用OpenCV中的cv2.resize函数调整图像大小并返回。当训练模型时c;会调用load_dataseth函数,从指定路径读取训练数据对图片进行转换并得到相应的四维数组c;
尺寸为最后标注数据c;chenkepu文件夹下都是需要被识别的脸部图像c;全部指定为0c;其他文件夹下是其他人脸c;全部指定为1c;最后返回数据集。实现代码如下:IMAGE_SIZE = 64 #图像大小参数IMAGE_SIZEdef resize_image(image,value=BLACK) return cv2.resize(constant,(height, width))images = [] #保存图片labels = []#保存标签# 读取图片def read_path(path_name): for dir_item in os.listdir(path_name): full_path = os.path.abspath(os.path.join(path_name, dir_item) if os.path.isdir(full_path): #读取路径 read_path(full_path) else: if dir_item.endswith('.jpg'): image = cv2.imread(full_path) image = resize_image(image, IMAGE_SIZE, IMAGE_SIZE) images.append(image) labels.append(path_name) return images, labelsdef load_dataset(path_name): #加载数据时调用此函数 images, labels = read_path(path_name) images = np.array(images) labels = np.array([0 if label.endswith('chenkepu') else 1 for label in labels])#打上标签 return images, labels #返回图片与标签
5.3 模型训练
5.3.1 数据集处理
收集人脸数据完成后c;开始训练模型c;完成对所需数据的全面加载后c;基于函数对数据集进行合理划分c;以得到分别用于训练、测试不同方面的集c;本次运用比例为7:3的c;划分前c;先会将数据全部都打乱c;使得训练集和测试集的@R_673_10863@均匀。划分好数据集以后c;若Keras中运用的后端引擎为c;则具备的属性为c;若为Theanoc;则具备的属性为c;为保证程序具有更高的稳健性c;需先对具备的实际属性进行判定c;且以此为依据来调整维度顺序。最后要开展归一化处理c;保证各特征值所对应的尺度能够相对一致。若不开展该处理c;所具备尺度不同的特征值对应的梯度会存在显著差异c;但对梯度进行更新的过程中c;对应的学习率却具备较高统一性c;若其对应数值较小c;则较小的梯度难以实现快速的更新c;若其对应的数值较大c;则较大的梯度在方向上面会缺乏稳定性c;不易收敛c;一般会将学习率对应的数值调低c;以实现跟所具备尺度较大的维度实现匹配c;进而保证损失函数能够处于较低范围内c;因此c;通过归一化c;把不同维度的特征值范围调整到相近的范围内c;就能统一使用较大的学习率加速学习。因为图片像素值的范围都在0~255c;图片数据的归一化可以简单地除以255。实现代码如下:
class Dataset: def __init__(self, path_name): # 训练集 self.Train_images = None self.Train_labels = None # 验证集 self.valid_images = None self.valid_labels = None # 测试集 self.test_images = None self.test_labels = None # 数据集加载路径 self.path_name = path_name #def load(self, img_rows=IMAGE_SIZE, img_cols=IMAGE_SIZE, img_chAnnels=3, nb_classes=2): # 加载数据集到内存 images, labels = load_dataset(self.path_name) #训练 验证 训练标签 验证标签 Train_images, valid_images, Train_labels, valid_labels = Train_test_split(images, labels, test_size=0.3, random_state=random.randint(0, 100)) _, test_images, _, test_labels = Train_test_split(images, labels, test_size=0.5, random_state=random.randint(0, 100)) if K.image_data_format() == 'chAnnels_first': Train_images = Train_images.reshape(Train_images.shape[0], img_chAnnels, img_rows, img_cols) valid_images = valid_images.reshape(valid_images.shape[0], img_chAnnels, img_rows, img_cols) test_images = test_images.reshape(test_images.shape[0], img_chAnnels, img_rows, img_cols) self.input_shape = (img_chAnnels, img_rows, img_cols) else: Train_images = Train_images.reshape(Train_images.shape[0], img_rows, img_cols, img_chAnnels) valid_images = valid_images.reshape(valid_images.shape[0], img_rows, img_cols, img_chAnnels) test_images = test_images.reshape(test_images.shape[0], img_rows, img_cols, img_chAnnels) self.input_shape = (img_rows, img_cols, img_chAnnels) valid_labels = np_utils.to_categorical(valid_labels, nb_classes) test_labels = np_utils.to_categorical(test_labels, nb_classes) # 像素数据浮点化以便归一化 Train_images = Train_images.astype('float32') valid_images = valid_images.astype('float32') test_images = test_images.astype('float32') # 将其归一化,图像的各像素值归一化到0~1区间 Train_images /= 255 valid_images /= 255 test_images /= 255 self.Train_images = Train_images #加载训练数据 self.valid_images = valid_images #加载验证数据 self.test_images = test_images #加载测试数据 self.Train_labels = Train_labels #加载训练标签 self.valid_labels = valid_labels #加载验证标签 self.test_labels = test_labels #加载测试标签
5.3.2 搭建神经网络
该网络具备的整体结构列示在表5.1中c;Layer指各层对应的具体类型c;Filters指输出滤波器的具体数量c;Size为卷积核体积c;为输出数据信息。
表5.1 网络结构概况
Layer (typE) | Filters | Size | Output Shape |
32 | (3,3) | (22, 22, 32) | |
activation (Activation) | (22, 22, 32) | ||
32 | (3,3) | (20, 20, 32) | |
activation_1 (Activation) | (20, 20, 32) | ||
@H_239_1698@max_pooling2d (MaxPooling2D) | (2,2) | (10, 10, 32) | |
dropout (Dropout) | (10, 10, 32) | ||
64 | (3,3) | (10, 10, 64) | |
activation_2 (Activation) | (10, 10, 64) | ||
64 | (3,3) | (8, 8, 64) | |
activation_3 (Activation) | (8, 8, 64) | ||
@H_239_1698@max_pooling2d_1 (MaxPooling2) | (2,2) | (4, 4, 64) | |
dropout_1 (Dropout) | (4, 4, 64) | ||
flatten (Flatten) | (1024) | ||
dense (DensE) | (512) | ||
activation_4 (Activation) | (512) | ||
dropout_2 (Dropout) | (512) | ||
dense_1 (DensE) | (2) | ||
activation_5 (Activation) | (2) |
上表描述了搭建神经网络的详细信息c;如下图5.2是基于CNN的人脸识别神经网络结构图。包含4个卷积层、池化及全连接层各2各、Flatten及分类层各1个c;其中每一层的作用如下:
图5.2 基于CNN的人脸识别神经网络结构图
(1)卷积层(convolution layer):运用keras内包含的函数基于二维层面开展相关的卷积计算。输入图像纯为64*64c;对其开展滑窗计算c;如下图5.2所示:
图5.3 卷积计算
(2)激活函数层:激活函数将简单的线性分类变成复杂的非线性分类以获得更好的分类效果c;该网络主要运用了relu函数c;输入的具体数值若小于0c;则输出的所有数值均为0c;若输入部分超过0c;那么最终输出的数值会与之相等。其优点为能够在较短时间内实现收敛c;其数学形式如下:
图5.4 池化
(4)Dropout层:随机对一定数量的输入神经元间存在的链接进行断开c;避免出现过拟合情况。
(5)Flatten层:完成上面提及的各个过程后c;数据仍旧以二维方式呈现c;而基于该层能够将其压缩为一维。
(6)全连接层:负责将数据划分成不同类型且开展回归处理。该层会对512个特征进行保留并传给下层。函数为基础完成整个分类过程。基于分类层面c;若神经元所输出的具体数值较大c;则更可能被归为真实类别。所以通过该函数进行处理后c;从上层得到的N个输入会以映射方式形成与之对应的概率分布c;且所有概率相加后为1c;所对应概率最高的便是预估的具备类别。其函数式如下:
实现代码如下:
# 建立模型def build_model(self, dataset, nb_classes=2):
# 构建一个空的线性堆叠网络模型
self.model = Sequential() self.model.add(Convolution2D(32, 3, 3, padding='same', input_shape=dataset.input_shape)) # 2维卷积层 self.model.add(Activation('Relu')) # self.model.
self.model.add(@H_830_44@maxPooling2D(pool_size=(2, 2))) # 池化层self.model.add(Dropout(0.25)) # self.model.add(Dropout(0.5)) # Dropout层self.model.add(Dense(nb_classes)) # Dense层self.model.add(Activation('softmax')) #分类层c;输出最终结果# 输出模型概况self.model.su@H_830_44@mmary()
5.3.3 模型训练
搭建神经网络后c;开始训练模型。 在开始训练前c;先对优化器对应的函数进行设置c;优化器在训练过程主要对相关参数进行调节c;保证处于最优水平c;本次基为主要依据来判定是不是要运用相应的动量方法c;相对于传统动量法c;其效率更高c;实现代码如下:
# 训练模型def Train(self, dataset, batch_size = 32, nb_epoch = 5, data_augmentation=True): sgd = SGD(lr=0.01, decay=1e-6, @H_535_171@momentum=0.9, nesterov=True) # 采用SGD+momentum的优化器进行训练c;首先生成一个优化器对象 self.model.compile(loss='categorical_crossentropy', optimizer=sgd,
if not data_augmentation: self.model.fit(dataset.Train_images, dataset.Train_labels, batch_size=batch_size, nb_epoch=nb_epoch, validation_data=(dataset.valid_images, dataset.valid_labels), shuffle=True) featurewise_std_normalization=false, # 是否数据标准化(输入数据除以数据集的标准差) datagen.fit(dataset.Train_images) # 利用生成器开始训练模型 self.model.fit(datagen.flow(dataset.Train_images, dataset.Train_labels, batch_size=batch_size),
steps_per_epoch = int(2100/batch_size), epochs=nb_epoch,
validation_data=(dataset.valid_images, dataset.valid_labels),verbose=1)
5.4 人脸识别GUI打卡小程序
人脸识别GUI打卡小程序使用Python GUI库 Tkinter。实现了签到打卡c;模式选择c;录入新人c;查看签到信息等功能。使用Frame初始化页面c;组件使用grid布局排列。数据库使用sqlLite3c;在页面创建时初始化。
在启动小程序时c;首先使用sqlite3.connect函数创建或打开一个数据库c;然后在初始化数据库时c;创建打卡记录表、管理员表、人脸标签表表。在需要调用数据库时c;使用数据库类中封装的方法。主要实现代码如下:
self.conn.execute('create table if not exists record_table(' 'id INTEGER PRIMary key autoincrement,' 'name varchar(30) ,' 'Record_time timestamp)')self.conn.execute('create table if not exists name_table(' 'id INTEGER PRIMary key autoincrement,' 'name varchar(30))')self.conn.execute('create table if not exists admin_table(' 'id INTEGER PRIMary key autoincrement,' 'username varchar(30),' 'password varchar(32))')
启动小程序后c;通过Frame类创建一个窗口c;使用grid布局。在网格布局上添加Label标签c;设置字体font为粗体。在网格布局上添加签到打卡、录入新人按钮c;给按钮command属性上绑定点击事件c;分别跳转到签到打卡页面与录入新人界面c;通过给按钮bg属性添加16进制颜色c;改变按钮的颜色。实现效果如图5.1所示。
图5.5 主页页面
在主页上点击签到打卡后c;小程序将调用电脑摄像头c;对摄像头外的人脸进行识别。在CNN模式下c;加载训练的H5模式模型文件c;对获取的人脸进行识别c;识别成功将在打卡记录表中插入一条数据。在LBPH模式下c;将加载训练后的yml文件c;对人脸进行识别打卡。实现代码如下:
def check(names,mode_id): cam = cv2.VideoCapture(0) if @H_830_44@mode_id==1: recognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.read('face_Trainer/Trainer.yml') #加载模型 cascadePath = "haarcascade_frontalface_default.xml" faceCascade = cv2.CascadeClassifier(cascadePath)#加载人脸识别器 font = cv2.FONT_HERSHEY_SIMPLEX (graY[y:y + h, x:x + w]) if confidence < 100: username = names[idnum-1] confidence = "{0}%".format(round(100 - confidence)) cv2.putText(img, str(username cv2.imshow('camera', img) time.sleep(2) db.record().insert_record(username) # 签到信息插入数 cam.release() cv2.destroyAllWindows() return else: idnum = "unknown" confidence = "{0}%".format(round(100 - confidence)) cv2.putText(img, str(idnum), (x + 5, y - 5), font, 1, (0, 0, 255), 1) cv2.putText(img, str(confidence),
break elif @H_830_44@mode_id==2: face_recognition(names,True) #进行加载H5人脸识别模型 print(2) else: print("请选着模式") cam.release() cv2.destroyAllWindows()
点击菜单栏中登录按钮c;创建Frame窗口c;并销毁主页页面。用户名和密码使用Entry控件实现获取输入的数据。获取数据后c;点击按钮触发点击事件中函数c;把输入的用户名与密码跟数据库中保存的数据开展全面对比c;若发现彼此能够匹配c;跳转到主页c;同时将用户状态self.authority的值改为1。
图5.6 登录界面
点击菜单栏中注册按钮c;创建Frame窗口c;并销毁主页页面。用户名和密码使用Entry控件实现获取输入的数据。获取数据后c;点击按钮触发点击事件中函数c;将获取到的用户名与密码向数据中插入数据c;实现效果如图5.3所示。
图5.7 注册界面
usr_name = self.var_usr_name.get()usr_pwd = self.var_usr_pwd.get()if usr_name == "" or usr_pwd == "": tkinter.messagebox.askokcancel(title='提示', message='请输入用户名或密码!') returntkinter.messagebox.askokcancel(title='提示', message='注册成功!')self.mydb.add_admin(usr_name,usr_pwd)
#向数据库插入一条数据
def add_admin(self,username,password): sql = "INSERT INTO admin_table VALUES (null,?,?);" self.conn.execute(sql,[username,password]) self.conn.co@H_830_44@mmit()
在主页上点击增加新人按钮c;创建Frame窗口c;并销毁主页页面。在LBPH模式下c;提示输入姓名c;输入姓名后c;点击确定后调用OpenCV的VideoCapture函数打开电脑的摄像头c;获取人脸并训练数据。实现效果如图5.3所示。
图5.8 增加人脸界面
管理员点击签到信息按钮c;从数据库读取打卡记录表c;将所有数据都绑定在Treeview上c;实现效果如图5.5所示。查询数据库实现代码如下:
def query_record(self): self.cursor.execute('SELEct * from record_table') #执行一条查找的SQL数据 results = self.cursor.fetchall() return results
图5.9 签到信息
以上是大佬教程为你收集整理的我的毕业设计之基于深度学习的人脸识别系统全部内容,希望文章能够帮你解决我的毕业设计之基于深度学习的人脸识别系统所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。