当前位置:   article > 正文

个人学习日志——树莓派实时人脸识别项目_树莓派人脸识别

树莓派人脸识别

这是我运行的第一个项目,源代码来自于GitHub。第一次接触树莓派,python编程

学习目标:

1、了解树莓派的python基础知识   

2、了解程序如何运行

3、了解程序的框架 

4、如何调用接口

硬件:树莓派4B csi500W摄像头 

环境:树莓派官方系统 python3 opencv

参考链接:

1、【创客实战训练营】树莓派使用OpenCV实现简单人脸识别_哔哩哔哩_bilibili​​​​​​

2、实时人脸识别:一个端到端项目 - Hackster.io(主要参考)

3、【opencv】树莓派上OpenCV-Face-Recognition人脸识别配置_BHY_的博客-CSDN博客 

4、GitHub - Mjrovai/OpenCV-Face-Recognition:使用OpenCV和Python的实时人脸识别项目

5、用树莓派实现实时的人脸检测 | 树莓派实验室 (nxez.com)

环境已按照哔哩哔哩中教程配置完毕

捕获将由PiCam生成的视频流,并以BGR颜色和灰色模式显示两者

  1. import numpy as np
  2. import cv2
  3. cap = cv2.VideoCapture(0)
  4. cap.set(3,640) #设置宽
  5. cap.set(4,480) #设置高
  6. while(True):
  7. ret, frame = cap.read()
  8. frame = cv2.flip(frame, 1) #反转摄像头
  9. gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  10. cv2.imshow('frame', frame)#BGR模式
  11. cv2.imshow('gray', gray)#灰色窗口
  12. k = cv2.waitKey(30) & 0xff
  13. if k == 27: # 摁下ESC关闭窗口(ESC的ascll码为27)
  14. break
  15. cap.release()
  16. cv2.destroyAllWindows()

原作者摄像头是反的,将frame=cv2.flip(frame,-1)中的-1改为1

我尝试将灰色窗口改为其他颜色,都报错

这个段代码运行很顺利,没有报错

人脸检测

  1. import numpy as np
  2. import cv2
  3. faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')#加载分类器路径和文件
  4. cap = cv2.VideoCapture(0)
  5. cap.set(3,640) # set Width
  6. cap.set(4,480) # set Height
  7. while True:
  8. ret, img = cap.read()
  9. img = cv2.flip(img, 1)
  10. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  11. faces = faceCascade.detectMultiScale(
  12. gray,
  13. scaleFactor=1.2,#表示每次图像尺寸减小的比例
  14. minNeighbors=5, #表示一个目标至少要被检测5次才会被认定为人脸
  15. minSize=(20, 20), #目标最小尺寸
  16. )
  17. for (x,y,w,h) in faces:#如果检测到人脸返回方框
  18. cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)#更改此函数数据可改变方框的大小其实位置颜色
  19. roi_gray = gray[y:y+h, x:x+w]
  20. roi_color = img[y:y+h, x:x+w]
  21. cv2.imshow('video',img)
  22. k = cv2.waitKey(30) & 0xff
  23. if k == 27: # press 'ESC' to quit
  24. break
  25. cap.release()
  26. cv2.destroyAllWindows()

此处要注意调用了 Cascades/haarcascade_frontalface_default.xml文件,需要把该文件与源程序放在一个文件夹中(指定路径也可以)。该文件得到作者的GitHub中下载。

opencv的分类器GitHub地址:

opencv/data/haarcascades at master · opencv/opencv · GitHubhttps://github.com/opencv/opencv/tree/master/data/haarcascades

cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)更改此函数数据可改变方框的大小其实位置颜色

可以顺利运行,但我发现个有意思的事情--------------------------这个识别会将我的耳朵也识别成人脸

哈哈哈啊哈 

 发现运行人脸眼睛和嘴巴时,特别的慢,第一次得加载个两分钟的样子。

人脸识别

1、人脸采集

将GitHub中的haarcascade_frontalface_default.xml放在程序所在的文件夹

在本程序文件夹创建一个dataset文件夹,如果要创建其他名的文件夹,则需将文件中相应的文件名做出更改

  1. import cv2
  2. import os
  3. cam = cv2.VideoCapture(0)
  4. cam.set(3, 640) # set video width
  5. cam.set(4, 480) # set video height
  6. face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
  7. # 对于每个人,输入一个数字人脸 ID
  8. face_id = input('\n enter user id end press <return> ==> ')
  9. print("\n [INFO] Initializing face capture. Look the camera and wait ...")
  10. # 初始化单个采样面计数
  11. count = 0
  12. while(True):
  13. ret, img = cam.read()
  14. img = cv2.flip(img, 1) # flip video image vertically
  15. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  16. faces = face_detector.detectMultiScale(gray, 1.3, 5)
  17. for (x,y,w,h) in faces:
  18. cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)
  19. count += 1
  20. # 将捕获的图像保存到数据集文件夹中
  21. cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])#文件夹名在此处
  22. cv2.imshow('image', img)
  23. k = cv2.waitKey(100) & 0xff # 摁esc退出
  24. if k == 27:
  25. break
  26. elif count >= 30: # 取30张人脸样本并停止视频
  27. break
  28. # 做一些清理
  29. print("\n [INFO] Exiting Program and cleanup stuff")
  30. cam.release()
  31. cv2.destroyAllWindows()

输入只能为0,1,2,3,4,5分别对应5个人脸

运行后输入数字就可以看到dataset中有30张黑白人脸照片

2、训练opencv识别器

得安装确认 Rpi 上是否安装了 PIL 库。如果没有,请在终端中运行以下命令

pip install pillow

建立名为 trainer文件夹用来存放训练结果

  1. import cv2
  2. import numpy as np
  3. from PIL import Image
  4. import os
  5. # 人脸图像数据库的路径
  6. path = 'dataset'
  7. recognizer = cv2.face.LBPHFaceRecognizer_create()
  8. detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml");
  9. # 用于获取图像和标签数据的函数
  10. def getImagesAndLabels(path):
  11. imagePaths = [os.path.join(path,f) for f in os.listdir(path)]
  12. faceSamples=[]
  13. ids = []
  14. for imagePath in imagePaths:
  15. PIL_img = Image.open(imagePath).convert('L') # 将其转换为灰度
  16. img_numpy = np.array(PIL_img,'uint8')
  17. id = int(os.path.split(imagePath)[-1].split(".")[1])
  18. faces = detector.detectMultiScale(img_numpy)
  19. for (x,y,w,h) in faces:
  20. faceSamples.append(img_numpy[y:y+h,x:x+w])
  21. ids.append(id)
  22. return faceSamples,ids
  23. print ("\n [INFO] Training faces. It will take a few seconds. Wait ...")
  24. faces,ids = getImagesAndLabels(path)
  25. recognizer.train(faces, np.array(ids))
  26. # 将模型保存到 trainer/trainer.yml 中
  27. recognizer.write('trainer/trainer.yml') # recognizer.save函数在 Mac 上工作,但在 Pi 上不起作用
  28. # 打印经过训练的面孔数量并结束程序
  29. print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))

执行完人脸采样必须执行训练opencv识别器。

3、识别器

  1. import cv2
  2. import numpy as np
  3. import os
  4. recognizer = cv2.face.LBPHFaceRecognizer_create()
  5. recognizer.read('trainer/trainer.yml')
  6. cascadePath = "haarcascade_frontalface_default.xml"
  7. faceCascade = cv2.CascadeClassifier(cascadePath);
  8. font = cv2.FONT_HERSHEY_SIMPLEX
  9. #启动式 ID 计数器
  10. id = 0
  11. # id名称
  12. names = ['None', 'Marcelo', 'Paula', 'Ilza', 'Z', 'W']
  13. # 初始化并开始实时视频捕获
  14. cam = cv2.VideoCapture(0)
  15. cam.set(3, 640) # set video widht
  16. cam.set(4, 480) # set video height
  17. # 定义要识别为人脸的最小窗口大小
  18. minW = 0.1*cam.get(3)
  19. minH = 0.1*cam.get(4)
  20. while True:
  21. ret, img =cam.read()
  22. img = cv2.flip(img, 1)
  23. gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
  24. faces = faceCascade.detectMultiScale( #faces的值为人脸的坐标
  25. gray,
  26. scaleFactor = 1.2,
  27. minNeighbors = 5,
  28. minSize = (int(minW), int(minH)),
  29. )
  30. for(x,y,w,h) in faces:
  31. cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)#显示方框
  32. id, confidence = recognizer.predict(gray[y:y+h,x:x+w])#捕获人脸返回所在位置
  33. # 检查匹配度是否小于它们 ,100 ==>“0”的匹配度
  34. if (confidence < 100):
  35. id = names[id]
  36. confidence = " {0}%".format(round(100 - confidence))#显示百分比匹配度
  37. else:
  38. id = "unknown"#否则输出不认识
  39. confidence = " {0}%".format(round(100 - confidence))#显示百分比匹配度
  40. cv2.putText(img, str(id), (x+5,y-5), font, 1, (255,255,255), 2)#显示id名
  41. cv2.putText(img, str(confidence), (x+5,y+h-5), font, 1, (255,255,0), 1) #显示匹配度
  42. cv2.imshow('camera',img)
  43. k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video
  44. if k == 27:
  45. break
  46. # 做一些清理
  47. print("\n [INFO] Exiting Program and cleanup stuff")
  48. cam.release()
  49. cv2.destroyAllWindows()

id0对应的是None,id1对应的是marcelo以此内推,可以改变。

 识别度小于百分之0则会输出unknown。

修改为程序添加功能

将陌生人框为红色

程序稍微修改下,将不认识的人用红色方框框出。

  1. for(x,y,w,h) in faces:
  2. id, confidence = recognizer.predict(gray[y:y+h,x:x+w])
  3. # 检查匹配度是否小于它们 ,100 ==>“0”的匹配度
  4. if (confidence < 100):
  5. id = names[id]
  6. confidence = " {0}%".format(round(100 - confidence))#显示百分比匹配度
  7. cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)#显示绿色方框
  8. else:
  9. id = "unknown"#否则输出不认识
  10. confidence = " {0}%".format(round(100 - confidence))#显示百分比匹配度
  11. cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255), 2)#显示红色方框

实现终端输出人脸数量

思路:在循环开始时定义一个整型变量dex初值为0,只要检测到人dex就加1,一次循环一次就输出一次。

  1. import cv2
  2. import numpy as np
  3. import os
  4. recognizer = cv2.face.LBPHFaceRecognizer_create()
  5. recognizer.read('trainer/trainer.yml')
  6. cascadePath = "haarcascade_frontalface_default.xml"
  7. faceCascade = cv2.CascadeClassifier(cascadePath);
  8. font = cv2.FONT_HERSHEY_SIMPLEX
  9. # 启动式 ID 计数器
  10. id = 0
  11. # id名称
  12. names = ['None', 'LFM', 'LJ', 'Ilza', 'Z', 'W']
  13. # 初始化并开始实时视频捕获
  14. cam = cv2.VideoCapture(0)
  15. cam.set(3, 640) # set video widht
  16. cam.set(4, 480) # set video height
  17. # 定义要识别为人脸的最小窗口大小
  18. minW = 0.1 * cam.get(3)
  19. minH = 0.1 * cam.get(4)
  20. while True:
  21. dex1 = 0#定义熟人计数变量
  22. dex2 = 0#定义陌生人计数变量
  23. ret, img = cam.read()
  24. img = cv2.flip(img, 1)
  25. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  26. faces = faceCascade.detectMultiScale( # faces的值为人脸的坐标
  27. gray,
  28. scaleFactor=1.2,
  29. minNeighbors=5,
  30. minSize=(int(minW), int(minH)),
  31. )
  32. for (x, y, w, h) in faces:
  33. id, confidence = recognizer.predict(gray[y:y + h, x:x + w]) # 捕获人脸返回所在位置
  34. # 检查匹配度是否小于它们 ,100 ==>“0”的匹配度
  35. if (confidence < 100):
  36. id = names[id]
  37. confidence = " {0}%".format(round(100 - confidence)) # 显示百分比匹配度
  38. cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2) # 显示方框
  39. dex1 += 1#熟人加一
  40. else:
  41. dex2 += 1#陌生人加一
  42. id = "unknown" # 否则输出不认识
  43. confidence = " {0}%".format(round(100 - confidence)) # 显示百分比匹配度
  44. cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2) # 显示方框
  45. cv2.putText(img, str(id), (x + 5, y - 5), font, 1, (255, 255, 255), 2) # 显示id名
  46. cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (255, 255, 0), 1) # 显示匹配度
  47. cv2.imshow('camera', img)
  48. print("'熟人'{}个,'陌生人'{}个",format(dex1), format(dex2))#输出检测检测到的人脸个数
  49. k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video
  50. if k == 27:
  51. break
  52. # 做一些清理
  53. print("\n [INFO] Exiting Program and cleanup stuff")
  54. cam.release()
  55. cv2.destroyAllWindows()

运行了一下都正常,就是树莓派的那个软件里显示不了中文

 没毛病,也可以吧输出换成别的

将我的两个室友都会识别成我,不会显示unknown,准确度太低了,采集照片的多少也与人脸识别没啥太多关系,但可以通过调匹配度来控制人物的识别,但也没有太大的提升。

学习总结

树莓派的基本配置,了解了python程序的内部结构,函数库的安装,函数库的使用。在此次项目中遇到了各种大大小小的问题,还好网上都能找到解决方案。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/494979
推荐阅读
相关标签
  

闽ICP备14008679号