900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 树莓派实现人脸检测

树莓派实现人脸检测

时间:2021-06-08 02:09:51

相关推荐

树莓派实现人脸检测

文章目录

准备工作实现阶段 一、人脸检测1.下载分类器2.代码3.检测结果 二、数据收集1.新建一个文件夹2.编写代码3.运行效果 三、训练识别器1.新建一个文件夹2.编写代码3.运行效果 四、人脸识别1.编写代码2.运行结果 参考文档

准备工作

先在树莓派上下载好OpenCV3版本

可参考我的上一篇文章。

安装openCV

实现阶段

1.人脸检测和数据收集

2.训练识别器

3.人脸识别

一、人脸检测

1.下载分类器

直接下载xml文件

OpenCV 也包含很多预训练分类器,可用于人脸、眼睛、笑容等的检测。相关的 XML 文件可从该目录下载:

/opencv/opencv/tree/master/data/haarcascades

安装openCV自带

安装OpenCV成功后,在opencv-3.4.0/data中会有好几个文件,其中以下文件存放了OpenCV自带的级联分类器文件,都是已经训练好的文件,可以检测人脸、眼睛、嘴等部位,但效果也并非就是完美的,会存在一些准确率问题,毕竟是开源的嘛,想要准确率很高的还是得自己训练。

2.代码

我的级联分类器放在/home/pi/haarcascade/目录下,请根据实际情况修改。

import cv2# 导入人脸级联分类器,'.xml'文件里包含训练出来的人脸特征face_engine = cv2.CascadeClassifier('/home/pi/haarcascade/haarcascade_frontalface_default.xml')# 导入人眼级联分类器,'.xml'文件里包含训练出来的人眼特征eye_cascade = cv2.CascadeClassifier('/home/pi/haarcascade/haarcascade_eye.xml')# 调用摄像头摄像头cap = cv2.VideoCapture(0) while(True):# 获取摄像头拍摄到的画面# 会得到两个参数,一个是否捕捉到图像(True/False),另一个为存放每帧的图像ret, frame = cap.read() # 读取一帧图像# 每帧图像放大1.1倍,重复检测10次faces = face_engine.detectMultiScale(frame,1.1, 10) # 得到人脸,可能不止一个img = frame # 复制for (x,y,w,h) in faces:# 画出人脸框,蓝色,画笔宽度为2img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)# 框选出人脸区域,在人脸区域而不是全图中进行人眼检测,节省计算资源face_area = img[y:y+h, x:x+w] # 人脸区域eyes = eye_cascade.detectMultiScale(face_area,1.1,5)# 用人眼级联分类器在人脸区域进行人眼识别,返回的eyes为眼睛坐标列表for (ex,ey,ew,eh) in eyes:#画出人眼框,绿色,画笔宽度为1cv2.rectangle(face_area,(ex,ey),(ex+ew,ey+eh),(0,255,0),1)# 实时展示效果画面cv2.imshow('frame2',img)# 每5毫秒监听一次键盘动作if cv2.waitKey(5) & 0xFF == ord('q'): #当按下“q”键时退出人脸检测break# 最后,关闭所有窗口cap.release()cv2.destroyAllWindows() # 释放资源

其中一些重要的参数

我们必须调用分类器函数,向其输入一些非常重要的参数,如比例因子、邻近数和人脸检测的最小尺寸。

例如:

faces = faceCascade.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=5,minSize=(20, 20))

其中:

gray 表示输入 grayscale 图像。

scaleFactor 表示每个图像缩减的比例大小。

minNeighbors 表示每个备选矩形框具备的邻近数量。数字越大,假正类越少。

minSize 表示人脸识别的最小矩形大小。

3.检测结果

可见框起来的部分就是检测的人脸

二、数据收集

1.新建一个文件夹

先新建一个文件夹用来存储用图像获取的照片

2.编写代码

获取摄像头的图像

import cv2import oscam = cv2.VideoCapture(0) # 获取摄像头cam.set(3, 640) # set video width # 设置视频的高度和宽度cam.set(4, 480) # set video height# 检测人脸face_detector = cv2.CascadeClassifier('/home/pi/haarcascade/haarcascade_frontalface_default.xml')# For each person, enter one numeric face idface_id = input('\n enter user id end press <return> ==> ')#print("\n [INFO] Initializing face capture. Look the camera and wait ...")# Initialize individual sampling face countcount = 0while(True):ret, img = cam.read() # 从摄像头读取图像# img = cv2.imread("/home/pi/Desktop/陈卓璇/" + str(count) + '.jpg')#print("/home/pi/Desktop/兔子牙/" + str(count) + '.jpg')# 翻转图像 1 水平翻转 0 垂直翻转 -1 水平垂直翻转#img = cv2.flip(img, -1) # flip video image verticallygray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转化为灰度图faces = face_detector.detectMultiScale(gray, 1.3, 5) # 识别人脸count += 1# 在人脸上画矩形for (x,y,w,h) in faces:cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)# Save the captured image into the datasets foldercv2.imwrite("/home/pi/Desktop/dataset/user." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])cv2.imshow('image', img) # 显示#cv2.imshow('image', img) # 显示k = cv2.waitKey(100) & 0xff # Press 'ESC' for exiting videoif k == 27:breakelif count >= 10: # Take 10 face sample and stop videobreak# Do a bit of cleanupprint("\n [INFO] Exiting Program and cleanup stuff")cam.release()cv2.destroyAllWindows()

获取文件夹的图片

先准备一个文件夹。里面放上图片

只需要按下面修改

注释掉第一句,释放第二句和第三句。

3.运行效果

在桌面dataset文件夹里有10张图片

三、训练识别器

我们需要从数据集中抽取所有的用户数据,并训练 OpenCV 识别器,这一过程可由特定的 OpenCV 函数直接完成。这一步将在「trainer/」目录中保存为.yml 文件。

1.新建一个文件夹

2.编写代码

import numpy as npfrom PIL import Image # python里面的图像库import osimport cv2# Path for face image databasepath = '/home/pi/Desktop/dataset' # 数据集的路径recognizer = cv2.face.LBPHFaceRecognizer_create()detector = cv2.CascadeClassifier("/home/pi/haarcascade/haarcascade_frontalface_default.xml");# function to get the images and label datadef getImagesAndLabels(path):imagePaths = [os.path.join(path,f) for f in os.listdir(path)]# print(imagePaths) # 输出文件夹所有的文件路径faceSamples=[] # 存放人脸ids = [] # 存放人脸的IDfor imagePath in imagePaths: # 遍历路径PIL_img = Image.open(imagePath).convert('L') # convert it to grayscaleimg_numpy = np.array(PIL_img,'uint8')#print(os.path.split(imagePath)[-1])id = int(os.path.split(imagePath)[-1].split(".")[1]) # 获取ID#print(" " + str(id)) # 输入IDfaces = detector.detectMultiScale(img_numpy)for (x,y,w,h) in faces:faceSamples.append(img_numpy[y:y+h,x:x+w])ids.append(id)return faceSamples,idsprint ("\n [INFO] Training faces. It will take a few seconds. Wait ...")faces,ids = getImagesAndLabels(path)recognizer.train(faces, np.array(ids))# Save the model into trainer/trainer.ymlrecognizer.write('/home/pi/Desktop/trainer/trainer.yml') # recognizer.save() worked on Mac, but not on Pi# Print the numer of faces trained and end programprint("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))

在训练过后,文件「trainer.yml」将保存在我们前面定义的 trainer 目录下。此外,我们还在最后使用了 print 函数以确认已经训练的用户面部数量。

3.运行效果

四、人脸识别

这里,我们将通过摄像头捕捉一个新人脸,如果这个人的面孔之前被捕捉和训练过,我们的识别器将会返回其预测的 id 和索引,并展示识别器对于该判断有多大的信心。

1.编写代码

import cv2import numpy as npimport os recognizer = cv2.face.LBPHFaceRecognizer_create() # 识别器recognizer.read('/home/pi/Desktop/trainer/trainer.yml') # 加载训练集cascadePath = "/home/pi/haarcascade/haarcascade_frontalface_default.xml"faceCascade = cv2.CascadeClassifier(cascadePath);font = cv2.FONT_HERSHEY_SIMPLEX # 字体#iniciate id counterid = 0# names related to ids: example ==> Marcelo: id=1, etcnames = ['None', 'luatao','lihua'] # Initialize and start realtime video capturecam = cv2.VideoCapture(0)cam.set(3, 640) # set video widhtcam.set(4, 480) # set video height# Define min window size to be recognized as a faceminW = 0.1*cam.get(3)minH = 0.1*cam.get(4)while True:ret, img =cam.read() # 读取一帧图像#img = cv2.flip(img, -1) # Flip verticallygray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 转化为灰度图faces = faceCascade.detectMultiScale( gray,scaleFactor = 1.2,minNeighbors = 5,minSize = (int(minW), int(minH)),)for(x,y,w,h) in faces:cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)id, confidence = recognizer.predict(gray[y:y+h,x:x+w])# Check if confidence is less them 100 ==> "0" is perfect match if (confidence < 100):id = names[id]confidence = " {0}%".format(round(100 - confidence))else:id = "unknown"confidence = " {0}%".format(round(100 - confidence))cv2.putText(img, str(id), (x+5,y-5), font, 1, (255,255,255), 2)cv2.putText(img, str(confidence), (x+5,y+h-5), font, 1, (255,255,0), 1) cv2.imshow('camera',img) k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting videoif k == 27:break# Do a bit of cleanupprint("\n [INFO] Exiting Program and cleanup stuff")cam.release()cv2.destroyAllWindows()

recognizer.predict () 将把待分析人脸的已捕捉部分作为一个参数,并返回其可能的所有者,指示其 id 以及识别器与这一匹配相关的置信度。

注意,如果匹配是完美的,置信度指数将返回「零」。

2.运行结果

参考文档

//03/09/real-time-face-recognition-an-end-to-end-project-with-raspberry-pi.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。