Python | 人脸识别系统 — 用户操作

news/2024/11/23 3:58:27/

本博客为人脸识别系统的摄像头画面展示代码解释

人脸识别系统博客汇总:人脸识别系统-博客索引

项目GitHub地址:Su-Face-Recognition: A face recognition for user logining

注意:阅读本博客前请先参考以下博客

工具安装、环境配置:人脸识别系统-简介

UI界面设计:人脸识别系统-UI界面设计

UI事件处理:人脸识别系统-UI事件处理

人脸识别:人脸识别系统-人脸识别

活体检测:人脸识别系统-活体检测

阅读完本博客后可以继续阅读:

摄像头画面展示:人脸识别系统-摄像头画面展示

用户端逻辑:

  • 人脸识别:Python | 人脸识别系统 — 人脸识别
  • 活体检测:Python | 人脸识别系统 — 活体检测
  • 背景模糊:Python | 人脸识别系统 — 背景模糊
  • 姿态检测:Python | 人脸识别系统 — 姿态检测
  • 人脸比对:Python | 人脸识别系统 — 人脸比对

管理员端逻辑:

  • 管理员操作:
  • 用户操作:

一、用户登录

        1、登录逻辑

        信息核验(数据库) -> 静默活体检测 -> 交互活体检测 -> 人脸识别 

        一旦用户超过三次没有登录成功(活体检测/人脸识别不成功),系统将当前用户进行锁定。用户需要通过管理员进行解锁。

    # 登录标志USER_LOGIN_MSG_FLAG = False # 用户信息核验成功标志USER_LOGIN_FLAG = False # 用户登录成功标志... ...# 用户登录def user_login(self):if not self.cap.isOpened():QMessageBox.information(self, "提示", self.tr("请先打开摄像头"))else:global USER_LOGIN_FLAGif not USER_LOGIN_FLAG:QApplication.processEvents()login = LoginWindow(self) # 创建信息核验界面对象login.exec_() global USER_LOGIN_MSG_FLAGglobal USER_LOGIN_NAMEif USER_LOGIN_MSG_FLAG:# 登录信息成功,进行活体检测QMessageBox.about(self, '提示', '登录成功,进行活体检测')if self.detect_face():# 活体检测成功,进行人脸识别global ENCODING_TEMPface_encoding = FaceEncodingUtil.decoding_FaceStr(ENCODING_TEMP)if self.recognize_instant_face(face_encoding):QMessageBox.about(self, '提示', '登陆成功')self.save_record(USER_LOGIN_NAME, '使用摄像头进行登录') # 使用excel表格进行保存USER_LOGIN_FLAG = Trueelse:QMessageBox.about(self, '提示', '人脸识别失败,请重新登录')if USER_LOGIN_NAME != "":UserSqlUtil.add_name_warn(USER_LOGIN_NAME)USER_LOGIN_MSG_FLAG = Falseelse:QMessageBox.about(self, '提示', '活体检测失败,请重新登录')if USER_LOGIN_NAME != "":UserSqlUtil.add_name_warn(USER_LOGIN_NAME)USER_LOGIN_MSG_FLAG = Falselogin.destroy()else:QMessageBox.about(self, '提示', '用户已经登录')

        2、信息核验

        用户点击 [用户登录] 按钮,主界面弹出信息核验界面,要求用户输入账号、密码。点击确认后,系统访问数据库,判断输入信息是否正确。

        信息核验界面相关代码:

# 用户登录界面
class LoginWindow(QDialog, LoginMsgUi):def __init__(self, parent=None):super(LoginWindow, self).__init__(parent)self.setupUi(self)self.minimize_button.clicked.connect(self.showMinimized)self.close_button.clicked.connect(self.cancel_login)self.confirm_button.clicked.connect(self.search_user)self.cancel_button.clicked.connect(self.cancel_login)# 点击确认,搜索用户def search_user(self):input_name = self.name_lineEdit.text()input_password = self.password_lineEdit.text()if input_name == "":QMessageBox.about(self, '提示', '姓名不能为空')elif input_password == "":QMessageBox.about(self, '提示', '密码不能为空')else:row = UserSqlUtil.search_by_name("\"" + input_name + "\"")if row:result = row[0]password = result[1]if input_password != password:QMessageBox.about(self, '提示', '密码输入错误')else:global USER_LOGIN_MSG_FLAGcount = UserSqlUtil.search_count_warn("\"" + input_name + "\"")if count >= 3:QMessageBox.about(self, '警告', '该账号目前已被锁定')USER_LOGIN_MSG_FLAG = Falseelse:global ENCODING_TEMPglobal USER_LOGIN_NAMEUSER_LOGIN_MSG_FLAG = TrueENCODING_TEMP = result[5]USER_LOGIN_NAME = input_nameself.close_window()else:QMessageBox.about(self, '提示', '该用户不存在')# 点击取消按钮def cancel_login(self):global USER_LOGIN_MSG_FLAGUSER_LOGIN_MSG_FLAG = Falseself.close_window()# 关闭窗口def close_window(self):self.name_lineEdit.setPlaceholderText("请输入姓名")self.password_lineEdit.setPlaceholderText("请输入密码")self.close()

        数据库表结构(user表)

        数据库代码

# -*- coding: utf-8 -*-
import pymysqldef init_conn():conn = pymysql.connect(host="127.0.0.1",  # 数据库的IP地址user="root",  # 数据库用户名称password="root",  # 数据库用户密码db="contest",  # 数据库名称port=3306,  # 数据库端口名称charset="utf8"  # 数据库的编码方式)return conndef execute_with_bool(sql_str, args=()):conn = init_conn()cursor = conn.cursor()try:cursor.execute(sql_str, args)conn.commit()return Trueexcept Exception as e:conn.rollback()print(e)return Falsefinally:cursor.close()def execute_with_list(sql_str):conn = init_conn()cursor = conn.cursor()results = []try:cursor.execute(sql_str)results = cursor.fetchall()except Exception as e:conn.rollback()print(e)finally:cursor.close()return resultsdef insert_data(name, password, age, sex, more, face_encoding):return execute_with_bool("insert into user(name,password,age,sex,more,face_encoding) values(%s,%s,%s,%s,%s,%s)",(name, password, age, sex, more, face_encoding))def update_by_name(name, password, age, sex, more, face_encoding):return execute_with_bool("update user set name=%s,password=%s,age=%s,sex=%s,more=%s,face_encoding=%s where name = %s",(name, password, age, sex, more, face_encoding, name))def update_by_name_without_encoding(name, age, sex, more):return execute_with_bool("update user set name=%s,age=%s,sex=%s,more=%s where name = %s",(name, age, sex, more, name))def search_all_msg():return execute_with_list("select * from user")def search_by_name(name):return execute_with_list("select * from user where name = " + name)def search_count_name(name):return execute_with_list("select count(*) from user where name = " + name)[0][0]def delete_by_name(name):return execute_with_bool("delete from user where name = %s", name)def search_count_warn(name):return execute_with_list("select count(*) from warn where name = " + name)[0][0]def add_name_warn(name):return execute_with_bool("insert into warn(name) values(%s)", name)

        3、活体检测

活体检测函数 detect_face() 详见博客:

      4、人脸识别

人脸识别函数 recognize_instant_face() 详见博客:

人脸识别使用的是函数 recognize_instant_face(),其中需要参数face_encoding,为1*128的矩阵。当我们从数据库取出当前登录用户的人脸编码时,为字符串类型,需要进行转换。编写工具类FaceEncodingUtil,调用编写的方法 decoding_FaceStr 进行转换。其工具类方法如下:

# -*- coding: utf-8 -*-
import numpydef decoding_FaceStr(encoding_str):# 将字符串转为numpy ndarray类型,即矩阵# 转换成一个listdecoding_list = encoding_str.strip(' ').split(',')# 将list中str转换为floatdecoding_float = list(map(float, decoding_list))face_encoding = numpy.array(decoding_float)return face_encoding

二、用户注册

        1、判断器

        摄像头截取当前人脸 -> 信息填写 -> 面部信息编码 -> 信息保存(数据库)

        摄像头截取当前人脸照片,使用当前时间点作为照片名保存到photo目录下,面部信息编码成功后删除照片。

    signal_register = pyqtSignal()  # 用户注册 界面信号... ...# 用户注册def user_register(self):isCapOpened_flag = self.cap.isOpened()if not isCapOpened_flag:QMessageBox.information(self, "提示", self.tr("请先打开摄像头!"))else:ret, frame = self.cap.read()frame_location = face_recognition.face_locations(frame)if len(frame_location) == 0:QMessageBox.information(self, "提示", self.tr("没有检测到人脸,请重新拍摄!"))else:QMessageBox.information(self, "提示", self.tr("拍照成功!"))global PHOTO_FOLDER_PATHglobal SHOT_TEMP_NAMESHOT_TEMP_NAME = datetime.now().strftime("%Y%m%d%H%M%S")self.show_image.save(PHOTO_FOLDER_PATH + SHOT_TEMP_NAME + ".jpg")self.send_signal_register()# 发射信号 打开注册用户界面def send_signal_register(self):self.signal_register.emit()

        2、逻辑编写

        用户点击 [用户注册] 按钮,主界面弹出信息填写界面,要求用户输入账号、密码等信息。点击确认后,系统判断输入信息格式是否正确。

# 用户注册界面
class RegisterWindow(QMainWindow, RegisterMsgUi):def __init__(self, parent=None):super(RegisterWindow, self).__init__(parent)self.setupUi(self)self.minimize_button.clicked.connect(self.showMinimized)self.close_button.clicked.connect(self.close_window)self.cancel_button.clicked.connect(self.delete_shot)self.confirm_button.clicked.connect(self.fill_information)# 填写信息def fill_information(self):flag = 0name = self.name_lineEdit.text()password = self.password_lineEdit.text()age = self.age_lineEdit.text()sex = self.sex_lineEdit.text()more_infor = self.more_lineEdit.text()if self.judge_name_conflict(name):if name != '':# 输入密码if password != '':# 输入年龄if age == '':age = '未知'elif not str.isdigit(age):flag = 1QMessageBox.about(self, '提示', '请输入正确的年龄格式')# 输入性别if sex == '':sex = '未知'elif sex != '男' and sex != '女':flag = 1QMessageBox.about(self, '提示', '请输入正确的性别格式')sex = '未知'# 输入更多信息if more_infor == '':more_infor = '未知'global PHOTO_FOLDER_PATHglobal SHOT_TEMP_NAMEif flag == 0:# 计算脸部数据并保存到数据库QApplication.processEvents()register_encoding = self.analyse_encoding(SHOT_TEMP_NAME)if self.save_database(name, password, age, sex, more_infor, register_encoding):QMessageBox.about(self, '提示', '完成注册')else:QMessageBox.about(self, '提示', '注册失败')self.delete_shot()elif flag == 1:QMessageBox.about(self, '提示', '注册失败')else:QMessageBox.about(self, '提示', '请输入密码')else:QMessageBox.about(self, '提示', '请输入姓名')else:QMessageBox.about(self, '提示', '用户' + name + '已经注册过')# 保存注册信息@staticmethoddef save_database(name, password, age, sex, more, face_encoding):return UserSqlUtil.insert_data(name, password, age, sex, more, face_encoding)# 判断姓名是否冲突@staticmethoddef judge_name_conflict(name):count = UserSqlUtil.search_count_name("\"" + name + "\"")if count != 0:return Falseelse:return True# 分析截图@staticmethoddef analyse_encoding(name):global PHOTO_FOLDER_PATHphoto_path = PHOTO_FOLDER_PATH + name + ".jpg"register_images = face_recognition.load_image_file(photo_path)register_encoding = face_recognition.face_encodings(register_images)[0]return FaceEncodingUtil.encoding_FaceStr(register_encoding)# 删除截图def delete_shot(self):global PHOTO_FOLDER_PATHglobal SHOT_TEMP_NAMEdelete_shot_path = PHOTO_FOLDER_PATH + SHOT_TEMP_NAME + ".jpg"os.remove(delete_shot_path)SHOT_TEMP_NAME = ""self.close_window()# 关闭窗口def close_window(self):lineText = [self.age_lineEdit, self.sex_lineEdit, self.name_lineEdit, self.more_lineEdit]line = 0for lineEdit in lineText:lineEdit.setPlaceholderText(str(line))if 3 >= line >= 0:lineEdit.setPlaceholderText("请输入信息")line = line + 1self.close()

进行数据库保存的时候,面部编码数据为为1*128的矩阵,需要通过工具类FaceEncodingUtil的方法 encoding_FaceStr 进行转换。其工具类方法如下:

# -*- coding: utf-8 -*-
import numpydef encoding_FaceStr(image_face_encoding):# 将numpy array类型转化为列表encoding__array_list = image_face_encoding.tolist()# 将列表里的元素转化为字符串encoding_str_list = [str(i) for i in encoding__array_list]# 拼接列表里的字符串encoding_str = ','.join(encoding_str_list)return encoding_str

三、用户登出

        用户登出操作比较简单,将全局标志 USER_LOGIN_FLAG 设置为False即可。

        判断器代码如下:

    # 用户登出def user_logout(self):global USER_LOGIN_FLAGglobal USER_LOGIN_NAMEif not USER_LOGIN_FLAG:QMessageBox.about(self, '提示', '请先登录')else:USER_LOGIN_FLAG = FalseQMessageBox.about(self, '提示', '退出成功')self.save_record(USER_LOGIN_NAME, '退出登录') # 记录到excel表格中

四、Excel表格记录

        将用户登录、登出的操作时间、设备、用户名等信息保存到系统excel表格中。可以通过管理员身份登录系统,导出系统的excel表格进行查看。导出excel表格的代码在管理员端编写。

        保存信息到excel表格的代码如下:

    # 将记录保存到excel中@staticmethoddef save_record(name, record):global DATA_FOLDER_PATHlocal_path = DATA_FOLDER_PATH + 'history.xls'old_book = xlrd.open_workbook(local_path)new_book = copy(old_book)sheet2 = new_book.get_sheet(0)sheet0 = old_book.sheet_by_index(0)n_rows = sheet0.nrowsstr_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")sheet2.write(n_rows + 1, 0, str_time)sheet2.write(n_rows + 1, 1, '摄像头')sheet2.write(n_rows + 1, 2, name)sheet2.write(n_rows + 1, 3, record)new_book.save('new_book.xls')os.remove(local_path)os.rename('new_book.xls', local_path)

        

阅读完本博客后可以继续阅读:

摄像头画面展示:人脸识别系统-摄像头画面展示

用户端逻辑:

  • 人脸识别:Python | 人脸识别系统 — 人脸识别
  • 活体检测:Python | 人脸识别系统 — 活体检测
  • 背景模糊:Python | 人脸识别系统 — 背景模糊
  • 姿态检测:Python | 人脸识别系统 — 姿态检测
  • 人脸比对:Python | 人脸识别系统 — 人脸比对

管理员端逻辑:

  • 管理员操作:
  • 用户操作:

注:以上代码仅为参考,若需要运行,请参考项目GitHub完整源代码: Su-Face-Recognition: A face recognition for user logining


http://www.ppmy.cn/news/59883.html

相关文章

英语中主语从句的概念及其用法,例句(不断更新)

主语从句的原理 主语从句是一种充当整个句子主语的从句,主语从句构成的句子,是要以引导词开头的。它可以用名词性从属连词、关系代词或关系副词引导。主语从句通常位于谓语动词之前,用于表示动作、状态或事件的主体。 以下是一些常用的引导主…

基于springboot的私人健身与教练预约管理系统

摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代…

SQL 执行顺序

数据的关联过程 from&join&where group by having&where select order by limit 这是一条标准的查询语句: 这是我们实际上SQL执行顺序: 我们先执行from,join来确定表之间的连接关系,得到初步的数据 where对数据进行普通的初步的筛选 …

玩转肺癌目标检测数据集Lung-PET-CT-Dx ——④转换成PASCAL VOC格式数据集

文章目录 关于PASCAL VOC数据集目录结构 ①创建VOC数据集的几个相关目录XML文件的形式 ②读取dcm文件与xml文件的配对关系③创建VOC格式数据集④创建训练、验证集 本文所用代码见文末Github链接。 关于PASCAL VOC数据集 pascal voc数据集是关于计算机视觉,业内广泛…

Redis超详细入门手册教程!还不快来看看?

地址: RedisRedis is an open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker. Redis provides data structures …https://redis.io/ 1:NoSQL简介 1.1:数据库应用的演变历程 单…

【VScode】的 安装--配置--使用(中文插件下载不了怎么办?)

🖊作者 : D. Star. 📘专栏 : VScode 😆今日分享 : ”兰因絮果“是世间定律吗? 一段美好爱情开始时你侬我侬、缠缠绵绵,最后却以相看两厌结尾,让人唏嘘。清代词人纳兰容若于是咏出「人生若只如初见&#xff…

眼见为实,来瞧瞧MySQL中的隐藏列!

在介绍mysql的多版本并发控制MVCC的过程中,我们提到过mysql中存在一些隐藏列,例如行标识、事务ID、回滚指针等,不知道大家是否和我一样好奇过,要怎样才能实际地看到这些隐藏列的值呢? 本文我们就来重点讨论一下诸多隐…

Windows上使用CLion配置OpenCV环境,CMake下载,OpenCV的编译,亲测可用的方法(一)

一、Windows上使用CLion配置OpenCV环境,亲测可用的方法: Windows上使用CLion配置OpenCV环境 教程里的配置: widnows 10 clion 2022.1.1 mingw 8.1.0 opencv 4.5.5 Cmake3.21.1 我自己的配置: widnows 10 clion 2022.2.5 mingw 8.1.0 https://sourceforge.net/projects/min…