1、提出问题
通过python+opencv实现对摄像头输入的图像实时人脸识别,或者对输入的图片进行人脸识别
2、解决思路
本项目主要有两个模块:数据训练和人脸识别
1.1 数据训练
数据训练模块的思路如下:
(1)定义getImageAndLabels()用来返回训练图像的脸部数据和图像文件名中的顺序数据:
faces和ids
(2)创建、加载识别器recognizer
(3)对faces和np.array(ids)进行训练:recognizer.train(faces, np.array(ids))
(4)训练好的数据存储在trainer.yml下,便于人脸识别模块调用
1.2 人脸识别
人脸识别模块的思路如下:
(1)加载数据训练模块的训练数据
(2)加载opencv提供的人脸分类器
(3)定义face_detect_demo()方法获取需要识别的图片上的人脸并在脸部绘制方框,把方框内部的人脸数据与trainer.yml中的数据对比,返回trainer.yml文件中相似图片数据的id和confidence
(4)定义name()方法获取训练图片的人名,以便于对识别出的图片中的人脸做标记
(5)将摄像头捕捉的图像抽帧传入face_detect_demo()实时识别并在图片上显示结果
3、代码
3.1 数据训练模块代码
import os import cv2 as cv import numpy as np from PIL import Image def getImageAndLabels(path): #储存人脸信息 facesSamples = [] #储存序号数据 ids = [] #储存姓名信息 names = [] #储存图片信息 imagePaths = [] # 得到文件名中的人名 # listdir列出文件夹下的文件 for file in os.listdir(path): if file.endswith('jpg'): # 路径拼接,imagePath是图片的绝对路径 imagePath = os.path.join(path, file) # 将图片路径添加到列表中 imagePaths.append(imagePath) #加载分类器 face_detector = cv.CascadeClassifier('D:/Software/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') #id从0开始 id = 1 #遍历imagePaths中存储的绝对路径对应的图片 for imagePath in imagePaths: #打开图片,灰度化PIL有九种不同模式,其中1为黑白,L为灰度 PIL_img = Image.open(imagePath).convert('L') #将图像转换成数组,以黑白深浅 img_numpy = np.array(PIL_img,'uint8') #获取图片人脸特征 faces = face_detector.detectMultiScale(image=img_numpy,scaleFactor=1.01,minNeighbors=5,minSize=(180,180),maxSize=(300,300)) # 得到图片绝对路径列表中的人名,存储在names列表 name = (os.path.split(imagePath)[1].split('-')[1]).split('.')[0] #预防无面容照片 for x,y,w,h in faces: names.append(name) ids.append(id) facesSamples.append(img_numpy[y:y+h,x:x+w]) #打印脸部特征和id print('id:',id) print('name:',name) print('fs',img_numpy[y:y+h,x:x+w]) # id自增1 id += 1 print(ids) print(names) return facesSamples,ids if __name__ == '__main__': #图片的路径 path = 'D:/SoftwareCache/PyCharmCache/Project_Face/trainer/faces' #获取图像数组和id标签数组和姓名 faces,ids = getImageAndLabels(path) #加载识别器 recognizer = cv.face.LBPHFaceRecognizer_create() #训练 recognizer.train(faces, np.array(ids)) print(ids) #保存文件 recognizer.write('./trainer.yml')
3.2 人脸识别模块代码
import cv2 as cv import os import numpy as np from PIL import Image import urllib import urllib.request #加载训练数据集文件 recognizer = cv.face.LBPHFaceRecognizer_create() #加载数据 recognizer.read('./trainer.yml') #名字 names = [] #警报全局变量 warningtime = 0 face_detector = cv.CascadeClassifier('D:/Software/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml') #准备识别的图像 def face_detect_demo(img): gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)#转换为灰度 #加载官方人脸识别器 face_detector = cv.CascadeClassifier('D:/Software/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') #在gray图上找出人脸 face = face_detector.detectMultiScale(gray,1.01,5,cv.CASCADE_SCALE_IMAGE,(180,180),(300,300)) for x,y,w,h in face: #在img上面绘制脸部方框 cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=1) #img上绘制脸部圆圈 cv.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1) #人脸识别 ids,confidence = recognizer.predict(gray[y:y+h,x:x+w]) print(ids) print('confidence:',confidence) print('name:',names[ids-1]) if confidence > 120: #gloal声明一个全局变量 global warningtime warningtime += 1 if warningtime > 100: #不是存储在数据库中的人脸,图片上打印:unknown # # cv.putText(img,'unknown',(x,y+15),cv.FONT_HERSHEY_SIMPLEX,0.75,(0,255,0),1) else: cv.putText(img,str(names[ids-1]),(x,y+15),cv.FONT_HERSHEY_SIMPLEX,0.75,(0,255,0),1) cv.imshow('result',img) def name(): imagePaths = [] path = './faces' for file in os.listdir(path): if file.endswith('jpg'): # 路径拼接,imagePath是图片的绝对路径 imagePath = os.path.join(path, file) # 将图片路径添加到列表中 imagePaths.append(imagePath) #得到图片文件名中的名字 for imagePath in imagePaths: # 打开图片,灰度化PIL有九种不同模式,其中1为黑白,L为灰度 PIL_img = Image.open(imagePath).convert('L') # 将图像转换成数组,以黑白深浅 img_numpy = np.array(PIL_img, 'uint8') # 获取图片人脸特征 faces = face_detector.detectMultiScale(image=img_numpy, scaleFactor=1.01, minNeighbors=5, minSize=(180, 180), maxSize=(300, 300)) # 得到图片绝对路径列表中的人名,存储在names列表 name = (os.path.split(imagePath)[1].split('-')[1]).split('.')[0] # 预防无面容照片 for x, y, w, h in faces: names.append(name) # 打印脸部特征和id print('id:', id) print('name:', name) print('fs', img_numpy[y:y + h, x:x + w]) print(names) cap = cv.VideoCapture(0) name() # #以图片做实验 # #D:SoftwareCachePyCharmCacheProject_FacetrainerFERET_80_80FERET_80_80-人脸数据库FERET-001-Lesley # # frame = cv.imread('./face8.jpg') # face_detect_demo(frame) # # while True: # if ord('q') == cv.waitKey(0): # break # # cv.destroyAllWindows() #以摄像头捕捉图像做实验 while True: flag,frame = cap.read() if not flag: break face_detect_demo(frame) if ord(' ') == cv.waitKey(10): break cv.destroyAllWindows() cap.release()
4、结果如下
5、声明
此篇博客为笔者学习B站python+opencv人脸识别项目后自己的一点总结,侵权请联系笔者删除。
B站视频链接:一天搞定人脸识别项目!学不会up直接下跪!(python+opencv)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Lq4y1Z7dm?spm_id_from=333.999.0.0
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)