首页 > 解决方案 > 带有树莓派的人脸追踪器

问题描述

我已经按照本教程使用伺服电机进行面部跟踪网站: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 左

标签: pythonopencvraspberry-pi3opencv3.0face-detection

解决方案


不确定您是否发现了它,但是每次运行该函数时都将位置设置为 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

您应该将位置的初始化移到函数外部。

希望能帮助到你

提示如果您在发布问题时未能得到很多\任何回复,通常是因为答案正盯着您,您需要重新研究或检查您的代码。


推荐阅读