python - 带有树莓派的人脸追踪器
问题描述
我已经按照本教程使用伺服电机进行面部跟踪网站:https: //embeditelectronics.com/blog/project/face-tracker/github:https ://github.com/embeditelectronics/Face-Tracker/blob/master/python -face-tracker/face.py 但问题是他在教程中使用的硬件与我现在使用的硬件不同我正在使用 adafruit PCA9685 将我的伺服系统连接到我的树莓派
我尝试使用 github 提供的示例根据我的 adafruit 板更改代码
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
# from pisoc import *
import Adafruit_PCA9685
pwm = Adafruit_PCA9685.PCA9685()
position=90
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def Track(pan, tilt, center, target = Point(160, 120), threshold = Point(16, 24), delta = Point(4, 3)):
global position
position=90
if (center.x > target.x + threshold.x):
position=position-delta.x
pwm.set_pwm(0, 0,position)
# pan.SetAngle(pan.ReadAngle() - delta.x)
elif (center.x < target.x - threshold.x):
position=position+delta.x
pwm.set_pwm(0, 0,position)
# pan.SetAngle(pan.ReadAngle() + delta.x)
if (center.y > target.y + threshold.y):
position=position+delta.x
pwm.set_pwm(1, 0,position)
# tilt.SetAngle(tilt.ReadAngle() + delta.y)
elif (center.y < target.y - threshold.y):
position=position-delta.x
pwm.set_pwm(1, 0,position)
# tilt.SetAngle(tilt.ReadAngle() - delta.y)
if __name__ == "__main__":
# PiSoC(log_level = 'debug')
pan= pwm.set_pwm(0, 0,position)
tilt=pwm.set_pwm(1,0,position)
# pan = Servo(0, max_angle = 320)
# tilt = Servo(1, max_angle = 240)
camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size = camera.resolution)
face_cascade = cv2.CascadeClassifier('/home/pi/Downloads/lbpcascade_frontalface.xml')
scale = (camera.resolution[0]/320.0, camera.resolution[1]/240.0)
time.sleep(0.1)
# pan.Start()
# tilt.Start()
for frame in camera.capture_continuous(rawCapture, format = 'bgr', use_video_port = True):
image = frame.array
resized = cv2.resize(image, (320, 240))
gray = cv2.cvtColor(resized,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.1, 5)
if len(faces) > 0:
for (x, y, w, h) in faces:
Track(pan, tilt, Point(x + w/2.0, y+ h/2.0))
break
faces_resized = [(int(scale[0]*x), int(scale[1]*y), int(scale[0]*w), int(scale[1]*h)) for (x, y, w, h) in faces]
for (x,y,w,h) in faces_resized:
cv2.rectangle(image,(x,y),(x+w,y+h),(255,255,0),2)
cv2.imshow("Result", image)
key = cv2.waitKey(1) & 0xFF
rawCapture.truncate(0)
if key == ord('q') or key == 27:
break
# pan.Stop()
# tilt.Stop()
这是完整的代码
但我坚持的是,pi 相机可以检测到我的脸,但伺服电机没有按预期运行,我不明白伺服电机和检测我的脸的代码部分之间的连接我知道某处缺少连接,但我不确定事情到底在哪里,我什至不确定这是否是进行面部跟踪的最佳方法我尝试了很多其他方法,如果你有更好的方法,最终会出现许多错误此代码或任何教程的版本请建议我
*******更新****
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
# from pisoc import *
import Adafruit_PCA9685
pwm = Adafruit_PCA9685.PCA9685()
position=90
FRAME_W = 180
FRAME_H = 100
cam_pan = 90
cam_tilt = 60
pwm.set_pwm_freq(50)
pwm.set_pwm(0, 0,120)
pwm.set_pwm(1, 0,120)
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def Track(pan, tilt, center, target = Point(160, 120), threshold = Point(16, 24), delta = Point(4, 3)):
global position
position=90
if (center.x > target.x + threshold.x):
position=position-delta.x
pwm.set_pwm(0, 0,position)
# pan.SetAngle(pan.ReadAngle() - delta.x)
elif (center.x < target.x - threshold.x):
position=position+delta.x
pwm.set_pwm(0, 0,position)
# pan.SetAngle(pan.ReadAngle() + delta.x)
if (center.y > target.y + threshold.y):
position=position+delta.x
pwm.set_pwm(1, 0,position)
# tilt.SetAngle(tilt.ReadAngle() + delta.y)
elif (center.y < target.y - threshold.y):
position=position-delta.x
pwm.set_pwm(1, 0,position)
# tilt.SetAngle(tilt.ReadAngle() - delta.y)
if __name__ == "__main__":
# PiSoC(log_level = 'debug')
pan= pwm.set_pwm(0, 0,position)
tilt=pwm.set_pwm(1,0,position)
# pan = Servo(0, max_angle = 320)
# tilt = Servo(1, max_angle = 240)
camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size = camera.resolution)
face_cascade = cv2.CascadeClassifier('/home/pi/Downloads/lbpcascade_frontalface.xml')
scale = (camera.resolution[0]/320.0, camera.resolution[1]/240.0)
time.sleep(0.1)
# pan.Start()
# tilt.Start()
for frame in camera.capture_continuous(rawCapture, format = 'bgr', use_video_port = True):
image = frame.array
resized = cv2.resize(image, (320, 240))
gray = cv2.cvtColor(resized,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.1, 5)
if len(faces) > 0:
for (x, y, w, h) in faces:
Track(pan, tilt, Point(x + w/2.0, y+ h/2.0))
break
faces_resized = [(int(scale[0]*x), int(scale[1]*y), int(scale[0]*w), int(scale[1]*h)) for (x, y, w, h) in faces]
for (x,y,w,h) in faces_resized:
cv2.rectangle(image,(x,y),(x+w,y+h),(255,255,0),2)
cv2.imshow("Result", image)
key = cv2.waitKey(1) & 0xFF
rawCapture.truncate(0)
if key == ord('q') or key == 27:
break
# pan.Stop()
# tilt.Stop()
现在伺服电机正在移动,但根据面部方向仅移动 0.5 右/0.5 左
解决方案
不确定您是否发现了它,但是每次运行该函数时都将位置设置为 90,因此它永远不会超过一步,因为再次调用时它总是重置为 90。
def Track(pan,tilt, center, target = Point(160, 120), threshold = Point(16, 24), delta = Point(4, 3)): 全局位置 position=90 if (center.x > target. x + 阈值.x):
position=position-delta.x
您应该将位置的初始化移到函数外部。
希望能帮助到你
提示如果您在发布问题时未能得到很多\任何回复,通常是因为答案正盯着您,您需要重新研究或检查您的代码。
推荐阅读
- c - 在C中更改输入字符串的大小写的代码
- java - netbeans 8.2,Windows 10 上的 java 调试器错误
- reactjs - 使用 setstate 时,我可以使用如下所示的简单对象吗?
- .net - 如何告诉 .NET DLL 引用另一个 DLL 的不同版本?
- django - Django在模板中的相关模型调用上“无法解析余数”
- python - python errno 99/未知接口
- javascript - React setState 不会立即更新组件视图
- c - C程序读取一个女孩的姓名和婚姻状况,并打印她的名字与Miss或Mrs
- mongodb - 从反应客户端调用猫鼬
- python - SQLAlchemy - 使用与数据库和会话的连接(不清楚行为和文档的一部分)