树莓派面部追踪器

时间:2019-06-30 16:57:08

标签: python opencv raspberry-pi3 opencv3.0 face-detection

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

1 个答案:

答案 0 :(得分:0)

不确定是否已经发现它,但是每次运行该函数时都将位置设置为90,因此它永远不会越过一步,因为再次调用时它总是重置为90。

def轨迹(水平,倾斜,中心,目标=点(160,120),阈值=点(16、24),增量=点(4、3)):     全球地位     位置= 90     如果(center.x> target.x + threshold.x):

    position=position-delta.x

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

希望有帮助

提示如果您在发布问题时未能获得很多答复,通常是因为答案盯着您,您需要研究或再次检查代码。