0

i have followed this tutorial for face tracking using servo motors website:https://embeditelectronics.com/blog/project/face-tracker/ github:https://github.com/embeditelectronics/Face-Tracker/blob/master/python-face-tracker/face.py but the thing is the hardware he used in the tutorial is different from the hardware i have used right now i'm using adafruit PCA9685 to connect my servos to my raspberry pi

i have tried changing the code according to my adafruit board using the github provided example

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()

here is the complete code

but the thing i'm stuck with this is, the pi-camera can detect my face but the servo motors are not functioned as expected and i don't understand the connection between the servo motors and the code part which detects my face i know somewhere there is a missing connection but im not sure where exactly the thing is and i'm not even sure if this the best way to do face tracking i have tried a lot other ways and ended up with many blunder errors if you have a better version of this code or any tutorial please do suggest me

*******updated****

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()

now the servo motors are moving but just a 0.5 right /0.5 left based on the face direction

john
  • 539
  • 2
  • 9
  • 24

1 Answers1

0

not sure if you spotted it yet but you are setting the position to 90 everytime the function is run so its never going to get past one step as its always reset to 90 when called again.

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

you should move the initialization of position to outside the function.

hope it helps

TIP If you fail to get many\any responses when you post issues its usually because the answer is staring at you and you need to either research or check your code again.