#主要思路 读取文件夹中已知图片中人物的人脸特征,保存在人脸特征列表中,然后使用摄像头识别到的 #人 获取其人脸特征与保存的相比较 相识度误差不超过0.42 误差程序中可自行调整 #最好安装GPU版本dlib 识别画面会流畅很多 CPU版本画面比较缓慢 import os # import dlib import cv2 import numpy as np import face_recognition from datetime import datetime from PIL import Image, ImageDraw, ImageFont import codecs import re import win32gui #参数是默认参数 可自行修改 #这里实现窗口显示中文汉字 不是乱码 def zh_ch_Titile(oldTitle,newTitle='中文',oneRun=False): if oneRun == False: handle = win32gui.FindWindow(0, oldTitle) win32gui.SetWindowText(handle, newTitle) oneRun= True return oneRun #该函数实现读取中文路径的图片 def imread2(imagePathName): # 读取中文路径图片 retImg = cv2.imdecode(np.fromfile(imagePathName, dtype=np.uint8), -1) return retImg #该函数实现显示中文不会成乱码 def putText2(img,text,pos,size=36,color=(255,0,0)): img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) font = ImageFont.truetype(font=r'simsun.ttc', size=size) draw = ImageDraw.Draw(img_pil) draw.text(pos, text, font=font, fill=color) # PIL中RGB=(255,0,0)表示红色 img_cv = np.array(img_pil) # PIL图片转换为numpy img = cv2.cvtColor(img_cv, cv2.COLOR_RGB2BGR) # PIL格式转换为OpenCV的BGR格式 return img #此处为了实现同一个人使用多张图片仍然正常识别 #比如为了识别张三 我们使用多张不同环境的图片或者不同光照条件的图片 为了提高正确的识别率 #命名为 张三.jpg 张三01.jpg 014张三.jpg 该程序都使用正则表达式忽略文件名中前后的数字 #保证程序识别率高 第一次到达的时间保存在csv文件中 path="images" pattern = re.compile(r'(\d)*(\D+)(\d)*.*') # 查找文件名 排除数字 # fileExist=os.path.isfile('a.csv') # if not fileExist: with codecs.open("最早到来时间.csv", 'w',encoding='utf-8') as f: f.write("姓名,时间") #内存保存图片对象 images=[] #保存图片名字,不包含扩展名,进行分类 classNames=[] templateImageList=os.listdir(path) print(templateImageList) for currentImage in templateImageList: if os.path.splitext(currentImage)[1].lower() in [".jpg",".png",".jpeg"]: img=imread2(f"{path}/{currentImage}") images.append(img) print("加载图片", os.path.splitext(currentImage)[0]) classNames.append(os.path.splitext(currentImage)[0]) print("所有图片",classNames) #传入内存图片对象 读取特征保存到列表中 def findEncodings(imagesInMemory): n=len(imagesInMemory) encodeList=[] i=0 for img in imagesInMemory: i=i+1 img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB) face_locations = face_recognition.face_locations(img) if len(face_locations) != 1: print("不是有效的图片") continue encode=face_recognition.face_encodings(img)[0] encodeList.append(encode) jdu=round(i/n,2)*100 print(f"读取特征完成 {jdu}%") return encodeList def markAttence(name): with codecs.open('最早到来时间.csv','r+',encoding='utf-8') as f: myDataList=f.readlines() nameList=[] for line in myDataList: entry=line.split(',') excludeNumberName = pattern.match(entry[0]) if excludeNumberName: nameList.append(excludeNumberName.group(2)) excludeNumberName = pattern.match(name) if excludeNumberName.group(2) not in nameList: now=datetime.now() dtString=now.strftime("%Y-%m-%d %H:%M:%S") if excludeNumberName: name1 =excludeNumberName.group(2).strip() f.writelines(f"{os.linesep}{name1},{dtString}") print("第一次发现" + name1 + "已到达") # print(myDataList) # markAttence('a') encodingsSaved=findEncodings(images) print("图片特征加载完毕") cv2.namedWindow("img",cv2.WINDOW_NORMAL) ima=cv2.imread("jz.png") cv2.imshow("img",ima) changeName=False cap=cv2.VideoCapture(0) while True: success,img=cap.read() imgResize=cv2.resize(img,(0,0),None,0.25,0.25) imgResize=cv2.cvtColor(imgResize,cv2.COLOR_BGR2RGB) faceCurrentFrame=face_recognition.face_locations(imgResize) encodeCrentFrame=face_recognition.face_encodings(imgResize,faceCurrentFrame) for encodeFace,faceLoc in zip(encodeCrentFrame,faceCurrentFrame): matches=face_recognition.compare_faces(encodingsSaved,encodeFace) faceDis=face_recognition.face_distance(encodingsSaved,encodeFace) # print(faceDis) matchesIndex=np.argmin(faceDis) #找到最匹配的特征 并且误差不超过0.42 if matches[matchesIndex] and faceDis[matchesIndex]<0.42: name=classNames[matchesIndex].upper() # print(faceDis[matchesIndex],name) y1,x2,y2,x1=faceLoc y1, x2, y2, x1 = y1*4, x2*4, y2*4, x1*4 cv2.rectangle(img,(x1,y1),(x2,y2),(0,255,0),3) faceDis[matchesIndex]=round(faceDis[matchesIndex],2) # cv2.putText(img,name+" "+str(faceDis[matchesIndex]),(x1,y1-10),cv2.FONT_HERSHEY_TRIPLEX,1,(0,255,0),1) excludeNumberName = pattern.match(name) if excludeNumberName: img=putText2(img,excludeNumberName.group(2)+" "+str(faceDis[matchesIndex]),(x1,y1-25),25,(0,255,0)) markAttence(name) cv2.imshow("img",img) k=cv2.waitKey(1) if k & 0xFF==ord('q'): break if changeName == False: changeName = zh_ch_Titile('img', "记录最早到来时间", changeName)
#新增修改上面部分代码,达到对无效图片进行验证 保证无效图片不会被读入