Я следовал этому руководству по слежению за лицом с помощью серводвигателей.
сайт: https://embeditelectronics.com/blog/project/face-tracker/
GitHub: https://github.com/embeditelectronics/Face-Tracker/blob/master/python-face-tracker/face.py
но дело в том, что оборудование, которое он использовал в учебнике, отличается от оборудования, которое я использовал
сейчас я использую adafruit PCA9685 для подключения моих сервоприводов к моей Raspberry Pi
Я попытался изменить код в соответствии с моей доской Adafruit, используя пример, предоставленный GitHub
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()
вот полный код
но я застрял в том, что пи-камера распознает мое лицо, но серводвигатели не работают должным образом
и я не понимаю связи между серводвигателями и частью кода, которая определяет мое лицо. Я знаю, что где-то отсутствует соединение, но я не уверен, где именно
и я даже не уверен, что это лучший способ для отслеживания лица, я перепробовал много других способов и в итоге получил много ошибок
если у вас есть лучшая версия этого кода или любой учебник, пожалуйста, предложите мне
******* обновленный ****
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 влево в зависимости от направления лица