人脸考勤机项目
文章内容如下:
1)项目简介
2)开发环境和使用的技术知识
3)功能实现
4)项目源码
一。项目简介
此项目是基于HOG和Dlib开发的一套实时无感考勤系统。首先是待考勤人员的个人信息录入。然后在过道或者入口处装置人脸考勤机,当有人经过时,摄像头抓取人脸并上传服务器,对抓取到的人脸进行人脸识别,判断此人身份,若此人在信息比对库中且第一次考勤,则考勤成功,并显示考勤人员姓名与比对距离,如非第一次考勤,并在一定时间隔外则更新考勤 。
二。开发环境和使用的技术知识
开发环境:Python,Opencv
技术知识:HOG+Dlib技术、Opencv视频读取-缩放-翻转-写入技术
三。功能实现
1. 人脸注册:将人脸特征存进feaure.csv
2. 人脸识别:将检测的人脸特征与feaure.csv人脸特征作比较,如果比中把考勤记录写入attendance.csv
1. 人脸注册:将人脸特征存进feaure.csv
①调取视频流,能显示人脸画面
cap = cv2.VideoCapture(0)"""调取摄像头"""while True:ret,frame = cap.read()frame = cv2.flip(frame,1)"""y轴镜像"""cv2.imshow('Face attendance',frame)"""展示每一帧图片"""if cv2.waitKey(10) & 0xFF == ord('q'):break
cap.release()
cv2.destroyAllWindows()
② 步骤如下:
第1步:启动HOG人脸检测器,读取人脸上下左右坐标,绘制人脸方框;
hog_face_detector = dlib.get_frontal_face_detector()"""启动hog人脸检测器"""
detections = hog_face_detector(frame,1)"""获取人脸参数,缩放因子为1"""
for face in detections:l,t,r,b = face.left(),face.top(),face.right(),face.bottom()"""获取人脸左,上,右,下的坐标"""
cv2.rectangle(frame,(l,t),(r,b),(0,255,0),2)"""绘制人脸框"""
第2步: 启动人脸关键点检测器获取人脸68个关键点,再转为特征描述符;
shape_detector = dlib.shape_predictor('./1/shape_predictor_68_face_landmarks.dat')"""启动人脸关键点检测器"""
detections = hog_face_detector(frame,1)"""获取人脸参数,缩放因子为1"""
for face in detections:points = shape_detector(frame,face)"""获取人脸68关键点"""
for point in points.parts():cv2.circle(frame,(point.x,point.y),2,(0,255,0),-10)"""绘制68关键点"""
face_descriptor = face_descriptor_extractor.compute_face_descriptor(frame,points)"""获取(转为)特征描述符"""
face_descriptor = [f for f in face_descriptor]"""为方便转换成列表存进feaure.csv"""
①②组合在一起复合代码如下:
def faceRegister(label_id=1,name='Jie Wang',count=3,interval=3):
#1)-检测人脸#准备工作hog_face_detector = dlib.get_frontal_face_detector()#①启动hog人脸检测器shape_detector = dlib.shape_predictor('./1/shape_predictor_68_face_landmarks.dat')#①启动人脸关键点检测器face_descriptor_extractor = dlib.face_recognition_model_v1('./1/dlib_face_recognition_resnet_model_v1.dat')#①启动特征描述符检测器cap = cv2.VideoCapture(0)#②调取摄像头start_time = time.time()#开始时间,是为了interval设置的collect_count = 0#初始采集次数f = open('./2/feature.csv','a',newline="")#采集到的特征描述符放在这个文件里csv_writer = csv.writer(f)#采集3次特征 while True:ret,frame = cap.read()frame = cv2.flip(frame,1)#y轴镜像detections = hog_face_detector(frame,1)#获取人脸参数,缩放因子为1for face in detections:l,t,r,b = face.left(),face.top(),face.right(),face.bottom()#获取人脸左,上,右,下的坐标points = shape_detector(frame,face)#获取人脸68关键点for point in points.parts():cv2.circle(frame,(point.x,point.y),2,(0,255,0),-10)#绘制68关键点cv2.rectangle(frame,(l,t),(r,b),(0,255,0),2)#绘制人脸框if collect_count < count:now = time.time()if now - start_time > interval:face_descriptor = face_descriptor_extractor.compute_face_descriptor(frame,points)#获取特征描述符face_descriptor = [f for f in face_descriptor]#转换成列表方便存进feaure.csvline = [label_id,name,face_descriptor]csv_writer.writerow(line)#写入csv_writercollect_count +=1start_time = nowprint("采集次数:{collect_count}".format(collect_count = collect_count))copy_collect_count = collect_count
# print(face_descriptor)else:if 3 == copy_collect_count:print("采集完毕")copy_collect_count = 0break#展示 cv2.imshow('Face attendance',frame)#展示每一帧图片if cv2.waitKey(10) & 0xFF == ord('q'):breakf.close()cap.release()cv2.destroyAllWindows()faceRegister()
2. 人脸识别:将检测的人脸特征与feaure.csv人脸特征作比较,如果比中把考勤记录写入attendance.csv
①从磁盘中调取注册时的人脸特征描述符,解析它
def getFeatureList():label_list = []name_list = []featuree_list = None"""后面用的np.concatenate()方法决定了此处不能是空列表,否则无法拼接"""with open('./2/feature.csv','r') as f:csv_reader = csv.reader(f)for line in csv_reader:label_id = line[0]name = line[1]face_descriptor = eval(line[2])"""从csv文件拿出来的列表是字符串,需要eval处理一下转为list"""face_descriptor = np.asarray(face_descriptor,dtype=np.float64)face_descriptor = np.reshape(face_descriptor,(1,-1))"""转成1xn格式,期望就是这样"""label_list.append(label_id)"""label_list拼接过程"""name_list.append(name)"""name_list拼接过程"""if featuree_list is None:"""featuree_list拼接过程"""featuree_list = face_descriptorelse:featuree_list = np.concatenate((featuree_list,face_descriptor),axis=0)
# print(name)return label_list,name_list,featuree_listlabel_list,name_list,featuree_list = getFeatureList()"""读取人脸注册时的特征"""
②特征描述符比对,计算与库的距离
distance = np.linalg.norm((face_descriptor-featuree_list),axis=1)"""范数求差"""
min_index = np.argmin(distance)"""获取最短距离索引"""
min_distance = np.argmin(distance)"""获取最短距离"""
if min_distance < threshold:"""识别到打印信息"""predict_id = label_list[min_distance]predict_name = name_list[min_distance]
③依据条件确认是否记录考勤
need_insert = False"""用于后面判断是否变化了考勤,是则写入到attendance.csv文件"""
if predict_name in recog_record:"""第一次检测到考勤则记录人脸信息,记录的是名字与考勤时间组成的键值对,如这次检测与上次记录差3s,则再考勤一次。上述都不是则跳过"""if time.time()-recog_record[predict_name]>3:need_insert = Truerecog_record[predict_name] = time.time()print(predict_name)else:print("无需重复签到!")need_insert = Falsepass
else:need_insert = Truerecog_record[predict_name] = time.time()print(predict_name)
④将考勤记录写入文件
if need_insert:"""考勤较上次变化了则记录"""time_local = time.localtime(recog_record[predict_name])"""时间戳"""time_str = time.strftime("%Y-%m-%d %H:%M:%S",time_local)"""化时间戳为年月日"""line = [predict_id,predict_name,min_distance,time_str]csv_writer.writerow(line)print("{name} {time}考勤记录已成功更新入文件!".format(name=predict_name,time=time_str))
①-④组合在一起复合代码如下:
def faceRecognizer(threshold = 0.5):#1)实时获取视频流中人脸特征描述符;#1准备工作label_list,name_list,featuree_list = getFeatureList()#读取人脸注册时的特征hog_face_detector = dlib.get_frontal_face_detector()#①启动hog人脸检测器shape_detector = dlib.shape_predictor('./1/shape_predictor_68_face_landmarks.dat')#①启动人脸关键点检测器face_descriptor_extractor = dlib.face_recognition_model_v1('./1/dlib_face_recognition_resnet_model_v1.dat')#①启动特征描述符检测器cap = cv2.VideoCapture(0)#②调取摄像头recog_record = {}#为存考勤信息做准备f = open('./2/attendance.csv','a',newline="")#为文件性质记录考勤数据做准备csv_writer = csv.writer(f)fps_time = time.time()#画面显示fps#2获取人脸识别中采集到的特征while True:ret,frame = cap.read()frame = cv2.flip(frame,1)#y轴镜像detections = hog_face_detector(frame,1)#获取人脸参数,缩放因子为1for face in detections:l,t,r,b = face.left(),face.top(),face.right(),face.bottom()#获取人脸左,上,右,下的坐标points = shape_detector(frame,face)#获取人脸68关键点cv2.rectangle(frame,(l,t),(r,b),(0,255,0),2)#绘制人脸框face_descriptor = face_descriptor_extractor.compute_face_descriptor(frame,points)#获取特征描述符face_descriptor = [f for f in face_descriptor]#转换成列表方便存进feaure.csv #3计算与库的距离distance = np.linalg.norm((face_descriptor-featuree_list),axis=1)#范数求差min_index = np.argmin(distance)#获取最短距离索引min_distance = np.argmin(distance)#获取最短距离if min_distance < threshold:#识别到打印信息predict_id = label_list[min_distance]predict_name = name_list[min_distance]#6给人脸框添加内容cv2.putText(frame,predict_name+" "+str(round(min_distance,2)),(l,b+30),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,(0,255,0),1)#4是否记录考勤 need_insert = False#用于后面判断是否变化了考勤,是则写入到attendance.csv文件if predict_name in recog_record:#第一次检测到考勤则记录人脸信息,记录的是名字与考勤时间组成的键值对,如这次检测与上次记录差3s,则再考勤一次。上述都不是则跳过if time.time()-recog_record[predict_name]>3:need_insert = Truerecog_record[predict_name] = time.time()print(predict_name)else:print("无需重复签到!")need_insert = Falsepasselse:need_insert = Truerecog_record[predict_name] = time.time()print(predict_name)if need_insert:#考勤较上次变化了则记录time_local = time.localtime(recog_record[predict_name])#时间戳time_str = time.strftime("%Y-%m-%d %H:%M:%S",time_local)#化时间戳为年月日line = [predict_id,predict_name,min_distance,time_str]csv_writer.writerow(line)print("{name} {time}考勤记录已成功更新入文件!".format(name=predict_name,time=time_str))else:print("未识别到") #5增加FPSnow = time.time()fps = 1/(now - fps_time)fps_time = nowcv2.putText(frame,"FPS:"+str(round(fps,2)),(20,40),cv2.FONT_HERSHEY_COMPLEX_SMALL,1,(0,255,0),1)cv2.imshow('Face attendance',frame)#展示每一帧图片if cv2.waitKey(10) & 0xFF == ord('q'):breakf.close()cap.release()cv2.destroyAllWindows() #读取人脸注册时的特征
def getFeatureList():label_list = []name_list = []featuree_list = None#后面用的np.concatenate()方法决定了此处不能是空列表,否则无法拼接with open('./2/feature.csv','r') as f:csv_reader = csv.reader(f)for line in csv_reader:label_id = line[0]name = line[1]face_descriptor = eval(line[2])#从csv文件拿出来的列表是字符串,需要eval处理一下转为listface_descriptor = np.asarray(face_descriptor,dtype=np.float64)face_descriptor = np.reshape(face_descriptor,(1,-1))#转成1xn格式,期望就是这样label_list.append(label_id)#label_list拼接过程name_list.append(name)#name_list拼接过程if featuree_list is None:#featuree_list拼接过程featuree_list = face_descriptorelse:featuree_list = np.concatenate((featuree_list,face_descriptor),axis=0)
# print(name)return label_list,name_list,featuree_listlabel_list,name_list,featuree_list = getFeatureList()
faceRecognizer(threshold = 10)
四。项目源码
源码链接:点击这里
相关文章:
人脸考勤机项目
文章内容如下: 1)项目简介 2)开发环境和使用的技术知识 3)功能实现 4)项目源码 一。项目简介 此项目是基于HOG和Dlib开发的一套实时无感考勤系统。首先是待考勤人员的个人信息录入。然后在过道或者入口处装置人脸…...
Python编程自动化办公案例(3)
作者简介:一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页 目录 前言 一.前几章代码 1.获取到第一题的选项单元格 2.实现批量获取文件 二. 批…...
Linux-MYSQL 登录数据库(命令行,图形化) 及 远程登录
命令行登录 :mysql 命令登录数据库语法 : mysql -u用户名 -p密码 -h 连接的数据库服务器的ip [-D] 数据库名 -p 端口注 : 上面的 mysql 命令是指的是 客户端的指令 ~!!-h : 指的就是 连接数据库服务器的 ip…...
electron网络环境在线/离线事件探测
electron判断网络环境问题,可以说在任何桌面应用都可以使用到,处理方式有很多种,我介绍几种办法第一种HTML5 API navigator.onLine:官方案例给的,这边为直接贴出地址了,有兴趣的同学可自行查看https://www.…...
UE 项目导航数据生成配置
WP构建及常规构建操作WP构建方式 :https://docs.unrealengine.com/5.0/zh-CN/world-partitioned-navigation-mesh/常规构建方式针对WP的构建方式特殊配置项关闭就好:取消勾选RecastNavMesh-XXX下的IsWorldPartitioned执行n.bNavMeshAllowPartitionedBuil…...
494.目标和
1. 回溯算法 这题和之前做的那些排列、组合的回溯稍微有些不同,你不需要每次选数据时都是for遍历去选择,很明显这是顺序选择的 比如 数组[0,1],target1; 递归数组,每个元素都 或者 - ,然后取最后结果为0…...
滑台模组的应用有哪些?
在自动化生产中,我们常常会看到滑台模组的身影,那么,滑台模组究竟在自动化生产设备中起着怎样的作用呢? 简单点说,滑台模组由滑块、滚珠丝杆、导轨、主体等其它传动零件组成的自动化晋级单元,经过各单元的组…...
CS224W课程学习笔记(四):node2vec算法原理与说明
引言 什么是图嵌入? 我想从上节的deepwalk中已经有一个十分完整的轮廓了,这里引出deepwalk论文中的一张很形象的图(当然,上节的一些实战演练,也将这种嵌入关系进行了模拟与可视化,前文为:&…...
扩展lucas定理
前置知识: lucas定理中国剩余定理 介绍 当正整数n,mn,mn,m很大,且质数ppp较小的时候,要求CnmC_n^mCnm对ppp取模后的值,可以用lucas定理。 但如果ppp不是质数,那该怎么办呢?如果mmm较小,则…...
医疗影像工具LEADTOOLS 入门教程: 从 PDF 中提取附件 - 控制台 C#
LEADTOOLS 是一个综合工具包的集合,用于将识别、文档、医疗、成像和多媒体技术整合到桌面、服务器、平板电脑、网络和移动解决方案中,是一项企业级文档自动化解决方案,有捕捉,OCR,OMR,表单识别和处理&#…...
【LVGL】学习笔记--(1)Keil中嵌入式系统移植LVGL
一 LVGL简介最近emwin用的比较烦躁,同时被LVGL酷炫的界面吸引到了,所以准备换用LVGL试试水。LVGL(轻量级和通用图形库)是一个免费和开源的图形库,它提供了创建嵌入式GUI所需的一切,具有易于使用的图形元素,美丽的视觉效…...
Transformer学习笔记
Transformer学习笔记1. 参考2. 模型图3.encoder部分3.1 Positional Encoding3.2 Muti-Head Attention3.3 ADD--残差连接3.4 Norm标准化3.5 单个Transformer Encoder流程图4.decoder部分4.1 mask Muti-Head Attention4.2 Muti-Head Attention5 多个Transformer Encoder和多个Tra…...
vue-cli引入wangEditor、Element,封装可上传附件的富文本编辑器组件(附源代码直接应用,菜单可调整)
关于Element安装引入,请参考我的另一篇文章:vue-cli引入Element Plus(element-ui),修改主题变量,定义全局样式_shawxlee的博客-CSDN博客_chalk variables 1、安装wangeditor npm i wangeditor --savewangE…...
移动办公时代,数智化平台如何赋能企业管理升级?
在传统的办公模式下,企业组织办公不仅时效低,周期长、成本高,且各办公系统相互独立。随着社会经济的发展,人们的工作生活变得多样化,对于办公的需求也越来越多,存在明显弊端的传统办公模式已不能满足企业对…...
2023“拼夕夕”为什么可以凭借简单的拼团做这么大?
2023“拼夕夕”为什么可以凭借简单的拼团做这么大? 2023-02-24 梦龙 大家好,我是你们熟悉而又陌生的好朋友梦龙,一个创业期的年轻人 大家都知道,拼夕夕背后的商业模式是拼团,但是大家知道为什么简单的拼团可以让拼夕…...
sqlmap工具
sqlmap Sqlmap是一个开源的渗透测试工具,可以用来自动化的检测,利用SQL注入漏洞,获取数据库服务器的权限。目前支持的数据库有MySQL、Oracle、PostgreSQL、Microsoft SQL Server、Microsoft Access等大多数据库 Sqlmap采用了以下5种独特的SQ…...
高/低压供配电系统设计——安科瑞变电站电力监控系统的应用
摘 要:在电力系统的运行过程中,变电站作为整个电力系统的核心,在保证电力系统可靠的运行方面起着至关重要的作用,基于此需对变电站监控系统的特点进行分析,结合变电站监控系统的功能需求,对变电站电力监控系…...
Tapdata 和 Databend 数仓数据同步实战
作者:韩山杰https://github.com/hantmacDatabend Cloud 研发工程师基础架构在云计算时代也发生着翻天地覆的变化,对于业务的支持变成了如何能利用好云资源实现降本增效,同时更好的支撑业务也成为新时代技术人员的挑战。 本篇文章通过…...
单核CPU, 1G内存,也能做JVM调优吗?
最近,笔者的技术群里有人问了一个有趣的技术话题:单核CPU, 1G内存的超低配机器,怎么做JVM调优?这实际上是两个问题。单核CPU的超低配机器,怎么充分利用CPU?单核CPU, 1G内存的超低配机器,怎么做J…...
《计算机应用研究》投稿经历和时间节点
记录四川计算机研究院《计算机应用研究》期刊投稿经历和时间节点。 日期状态周期2022.11.09上传稿件当天显示编辑部已接收稿件,开始初审2022.11.09 – 2022.11.15初审6天2022.11.15 – 2022.12.21外审36天2022.12.21收到退修意见(邮件形式)编…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
