首先需要安装opencv、dlib、face_recongnition库,opencv安装起来比较简单,其他两个库的安装请看关于face_recognition的安装最简单方式_时间和我都在往前走的博客-CSDN博客
这里代码可以直接用,不过路径得自己改,运行时按Ctrl+s先将要进行识别的人脸信息以人名—+扩展名保存在name里面,后续再运行一次,就会出现识别出来的人物姓名,按Esc退出程序,在csv里面就会出现签到信息。
当然这个只是实现了初步,比如说可以直接拿照片蒙混过关进行签到,或者戴个口罩就不行识别出来,所以有什么办法改进大家可以一起交流呀
import cv2
import face_recognition
import numpy as np
from PIL import Image,ImageDraw,ImageFont
import os
import datetime
Images = []#存储人脸数据集中的图像
Names = []#存储人脸数据中图像对应的人名
def ChineseText(img,text,position,textColor=(0,255,0),textSize=18):
#判断是否是opencv图片类型
if(isinstance(img,np.ndarray)):
img = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
#创建一个绘画对象
draw = ImageDraw.Draw(img)
#文字字体等属性设置
fontStyle = ImageFont.truetype('simsun.ttc',textSize,encoding ='utf-8')
#画文字
draw.text(position,text,textColor,font =fontStyle)
return cv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR)#rgb转化为bgr
#获取人脸的图像文件
def get_data():
path = "name" #文件路径
fileList = os.listdir(path)
print(fileList)
for file in fileList:
curImg = cv2.imdecode(np.fromfile(f'{path}/{file}',dtype=np.uint8),-1)
Images.append(curImg)
Names.append(os.path.splitext(file)[0])#分离文件名,取前面的名称,去掉扩展名
print(Names)
#获取人脸编码信息
def imgEncoding(Images):
encodeList = []#存储人脸的编码信息
for img in Images:
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
encode = face_recognition.face_encodings(img)[0]
encodeList.append(encode)
return encodeList
def saveInfo(name):
with open('save.csv','r+') as f:
myInfo = f.readlines()#读取
nameList = []
for line in myInfo:
enty = line.split(',')
nameList.append(enty[0])
if name not in nameList:
now = datetime.datetime.now()#获取时间信息
dtString = now.strftime('%H:%M:%S')#设置时间格式
f.writelines((f'\n{name},{dtString}'))#按行写入到csv文件中
#人脸识别签到
get_data()#先获取到人脸文件
encodeList = imgEncoding(Images)#再获取人脸集中的脸部编码
test = cv2.imread('image/qiwei.jpg')#用测试图进行测试
# test = cv2.cvtColor(test,cv2.COLOR_BGR2RGB)
cap = cv2.VideoCapture(0)
while True:
success,img = cap.read()
if success:
test = img
testLoc = face_recognition.face_locations(test)
testEcode = face_recognition.face_encodings(test)
#遍历摄像头中编好码的图像和人脸位置
for face,faceLoc in zip(testEcode,testLoc):
matches = face_recognition.compare_faces(encodeList,face,0.5)
faceDis = face_recognition.face_distance(encodeList,face)
#找到距离最小的下标
matchIdex = np.argmin(faceDis)
if matches[matchIdex]: #如果最小距离的比配结果为真
name = Names[matchIdex]
#找人脸位置四个角点的坐标
y1,x2,y2,x1 = faceLoc
cv2.rectangle(test,(x1,y1),(x2,y2),(255,0,0),2)
cv2.rectangle(test,(x1,y1-30),(x2,y1),(255,0,0),cv2.FILLED)#将识别到的名字写到实心矩形
img = ChineseText(test,name,(x1+6,y1-25),(255,255,255),30)
#调用签到函数
saveInfo(name)
cv2.imshow("image",img)
if cv2.waitKey(1) & 0xff ==27:
break
cap.release()
cv2.destroyAllWindows()