8370浏览
查看: 8370|回复: 5

[教程] 树莓派+mediapipe+pid 摄像头人脸跟随

[复制链接]
本帖最后由 云天 于 2022-2-5 12:47 编辑

IMG_20220204_215036.jpg
本教程中使用了“树莓派4b”+“树莓派两自由度云台”+“mediapipe”+“pid”,实现摄像头人脸跟随。
【树莓派】
4代B型4GB Raspberry Pi

树莓派最新发布的第四代产品 Raspberry Pi 4 B, 性能与树莓派 3B+相比无论是处理器速度,还是多媒体和内存上都有显著提升。Raspberry Pi 4 B拥有与入门级 x86 PC 系统相媲美的桌面性能,给您带来高品质体验。

Raspberry Pi 4 B 具备1.5Ghz运行的64位四核处理器,最高支持以60fps 速度刷新的4K分辨率的双显示屏,高达4GB RAM(可根据型号选择1GB、2GB、4GB),2.4/5.0 Ghz 双频无线LAN,蓝牙5.0/BLE,千兆以太网,USB3.0,和PoE功能。


【树莓派两自由度云台】

这是一款专为树莓派设计的两自由度云台扩展板,基于树莓派40PIN GPIO接口设计,直接插入树莓派GPIO口即可使用,同时也将树莓派GPIO口插针引出,不影响树莓派GPIO口的使用。模块采用I2C接口控制,仅需2根信号线即可实现云台转动和光强检测,板载PCA9685芯片,可输出12位分辨率的PWM控制云台转动;板载TSL25911FN,内置ADC,能够得到近似人眼对光的反应,辅助模块工作;板载电平转换电路,兼容3.3V/5V的工作电平;配套专用亚克力板用以固定树莓派摄像头,将摄像头搭配在云台上,拍摄时更方便。
FriFebruary-202202049280..png


IMG_20220204_214540.jpg
【mediapipe】
MediaPipe 是一款由 Google Research 开发并开源的多媒体机器学习模型应用框架。在谷歌,一系列重要产品,如 、Google Lens、ARCore、Google Home 以及 ,都已深度整合了 MediaPipe。
FriFebruary-202202044867..png

【安装配置】
1、配置云台
参考:https://wiki.dfrobot.com.cn/FIT0731%20%20%E6%A0%91%E8%8E%93%E6%B4%BE%E4%B8%A4%E8%87%AA%E7%94%B1%E5%BA%A6%E4%BA%91%E5%8F%B0
安装BCM2835库时,将“wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.68.tar.gz”中修改为:http://www.airspayce.com/mikem/bcm2835/bcm2835-1.71.tar.gz
2、安装mediapipe库
在终端中使用:pip3 install mediapipe-rpi4
QQ截图20220204123922.png

【测试云台程序】
  1. #!/usr/bin/python
  2. import time
  3. import RPi.GPIO as GPIO
  4. from PCA9685 import PCA9685
  5. pwm = PCA9685()
  6. try:
  7.     print ("This is an PCA9685 routine")   
  8.     pwm.setPWMFreq(50)
  9.     #pwm.setServoPulse(1,500)
  10.     #pwm.setRotationAngle(1, 130)
  11.    
  12.    
  13.     # setServoPulse(2,2500)
  14.         
  15.     pwm.setRotationAngle(0, 60)   
  16.             
  17. except:
  18.     pwm.exit_PCA9685()
  19.     print ("\nProgram end")
  20.     exit()
复制代码
IMG_20220204_215052.jpg
【测试mediapipe】

  1. import cv2
  2. import time
  3. import mediapipe as mp
  4. mp_face_detection = mp.solutions.face_detection
  5. mp_drawing = mp.solutions.drawing_utils
  6. pTime = 0
  7. cTime = 0
  8. # For webcam input:
  9. cap = cv2.VideoCapture(0)
  10. with mp_face_detection.FaceDetection(
  11.     model_selection=0, min_detection_confidence=0.8) as face_detection:
  12.   while cap.isOpened():
  13.     success, image = cap.read()
  14.     box=[]
  15.    
  16.     if not success:
  17.       print("Ignoring empty camera frame.")
  18.       # If loading a video, use 'break' instead of 'continue'.
  19.       continue
  20.     # To improve performance, optionally mark the image as not writeable to
  21.     # pass by reference.
  22.     h,w,c=image.shape
  23.     image.flags.writeable = False
  24.     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  25.     results = face_detection.process(image)
  26.     # Draw the face detection annotations on the image.
  27.     image.flags.writeable = True
  28.     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
  29.     if results.detections:
  30.       for detection in results.detections:
  31.         #mp_drawing.draw_detection(image, detection)
  32.         print(detection.location_data.relative_bounding_box)
  33.         box=detection.location_data.relative_bounding_box
  34.         #cx,cy,cw,ch=box
  35.         cx=box.xmin
  36.         cy=box.ymin
  37.         cw=box.width
  38.         ch=box.height
  39.         cv2.rectangle(image, (int(cx*w) , int(cy*h) ), (int((cx+cw)*w) , int((cy+ch)*h)),(0, 255, 0), 2)
  40.     # Flip the image horizontally for a selfie-view display.
  41.     cTime = time.time()
  42.     fps = 1 / (cTime - pTime)
  43.     pTime = cTime
  44.     cv2.putText(image, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3,(255, 0, 255), 3)
  45.     cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1))
  46.     if cv2.waitKey(5) & 0xFF == 27:
  47.       break
  48. cap.release()
复制代码
IMG_20220204_221335.jpg

【完整程序】
  1. #!/usr/bin/python
  2. import time
  3. import RPi.GPIO as GPIO
  4. from PCA9685 import PCA9685
  5. import cv2
  6. import numpy as np
  7. import mediapipe as mp
  8. mp_face_detection = mp.solutions.face_detection
  9. mp_drawing = mp.solutions.drawing_utils
  10. pTime = 0
  11. cTime = 0
  12. # For webcam input:
  13. cap = cv2.VideoCapture(0)
  14. pwm = PCA9685()
  15. pwm.setPWMFreq(50)
  16. pwm.setRotationAngle(1, 110)
  17. pwm.setRotationAngle(0, 90)   
  18.             
  19. kp=0.01
  20. kd=0.01
  21. kp_y=0.02
  22. kd_y=0.01
  23. pre_x=90
  24. pre_y=110  #定义舵机初始角度
  25. pre_err_x=0
  26. pre_err_y=0
  27. with mp_face_detection.FaceDetection(
  28.     model_selection=0, min_detection_confidence=0.65) as face_detection:
  29.   while cap.isOpened():
  30.     success, image = cap.read()
  31.     #image=cv2.resize(image, None, fx=0.5, fy=0.5)
  32.     box=[]
  33.    
  34.     if not success:
  35.       print("Ignoring empty camera frame.")
  36.       # If loading a video, use 'break' instead of 'continue'.
  37.       continue
  38.     # To improve performance, optionally mark the image as not writeable to
  39.     # pass by reference.
  40.     h,w,c=image.shape
  41.     image.flags.writeable = False
  42.     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  43.     results = face_detection.process(image)
  44.     # Draw the face detection annotations on the image.
  45.     image.flags.writeable = True
  46.     image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
  47.     if results.detections:
  48.       for detection in results.detections:
  49.         #mp_drawing.draw_detection(image, detection)
  50.         print(detection.location_data.relative_bounding_box)
  51.         box=detection.location_data.relative_bounding_box
  52.         #cx,cy,cw,ch=box
  53.         cx=box.xmin
  54.         cy=box.ymin
  55.         cw=box.width
  56.         ch=box.height
  57.         cv2.circle(image, (int(cx*w), int(cy*h)), 5, (255, 0, 255), cv2.FILLED)
  58.         cv2.rectangle(image, (int(cx*w) , int(cy*h) ), (int((cx+cw)*w) , int((cy+ch)*h)),(0, 255, 0), 2)
  59.         
  60.         err_x=(w/2-cx*w)
  61.         err_y=(cy*h+ch*h-h/2)
  62.         dis_err_x=err_x-pre_err_x
  63.         dis_err_y=err_y-pre_err_y
  64.         
  65.         
  66.   
  67.         pre_x=(pre_x+kp*err_x+kd*dis_err_x)
  68.         pre_y=(pre_y+kp_y*err_y+kd_y*dis_err_y)
  69.         pre_err_x=err_x
  70.         pre_err_y=err_y
  71.         print(h,"  ",pre_y," ",int(cy*h),"  ",err_y,"  ")
  72.             #防止超调
  73.         if pre_x<0:
  74.                pre_x=0
  75.         elif pre_x>180:
  76.                pre_x=180
  77.                
  78.         if pre_y<90:
  79.                pre_y=90
  80.         elif pre_y>130:
  81.                pre_y=130
  82.         pwm.setRotationAngle(0, pre_x)
  83.         pwm.setRotationAngle(1, pre_y)
  84.            
  85.         
  86.     # Flip the image horizontally for a selfie-view display.
  87.     cTime = time.time()
  88.     fps = 1 / (cTime - pTime)
  89.     pTime = cTime
  90.     cv2.putText(image, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3,(255, 0, 255), 3)
  91.     cv2.imshow('MediaPipe Face Detection', cv2.flip(image, 1))
  92.     if cv2.waitKey(5) & 0xFF == 27:
  93.       pwm.exit_PCA9685()
  94.       break
  95. cap.release()
复制代码

IMG_20220204_215121.jpg



【演示视频】


hnyzcj  版主

发表于 2022-2-5 20:39:53

回复

使用道具 举报

rzegkly  版主

发表于 2022-2-6 11:01:01

喜欢
回复

使用道具 举报

微笑的rockets  NPC

发表于 2022-2-7 15:21:05

很不错的项目
回复

使用道具 举报

只会喊666的咸鱼  学徒

发表于 2022-5-27 16:06:08

需要用智能摄像头吗?还是随便什么摄像头都可以?
回复

使用道具 举报

云天  高级技匠
 楼主|

发表于 2022-5-29 07:52:31

只会喊666的咸鱼 发表于 2022-5-27 16:06
需要用智能摄像头吗?还是随便什么摄像头都可以?

普通USB摄像头,就可以
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2022 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail