当前位置: 首页 > news >正文

基于人工智能的闸机人脸识别门禁系统

Opencv

面部智能识别这项技术还是比较复杂的,要想彻底理解并付诸实践,得有一套扎实的理论架构和强大的技术工具。首先要提到的就是OpenCV,它可以说是集大成者,另外,Dlib也是不可忽视的,尤其以精准性闻名。这两者几乎是现代计算机视觉处理,特别是人脸相关应用的基础平台。如果你深入了解它们是如何从复杂的图像数据中识别出人脸的,你会看到一些挺有意思的技术细节。比如,OpenCV常用的做法是通过Haar级联这种效率极高的分类器来快速检测面部区域,能迅速从画面中找出潜在的面孔。而Dlib的做法就有点不同,它更注重从面部特征的角度出发,使用像方向梯度直方图这种描述子来提取面部的细节信息,获得这些特征之后,接下来就是身份识别的过程,通常会用支持向量机等分类器来判断身份。其实,这些看似独立的技术,通过巧妙的结合,最终就支撑起了一个精准的人脸识别系统。

Haar级联分类器

Haar图像特征最初是通过对矩形区域进行分析来开发的,它通过计算不同区域之间的灰度对比,能够捕捉到描述物体形态的关键信息。在人脸识别任务中,Haar特征的一个突出特点就是它能够有效抓取面部的关键结构,比如眼睛、鼻子、嘴巴等位置的亮度差异。正是依靠这种独特的亮度对比模式,分类器才能高效地区分出人脸目标,哪怕背景复杂杂乱。 Haar特征大致可以分为三种类型:边缘特征、线性特征和中心特征。而Haar特征值则是通过计算图像中不同区域的灰度变化来得出的。具体来说,它是通过计算白色矩形区域和黑色矩形区域的像素总和的差值,来表示图像在这些区域内的灰度差异。利用Haar特征,我们可以迅速从图像中提取出我们关心的区域(比如人脸),并进行进一步的检测。 

image.png

Haar级联分类器其实就是通过分析大量的训练样本来建造一堆简单的识别单元。它之所以能精准地锁定目标,主要就是因为它对Haar特征模式的理解和学习非常到位。为了让效果更好,系统还加上了自适应增强算法和逐级筛选的串联结构。 简单说,自适应增强算法的作用就是反复优化特征集合,调整每个阶段分类器的权重,让它越来越精确。而那种逐级筛选的串联结构就像是分步走的过程,让分类器一层一层地筛查目标,最终从一堆可能性中找出我们需要的那个。这种方式让Haar级联分类器在复杂的图像中也能快速又精准地识别出目标。 

image.png

Dlib库

Dlib,作为一个强大的C++库,并且提供Python接口,已经在机器学习和计算机视觉领域占据了重要地位。它不仅在学术研究中被广泛应用,在工业界的高要求部署场景中也同样表现不凡。Dlib的核心架构融合了图像计算和深度学习的精髓,凭借高效的算法和灵活的模块化设计,在视觉分析任务中展现出了非常优秀的性能,尤其是在精准识别人脸和面部特征方面。 Dlib通过集成方向梯度直方图(HOG)特征提取技术与支持向量机(SVM)分类策略,能够实现高效的人脸区域检测。这个库还提供了很多预训练模型,比如专门用于精确定位面部结构的68点或5点标注模型。这些模型能精准地捕捉面部的关键几何特征点,比如眼眶轮廓、鼻下点、嘴角连线和颚骨边界等,为后续的详细面部分析提供了坚实的基础

代码部分

主程序代码

from PyQt5 import QtCore
from control.mainWindow import MyWindow
import sys#PyQt使用高分辨率
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)#主函数
if __name__ == '__main__':app = QApplication(sys.argv)#实例化主界面myWin = MyWindow()#显示主界面myWin.show()sys.exit(app.exec_())

人脸记录部分代码

from view.checkinmodify import *
from PyQt5.QtWidgets import QWidget, QMessageBox, QAbstractItemView, QTableWidgetItem, QLabel, QDialog, QFileDialog
from model.connectsqlite import ConnectSqlite
import model.configuration
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from datetime import datetime
import osclass CheckInRecord(QWidget, Ui_CheckInRecordForm):def __init__(self, parent=None):super(CheckInRecord, self).__init__(parent)self.setupUi(self)# 连接 SQLite 数据库self.dbcon = ConnectSqlite(model.configuration.DATABASE_PATH)self.checkin_data = []self.pushButton_search.clicked.connect(self.search)self.pushButton_modify.clicked.connect(self.modify)self.pushButton_delete.clicked.connect(self.delete)self.pushButton_export.clicked.connect(self.export_to_txt)  # 连接导出按钮self.make_table()# 导出数据为 TXT 文件def export_to_txt(self):if len(self.checkin_data) == 0:reply = QMessageBox.warning(self, '提示', '没有可导出的数据!',QMessageBox.Yes, QMessageBox.Yes)return# 获取当前时间用于文件名current_time = datetime.now().strftime("%Y%m%d_%H%M%S")default_filename = f"考勤记录报表_{current_time}.txt"# 打开文件保存对话框选择保存位置options = QFileDialog.Options()filepath, _ = QFileDialog.getSaveFileName(self,"保存考勤记录",default_filename,"Text Files (*.txt);;All Files (*)",options=options)if not filepath:  # 用户取消returntry:with open(filepath, 'w', encoding='utf-8') as f:# 写入文件头f.write("考勤记录报表\n")f.write(f"导出时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")f.write("=" * 60 + "\n\n")# 写入表头f.write(f"{'姓名':<15}{'学号':<20}{'考勤时间':<25}\n")f.write("-" * 60 + "\n")# 写入数据行for row in self.checkin_data:name = row[1]student_id = str(row[0])checkin_time = row[2].split(".")[0]f.write(f"{name:<15}{student_id:<20}{checkin_time:<25}\n")# 写入文件尾f.write("\n" + "=" * 60 + "\n")f.write(f"总记录数: {len(self.checkin_data)}")reply = QMessageBox.information(self, '成功', '报表导出成功!',QMessageBox.Yes, QMessageBox.Yes)except Exception as e:reply = QMessageBox.warning(self, '错误', f'导出失败: {str(e)}',QMessageBox.Yes, QMessageBox.Yes)# 搜索功能def search(self):print("search")search_str = self.lineEdit_search.text()row = 0search_result = Noneif search_str != '':# 遍历列表查找匹配数据for i in self.checkin_data:if search_str.lower() in str(i[1]).lower():search_result = str(i[1])self.tableWidget.setCurrentIndex(self.tableWidget.model().index(row, 1))if search_str.lower() in str(i[0]).lower():search_result = str(i[0])self.tableWidget.setCurrentIndex(self.tableWidget.model().index(row, 0))if search_str.lower() in str(i[2]).lower():search_result = str(i[2])self.tableWidget.setCurrentIndex(self.tableWidget.model().index(row, 2))row += 1if search_result == 0:reply = QMessageBox.warning(self, '错误', '未找到相关信息!',QMessageBox.Yes, QMessageBox.Yes)else:reply = QMessageBox.warning(self, '错误', '请输入搜索关键词',QMessageBox.Yes, QMessageBox.Yes)# 修改功能def modify(self):select = self.tableWidget.selectedItems()if len(select) != 0:row = self.tableWidget.selectedItems()[0].row()  # 获取选中的行column = self.tableWidget.selectedItems()[0].column()print(row, column)name = str(self.checkin_data[row][1])sid = str(self.checkin_data[row][0])checkin_time = str(self.checkin_data[row][2])id = self.checkin_data[row][-1]insert_list = [name, sid, checkin_time]dialog = CheckInModify(insert_list)dialog.exec_()modify_list = dialog.getInputs()modify_flag = modify_list[1]print("iddddd{}".format(id))result = self.dbcon.update_checkin_table(modify_list[0], id)if modify_flag:if result == 0:self.make_table()reply = QMessageBox.information(self, '成功', '修改成功!',QMessageBox.Yes, QMessageBox.Yes)else:reply = QMessageBox.warning(self, '错误', result,QMessageBox.Yes, QMessageBox.Yes)else:reply = QMessageBox.warning(self, '错误', '请选择需要修改的记录!',QMessageBox.Yes, QMessageBox.Yes)# 删除功能def delete(self):select = self.tableWidget.selectedItems()if len(select) != 0:row = self.tableWidget.selectedItems()[0].row()  # 获取选中的行column = self.tableWidget.selectedItems()[0].column()id = self.checkin_data[row][-1]result = self.dbcon.delete_checkin_table(id)if result == 0:self.make_table()reply = QMessageBox.information(self, '成功', '删除成功!',QMessageBox.Yes, QMessageBox.Yes)else:reply = QMessageBox.warning(self, '错误', result,QMessageBox.Yes, QMessageBox.Yes)else:reply = QMessageBox.warning(self, '错误', '请选择需要删除的数据!',QMessageBox.Yes, QMessageBox.Yes)# 显示数据库中的表格内容def make_table(self):# 清空表格self.tableWidget.clear()self.checkin_data = self.dbcon.return_all_checkin_record()data_show = []for row in self.checkin_data:name = row[1]student_id = str(row[0])checkin_time = row[2].split(".")[0]data_show.append([name, student_id, checkin_time])self.RowLength = 0self.tableWidget.setColumnCount(3)self.tableWidget.setColumnWidth(0, 220)  # 设置第1列宽度self.tableWidget.setColumnWidth(1, 220)  # 设置第2列宽度self.tableWidget.setColumnWidth(2, 300)  # 设置第3列宽度self.tableWidget.setHorizontalHeaderLabels(["姓名", "学号", "进入时间"])self.tableWidget.setRowCount(self.RowLength)self.tableWidget.verticalHeader().setVisible(False)  # 隐藏垂直表头self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)self.tableWidget.raise_()for row_data in data_show:self.RowLength = self.RowLength + 1label = QLabel()self.tableWidget.verticalHeader().setDefaultSectionSize(40)self.tableWidget.setRowCount(self.RowLength)self.tableWidget.setItem(self.RowLength - 1, 0, QTableWidgetItem(row_data[0]))self.tableWidget.setItem(self.RowLength - 1, 1, QTableWidgetItem(row_data[1]))self.tableWidget.setItem(self.RowLength - 1, 2, QTableWidgetItem(row_data[2]))self.tableWidget.item(self.RowLength - 1, 0).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)self.tableWidget.item(self.RowLength - 1, 1).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)self.tableWidget.item(self.RowLength - 1, 2).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)# 关闭窗口def close_all(self):self.close()# 考勤记录修改对话框
class CheckInModify(QDialog, Ui_Dialog):def __init__(self, current_list, parent=None):super(CheckInModify, self).__init__(parent)self.setupUi(self)self.name = current_list[0]self.sid = current_list[1]self.checkin_time = current_list[2]self.lineEdit_sno.setText(self.sid)self.lineEdit_name.setText(self.name)print(self.checkin_time)self.modify_flag = Falsetime1 = int(self.checkin_time.split(' ')[1].split(':')[0])time2 = int(self.checkin_time.split(' ')[1].split(':')[1])time1_format = str('{:0>2d}'.format(time1))time2_format = str('{:0>2d}'.format(time2))self.timeEdit_checkin.setTime(QTime.fromString(time1_format + ':' + time2_format))self.pushButton_add.clicked.connect(self.modify_return)def modify_return(self):self.modify_flag = Trueself.close()def getInputs(self):name = self.lineEdit_name.text()sid = self.lineEdit_sno.text()checkin_time = self.checkin_time.split(' ')[0] + " " + self.timeEdit_checkin.text()return [[name, sid, checkin_time], self.modify_flag]

人脸核验部分代码

点击基于人工智能的闸机人脸识别门禁系统查看全文

http://www.xdnf.cn/news/957565.html

相关文章:

  • 昇腾CANN集合通信技术解读——细粒度分级流水算法
  • CMake 从 GitHub 下载第三方库并使用
  • 高端性能封装正在突破性能壁垒,其芯片集成技术助力人工智能革命。
  • ABAP设计模式之---“童子军法则(The Boy Scout Rule)”
  • animate.css详解:轻松实现网页动画效果
  • 制作一款打飞机游戏68:地面敌人
  • CopyOnWriteArrayList和CopyOnWriteArraySet :并发安全的写时复制机制
  • 新手指南:如何轻松将文件压缩为RAR格式
  • Android多媒体——音/视频数据播放(十八)
  • 如何实现高可用评论服务
  • gtxe2_channel内部参数和寄存器配置-CPLL超频设计,超过6.6Gbps的最高速率
  • OpenHarmony按键分发流程(60%)
  • 4.redis集群
  • rk3568的data分区修改
  • 以太网PHY布局布线指南
  • Houdini POP入门学习07 - 分组
  • 热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
  • 论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
  • 游戏开发中常见的战斗数值英文缩写对照表
  • ubuntu中安装conda的后遗症
  • 3439. 重新安排会议得到最多空余时间 I
  • vue3 报错Missing semicolon
  • Yolov8 目标检测蒸馏学习记录
  • 【2025】pycharm 安装
  • 详解什么是One-Hot Encoding (独热编码)
  • PH热榜 | 2025-06-08
  • Ascend NPU上适配Step-Audio模型
  • C语言数据结构笔记4:子函数中使用的sizeof 指针无法获取数组的实际大小
  • 学习经验分享篇(3)——电机驱动电力电子方向投稿经历
  • 职场生存发展指南 | 边界 / 责任 / 社交 / 情绪