Как мне отправить команду, когда x и y находятся в центре во время отслеживания лица?

#python

#python

Вопрос:

Пожалуйста, простите мой ужасный код, для меня это просто хобби. Но я пытаюсь заставить python воспроизводить звук, когда оси отслеживания лиц x и y находятся в определенной центральной точке. Прямо сейчас я тестирую воспроизведение звука, как только звук заиграет, я могу заменить воспроизведение звука отправкой данных в arduino, чтобы запустить бесщеточный двигатель для минигана orbeez. Остальная часть кода работает, но я не могу заставить звук воспроизводиться. Звук БУДЕТ воспроизводиться, если я назову его по-другому.

Вот фрагмент кода

Кроме того, я перепробовал много разных способов ‘if (xcenter ycenter) == 2:’, это всего лишь последний из опробованных.

 # This will send data to the arduino according to the x coordinate
def angle_servox(angle):

    if angle>320:
        prov=1
        ser.write(b'2')
        print("Right")
        xcenter = 0

    elif angle<250:
        prov=2
        ser.write(b'1')
        print("Left")
        xcenter = 0

    elif angle>250 amp; angle<320:
        ser.write(b'0')
        print("Stop")
        xcenter = 1

# This will send data to the arduino according to the x coordinate
def angle_servoy(angle):

    if angle>250:
        prov=3
        ser.write(b'4')
        print("Down")
        ycenter = 0

    elif angle<75:
        prov=4
        ser.write(b'3')
        print("Up")
        ycenter = 0

    elif angle>80 amp; angle<240:
        ser.write(b'5')
        print("Stop")
        ycenter = 1

# import the haarcascade file
face_casc = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

#train the face for recognition
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("recognizers/face-trainer.yml.txt")

labels = {"person_name": 1}
with open("pickles/face-labels.pickle", 'rb') as f:
    og_labels = pickle.load(f)
    labels = {v:k for k,v in og_labels.items()}

# for default camera put value 0 or else 1
videoWeb = cv2.VideoCapture(1)
n=0


while (videoWeb.isOpened()):
    print(ser.read().decode().strip('rn'))
    ret,imag = videoWeb.read()
    gray = cv2.cvtColor(imag, cv2.COLOR_BGR2GRAY)
    #cv2.imshow('xyz',imag)
    faces = face_casc.detectMultiScale(
        gray,
        scaleFactor=1.4,
        minNeighbors=5,
        minSize=(30,30)
        )
    if (xcenter   ycenter) == 2:
        voice.play(active2)
  

Заранее спасибо

Ответ №1:

Насколько я могу судить, вы неправильно запрашиваете информацию, которую вы получаете от cv2 face detection (кроме того, вы, вероятно, могли бы удалить две angle_servo() функции для этого вопроса).

На высоком уровне вы хотите, чтобы ваш скрипт:

  1. Настройте поток с камеры
  2. Непрерывно получать изображения с камеры и находить лица
  3. Если в «середине» есть лицо, воспроизведите свой звук

Я никогда не использовал OpenCV, но на основе некоторого примера кода, который я нашел здесь, пересмотр вашего скрипта может быть:

 # Setup our face detection
face_casc = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("recognizers/face-trainer.yml.txt")

# Setup our video input
videoWeb = cv2.VideoCapture(1)

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def is_close_to(self, other_pt, error=5):
        x_is_close = abs(self.x - other_pt.x) <= error
        y_is_close = abs(self.y - other_pt.y) <= error

        return x_is_close and y_is_close

# If an image from the video camera looks like this:
#
#     x-->
#     ------------- 
#  y |  A          |    A is at (10, 20)
#  | |             |
#  v |             |
#    |          B  |    B is at (300, 500)
#     ------------- 
#
# Our predetermined references points
A = Point(10, 20)
B = Point(300, 500)

# Continuously get images from the camera
while (videoWeb.isOpened()):
    # and try to find faces in them
    ret,imag = videoWeb.read()
    gray = cv2.cvtColor(imag, cv2.COLOR_BGR2GRAY)
    faces = face_casc.detectMultiScale(
        gray,
        scaleFactor=1.4,
        minNeighbors=5,
        minSize=(30,30)
        )

    # I'm just guessing here, I have no idea if "size" is a property or not
    middle_of_imag = Point(imag.size.x/2, imag.size.y/2)

    # check the location of every face we found
    for (x,y,w,h) in faces:
        face_pt = Point(x, y)

        #NB: it might be better to get the "middle" of the face
        #face_pt = Point(x   w/2, y   h/2)

        if face_pt.is_close_to(A):
            print("face at point A")
        if face_pt.is_close_to(B):
            print("face at point B")
        if face_pt.is_close_to(middle_of_imag):
            print("face somewhat in the middle")

        # if x in faces is between 250 amp; 320 AND y in faces is between 80 amp; 240: send 'fire'"
        if (250 <= x <= 320) and (80 <= y <= 240):
            print("send fire")
  

Комментарии:

1. Хотя это работает, оно должно работать в определенном диапазоне. Вместо значения servo_x, установленного на 123, это должны быть все числа <123 и <250, например.

2. К сожалению, я не думаю, что здесь есть место для решения всей вашей проблемы, и, кроме того, это лишило бы вас отличного ощущения, которое вы получите, как только решите ее 😉

3. Да, я потратил, я даже не знаю, сколько часов, на поиск и пробование разных вещей, чтобы решить эту проблему. Я просто собираюсь отказаться от этого проекта на Python и пойти в другом направлении.

4. Хм, вам повезло, не беспокоясь о положении сервопривода? Например. есть 2 разных звука, которые воспроизводятся, если есть лицо в любом из двух мест? Я внесу правку, чтобы показать, что я имею в виду

5. Положение сервопривода действительно не имеет значения. ‘def angle_servo(угол)’ просто считывает положение лица на экране и отправляет команду (b’5′) в arduino. Комментарий «Влево / вправо / вверх / вниз» напечатан только для целей калибровки. Основная часть кода, которая имеет значение в данном случае, — это elif angle>250 amp; angle<320: ser.write(b’0′) print(«Стоп») и elif angle>80 amp; angle<240: ser.write(b’5′) print(«Стоп»)