Python+OpenCV人脸识别(基于LBPH+防照片识别+警报)
off999 2024-10-20 08:09 30 浏览 0 评论
- 目录
废话
1.环境配置(jupyter notebook python 3.6.5)
2.训练集准备
3.代码思路(艹图)
4.人脸识别源码
5.参考文章
6.可能遇到的问题
废话
嗯,开局说点废话,之前用stm32和esp8266改装了下宿舍门,但终究觉得没人脸识别来得舒服,所以就有了这篇文章
1.环境配置(jupyter notebook python 3.6.5)
我这里用的是python3.6,如果你想搭建一个3.6的环境又不想影响原有的,可以用小黑窗(Anaconda Prompt)搭建一个虚拟环境(虚拟环境是一个独立的空间不会影响外界,也不会受外界影响,适合应对不同版本python的需求)
如何搭建虚拟环境可以看看这篇文,简单粗暴
当你搭建好虚拟环境后,第三方库的安装也要安在虚拟环境里,那么如何切换到虚拟环境里呢
打开小黑窗 activate 虚拟环境名字就可以激活了效果如下:
看到小括号就说明已经切换到虚拟环境里了
然后就可以安装所需的第三方库了,eg.Opencv,scipy,request,dlib,安装方法如下:
1)OpenCV
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-contrib-python==3.4.2.16
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python==3.4.2.16
2)scipy
pip install scipy
3) request
pip install request
4) dlib
dlib库的安装比较麻烦,你得先找到对应版本,因为不同python版本对应不同dlib
如果你跟我一样是3.6,那装19.7就行
缺版本或找不到对应版本可以留言
2.训练集准备
这个训练集捏,是借助recognizer.train得到的.yml文件,所以精度没特别高,但是拿来玩玩门锁 还是够用,追求精度可以走深度学习
代码如下:
1)第一步准备照片(即你的人脸像),以“序号.名称”命名,例如“1.xx"这是为了方便切片和保存(即我们可以通过切片将每张照片的脸部特征,序号,名称一一对应)记得你照片的存放路径
2)第二步准备人脸数据集haarcascade_frontalface_alt2.xml,这个是opencv自带的用于检测人脸(注意是检测人脸不是识别人脸)这种做法我觉得有点像RIO ,就是我们在一张图片中匹配人像特征不是从角落开始,而是定位人脸,然后规划一个区域,在区域内进行匹配,这样节省很多时间
3)第三步,跑代码就完事了,然后你会在你指定的文件夹里面找到yml文件,这就是你的训练集
import osimport sysfrom PIL import Imageimport numpy as npimport cv2
def getImageAndLabels(path): #建两个空列表后续存储数据 facesSamples=[] ids=[] imagePaths=[os.path.join(path,f) for f in os.listdir(path)] #检测人脸 face_detector = cv2.CascadeClassifier('E:\jupyter_notebook\practice\haarcascades\haarcascade_frontalface_alt2.xml') #打印数组imagePaths print('路径:',imagePaths) #遍历列表中的图片 for imagePath in imagePaths: #打开图片,灰度 PIL_img=Image.open(imagePath).convert('L') #此时获取的是整张图片的数组 img_numpy=np.array(PIL_img,'uint8') #获取图片人脸特征,相当于rio faces = face_detector.detectMultiScale(img_numpy) #将文件名前的名字转化为ID并记录下来 str_id = os.path.split(imagePath)[1].split('.')[0] id = int(str_id) #id = os.path.split(imagePath)[1].split('.')[0] #预防检测到无面容照片 for x,y,w,h in faces: #把ID写进ids列表中 ids.append(id) #把所画的方框写进facesSamples列表中 facesSamples.append(img_numpy[y:y+h,x:x+w]) #打印脸部特征和id print('id:', id) print('fs:', facesSamples) return facesSamples,ids
if __name__ == '__main__': #图片路径 path='E:/face_dormitory/train' #获取图像数组和id标签数组和姓名 faces,ids=getImageAndLabels(path) #获取训练对象 recognizer=cv2.face.LBPHFaceRecognizer_create() recognizer.train(faces,np.array(ids)) #保存文件 recognizer.write('E:/face_dormitory/opencv/trainer/trainer_xx.yml')
3.代码思路(艹图)
4.人脸识别源码
1)引入库
import cv2import numpy as npimport osimport urllibimport urllib.requestimport hashlibfrom scipy.spatial import distance as distfrom collections import OrderedDictimport argparseimport timeimport dlib
2)加载训练集(这里shape_predictor_68_face_landmarks是用于眨眼检测的)
#加载训练数据集文件recogizer=cv2.face.LBPHFaceRecognizer_create()recogizer.read('E:/face_dormitory/opencv/trainer/trainer_xx.yml')names=[] #建个空id列表warningtime = 0predictor = dlib.shape_predictor('E:/face_dormitory/opencv/shape_predictor_68_face_landmarks.dat')
3)邮件函数(即识别出陌生人或可疑人用于发送抓拍照片的)
import smtplibfrom PIL import Imageimport email # 文件名不可以和引入的库同名from email.mime.image import MIMEImage # 图片类型邮件from email.mime.text import MIMEText # MIME 多用于邮件扩充协议from email.mime.multipart import MIMEMultipart # 创建附件类型 HOST = 'smtp.qq.com' # 调用的邮箱借借口SUBJECT = 'Warning!!!' # 设置邮件标题FROM = '1xxxxxxxxx@qq.com' # 发件人的邮箱需先设置开启smtp协议#TO = '1xxxxxxxxxxx@qq.com' # 设置收件人的邮箱(可以一次发给多个人,用逗号分隔)TO = 'xxxxxxxxxx@qq.com' # 设置收件人的邮箱(可以一次发给多个人,用逗号分隔)message = MIMEMultipart('related') # 邮件信息,内容为空 #相当于信封##related表示使用内嵌资源的形式,将邮件发送给对方 def sendmail(HOST, SUBJECT,FROM,TO,message): # ===========发送信息内容============= message_html = MIMEText('<h1 style="color:red;font-size:100px">Warning!!!</h1><img src="cid:small">', 'html', 'utf-8') message.attach(message_html) # ===========发送图片-============= message_image0 = MIMEText(open('E:/face_dormitory/unidentified/0.jpg', 'rb').read(), 'base64', 'utf-8') message_image0['Content-disposition'] = 'attachment;filename="Suspicious people.jpg"'# 设置图片在附件当中的名字 message_image1 = MIMEText(open('E:/face_dormitory/unidentified/1.jpg', 'rb').read(), 'base64', 'utf-8') message_image1['Content-disposition'] = 'attachment;filename="Suspicious people.jpg"'# 设置图片在附件当中的名字 message.attach(message_image0)# 添加图片文件到邮件-附件中去 message.attach(message_image1)# 添加图片文件到邮件-附件中去 ''' path='E:/face_dormitory/unidentified' imagePaths=[os.path.join(path,f) for f in os.listdir(path)] for imagePath in imagePaths: PIL_img=Image.open(imagePath,'utf-8') PIL_img['Content-disposition'] = 'attachment;filename="Suspicious people.jpg"' message.attach(PIL_img) ''' # ===========删除缓冲图片-============= #os.remove('E:/face_dormitory/unidentified/0.jpg') #os.remove('E:/face_dormitory/unidentified/1.jpg') # ===========发送excel-附件============= #message_xlsx = MIMEText(open('email_demo.xlsx', 'rb').read(), 'base64', 'utf-8')# 将xlsx文件作为内容发送到对方的邮箱读取excel,rb形式读取,对于MIMEText()来说默认的编码形式是base64 对于二进制文件来说没有设置base64,会出现乱码 #message_xlsx['Content-Disposition'] = 'attachment;filename="email_demo_change.xlsx"'# 设置文件在附件当中的名字 #message.attach(message_xlsx)# 添加excel文件到邮件-附件中去 # ===========配置相关-============= message['From'] = FROM # 设置邮件发件人 message['TO'] = TO # 设置邮件收件人 message['Subject'] = SUBJECT # 设置邮件标题 email_client = smtplib.SMTP_SSL()# 获取传输协议 email_client.connect(HOST, '465')# 设置发送域名,端口465 result = email_client.login(FROM, 'xxxxxxx') # qq授权码 print('登录结果', result) # ===========操作============= email_client.sendmail(from_addr=FROM, to_addrs=TO.split(','), msg=message.as_string()) #发送邮件指令 email_client.close()# 关闭邮件发送客户端
写邮件函数我是借鉴这个大佬的,站在巨人肩膀上嘛,总不能什么都靠自己来
4)防照片检测(即眨眼检测)这个也可以用于疲劳检测
详见:i·bug - resources - Facial point annotations
FACIAL_LANDMARKS_68_IDXS = OrderedDict([ ("mouth", (48, 68)), ("right_eyebrow", (17, 22)), ("left_eyebrow", (22, 27)), ("right_eye", (36, 42)), ("left_eye", (42, 48)), ("nose", (27, 36)), ("jaw", (0, 17))])
def eye_aspect_ratio(eye): # 计算距离,竖直的 A = dist.euclidean(eye[1], eye[5]) B = dist.euclidean(eye[2], eye[4]) # 计算距离,水平的 C = dist.euclidean(eye[0], eye[3]) # ear值 ear = (A + B) / (2.0 * C) return ear
def shape_to_np(shape, dtype="int"): # 创建68*2 coords = np.zeros((shape.num_parts, 2), dtype=dtype) # 遍历每一个关键点 # 得到坐标 for i in range(0, shape.num_parts): coords[i] = (shape.part(i).x, shape.part(i).y) return coords
def pervent_to_photo(): # 设置判断参数 EYE_AR_THRESH = 0.3 EYE_AR_CONSEC_FRAMES = 3 # 初始化计数器 COUNTER = 0 TOTAL = 0 # 检测与定位工具 print("loading facial landmark predictor...") detector = dlib.get_frontal_face_detector() #predictor = dlib.shape_predictor('E:/face_dormitory/opencv/shape_predictor_68_face_landmarks.dat') # 分别取两个眼睛区域 (lStart, lEnd) = FACIAL_LANDMARKS_68_IDXS["left_eye"] (rStart, rEnd) = FACIAL_LANDMARKS_68_IDXS["right_eye"] # 读取视频 print("starting video stream thread...") vs = cv2.VideoCapture(0) time.sleep(1.0) # 遍历每一帧 while True: # 预处理 frame = vs.read()[1] if frame is None: break (h, w) = frame.shape[:2] width=1200 r = width / float(w) dim = (width, int(h * r)) frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 检测人脸 rects = detector(gray, 0) # 遍历每一个检测到的人脸 for rect in rects: # 获取坐标 shape = predictor(gray, rect) shape = shape_to_np(shape) # 分别计算ear值 leftEye = shape[lStart:lEnd] rightEye = shape[rStart:rEnd] leftEAR = eye_aspect_ratio(leftEye) rightEAR = eye_aspect_ratio(rightEye) # 算一个平均的 ear = (leftEAR + rightEAR) / 2.0 # 绘制眼睛区域 leftEyeHull = cv2.convexHull(leftEye) rightEyeHull = cv2.convexHull(rightEye) cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1) cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1) # 检查是否满足阈值 if ear < EYE_AR_THRESH: COUNTER += 1 else: # 如果连续几帧都是闭眼的,总数算一次 if COUNTER >= EYE_AR_CONSEC_FRAMES: TOTAL += 1 # 重置 COUNTER = 0 # 显示 cv2.putText(frame, "Blinks: {}".format(TOTAL), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) cv2.imshow("Frame", frame) #眨眼两次则判断不是照片 if TOTAL >= 2: cv2.imwrite(r"E:/face_dormitory/unidentified/"+"1.jpg",frame) #抓拍 break #空格退出 if ord(' ') == cv2.waitKey(10): break #vs.release() cv2.destroyAllWindows()
5)人脸检测函数
#准备识别的图片def face_detect_demo(img): gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰度 face_detector=cv2.CascadeClassifier('E:\jupyter_notebook\practice\haarcascades\haarcascade_frontalface_alt2.xml') #加入数据集 face=face_detector.detectMultiScale(gray,1.1,5,cv2.CASCADE_SCALE_IMAGE,(100,100),(300,300)) #范围在100*100~300*300判断为脸 for x,y,w,h in face: cv2.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2) cv2.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1) # 人脸识别 ids, confidence = recogizer.predict(gray[y:y + h, x:x + w]) #置信评分 confidence 越大越不可信 if confidence > 50: global warningtime global num warningtime += 1 if warningtime > 100: #cv2.imwrite(r"E:/face_dormitory/unidentified/"+str(num)+".jpg",frame) #抓拍 cv2.imwrite(r"E:/face_dormitory/unidentified/"+"0.jpg",frame) #抓拍 time.sleep(0.1) sendmail(HOST=HOST, SUBJECT=SUBJECT,FROM=FROM,TO=TO,message=message) print('ddddddddddd') #num += 1 warningtime = 0 cv2.putText(img, 'unidentified', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1) else: cv2.putText(img,str(names[ids-1]), (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1) cv2.imshow('result',img)
#取名函数,切片取名,即照片名为1.cj.jpg,取名后就为cjdef name(): #相册路径 path = 'E:/face_dormitory/train' #循环读图 imagePaths=[os.path.join(path,f) for f in os.listdir(path)] for imagePath in imagePaths: #切名字 name = str(os.path.split(imagePath)[1].split('.',2)[1]) names.append(name)
6)主函数
#防照片识别pervent_to_photo() #打开摄像头,0是本地默认,1是外用,我把本地关了把外用开着所以直接0cap=cv2.VideoCapture(0)name()while True: flag,frame=cap.read() if not flag: break face_detect_demo(frame) #空格退出 if ord(' ') == cv2.waitKey(10): breakcv2.destroyAllWindows()cap.release() ?
5.参考文章
感谢大佬1
感谢大佬2
感谢大佬3
6.可能遇到的问题
1.如果你搭建了虚拟环境且里面安装了opencv,但是再引用的时候报错没装库,看看有没有将虚拟环境导入kernel
2.如果你发现我的逻辑有问题,相信你自己,错的肯定是我,请务必怼我,毕竟有探讨才有完善,我也是个小菜鸡
3.如果出现”No module named XXX“,说明安装差库了,请跑到虚拟环境里去安装,虚拟环境是独立的,你之前安装了什么都跟虚拟环境无关
相关推荐
- python gui编程框架推荐以及介绍(python gui开发)
-
Python的GUI编程框架有很多,这里为您推荐几个常用且功能强大的框架:Tkinter:Tkinter是Python的标准GUI库,它是Python内置的模块,无需额外安装。它使用简单,功能较为基础...
- python自动化框架学习-pyautogui(python接口自动化框架)
-
一、适用平台:PC(windows和mac均可用)二、下载安装:推荐使用命令行下载(因为会自动安装依赖库):pipinstallPyAutoGUI1该框架的依赖库还是蛮多的,第一次用的同学耐心等...
- Python 失宠!Hugging Face 用 Rust 新写了一个 ML框架,现已低调开源
-
大数据文摘受权转载自AI前线整理|褚杏娟近期,HuggingFace低调开源了一个重磅ML框架:Candle。Candle一改机器学习惯用Python的做法,而是Rust编写,重...
- Flask轻量级框架 web开发原来可以这么可爱呀~(建议收藏)
-
Flask轻量级框架web开发原来可以这么可爱呀大家好呀~今天让我们一起来学习一个超级可爱又实用的PythonWeb框架——Flask!作为一个轻量级的Web框架,Flask就像是一个小巧精致的工...
- Python3使用diagrams生成架构图(python架构设计)
-
目录技术背景diagrams的安装基础逻辑关系图组件簇的定义总结概要参考链接技术背景对于一个架构师或者任何一个软件工程师而言,绘制架构图都是一个比较值得学习的技能。这就像我们学习的时候整理的一些Xmi...
- 几个高性能Python网络框架,高效实现网络应用
-
Python作为一种广泛使用的编程语言,其简洁易读的语法和强大的生态系统,使得它在Web开发领域占据重要位置。高性能的网络框架是构建高效网络应用的关键因素之一。本文将介绍几个高性能的Python网络框...
- Web开发人员的十佳Python框架(python最好的web框架)
-
Python是一种面向对象、解释型计算机程序设计语言。除了语言本身的设计目的之外,Python的标准库也是值得大家称赞的,同时Python还自带服务器。其它方面,Python拥有足够多的免费数据函数库...
- Diagram as Code:用python代码生成架构图
-
工作中常需要画系统架构图,通常的方法是通过visio、processon、draw.io之类的软件,但是今天介绍的这个软件Diagrams,可以通过写Python代码完成架构图绘制,确实很co...
- 分享一个2022年火遍全网的Python框架
-
作者:俊欣来源:关于数据分析与可视化最近Python圈子当中出来一个非常火爆的框架PyScript,该框架可以在浏览器中运行Python程序,只需要在HTML程序中添加一些Python代码即可实现。该...
- 10个用于Web开发的最好 Python 框架
-
Python是一门动态、面向对象语言。其最初就是作为一门面向对象语言设计的,并且在后期又加入了一些更高级的特性。除了语言本身的设计目的之外,Python标准库也是值得大家称赞的,Python甚至还...
- 使用 Python 将 Google 表格变成您自己的数据库
-
图片来自Shutterstock,获得FrankAndrade的许可您知道Google表格可以用作轻量级数据库吗?GoogleSheets是一个基于云的电子表格应用程序,可以像大多数数据库管...
- 牛掰!用Python处理Excel的14个常用操作总结!
-
自从学了Python后就逼迫用Python来处理Excel,所有操作用Python实现。目的是巩固Python,与增强数据处理能力。这也是我写这篇文章的初衷。废话不说了,直接进入正题。数据是网上找到的...
- 将python打包成exe的方式(将python文件打包成exe可运行文件)
-
客户端应用程序往往需要运行Python脚本,这对于那些不熟悉Python语言的用户来说可能会带来一定的困扰。幸运的是,Python拥有一些第三方模块,可以将这些脚本转换成可执行的.exe...
- 对比Excel学Python第1练:既有Excel,何用Python?
-
背景之前发的文章开头都是“Python数据分析……”,使得很多伙伴以为我是专门分享Python的,但我的本意并非如此,我的重点还是会放到“数据分析”上,毕竟,Python只是一种工具而已。现在网上可以...
- 高效办公:Python处理excel文件,摆脱无效办公
-
一、Python处理excel文件1.两个头文件importxlrdimportxlwt其中xlrd模块实现对excel文件内容读取,xlwt模块实现对excel文件的写入。2.读取exce...
你 发表评论:
欢迎- 一周热门
-
-
python 3.8调用dll - Could not find module 错误的解决方法
-
加密Python源码方案 PyArmor(python项目源码加密)
-
Python3.8如何安装Numpy(python3.6安装numpy)
-
大学生机械制图搜题软件?7个受欢迎的搜题分享了
-
编写一个自动生成双色球号码的 Python 小脚本
-
免费男女身高在线计算器,身高计算公式
-
将python文件打包成exe程序,复制到每台电脑都可以运行
-
Python学习入门教程,字符串函数扩充详解
-
Python数据分析实战-使用replace方法模糊匹配替换某列的值
-
Python进度条显示方案(python2 进度条)
-
- 最近发表
-
- python gui编程框架推荐以及介绍(python gui开发)
- python自动化框架学习-pyautogui(python接口自动化框架)
- Python 失宠!Hugging Face 用 Rust 新写了一个 ML框架,现已低调开源
- Flask轻量级框架 web开发原来可以这么可爱呀~(建议收藏)
- Python3使用diagrams生成架构图(python架构设计)
- 几个高性能Python网络框架,高效实现网络应用
- Web开发人员的十佳Python框架(python最好的web框架)
- Diagram as Code:用python代码生成架构图
- 分享一个2022年火遍全网的Python框架
- 10个用于Web开发的最好 Python 框架
- 标签列表
-
- python计时 (54)
- python安装路径 (54)
- python类型转换 (75)
- python进度条 (54)
- python的for循环 (56)
- python串口编程 (60)
- python写入txt (51)
- python读取文件夹下所有文件 (59)
- java调用python脚本 (56)
- python操作mysql数据库 (66)
- python字典增加键值对 (53)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python qt (52)
- python人脸识别 (54)
- python斐波那契数列 (51)
- python多态 (60)
- python命令行参数 (53)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- centos7安装python (53)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)