@IvanTRG

Почему не корректно работает код?

В общем суть кода проста: определяется человек, далее задаются 8 различных зон и суть компа через ардуино зажечь светодиод. У меня получилось сделать чёткую работу, но код корректно работает только с одним человеком. Если более одного человека массив zones создается для каждого и светодиоды начинают моргать. Я попытался сделать combined_zones, это объединение двух массивов, однако это не дало ожидаемого результата. Может кто может помочь, чтобы код работал при нескольких людях
import cv2
import numpy as np
import pyfirmata  # Import pyFirmata
# Load the MobileNet SSD model
model = cv2.dnn.readNetFromCaffe('MobileNetSSD_deploy.prototxt.txt', 'MobileNetSSD_deploy.caffemodel')
board = pyfirmata.Arduino('COM6')# Windows
# объекты
classNames = {0: 'background', 1: 'aeroplane', 2: 'bicycle', 3: 'bird', 4: 'boat',
              5: 'bottle', 6: 'bus', 7: 'car', 8: 'cat', 9: 'chair', 10: 'cow',
              11: 'diningtable', 12: 'dog', 13: 'horse', 14: 'motorbike', 15: 'person',
              16: 'pottedplant', 17: 'sheep', 18: 'sofa', 19: 'train', 20: 'tvmonitor'}


cap = cv2.VideoCapture(0)
g = 0
g1 = 0

zone1_x_1, zone1_x_2, zone1_y_1,  zone1_y_2 = 0, 200, 0, 250
zone2_x_1, zone2_x_2, zone2_y_1, zone2_y_2 = 200, 360, 0, 250 # 1)начальный пиксель по x 2)начальный по y 3)
zone3_x_1, zone3_x_2, zone3_y_1, zone3_y_2 = 360, 540, 0, 250
zone4_x_1, zone4_x_2, zone4_y_1, zone4_y_2 = 540, 720, 0, 250
zone5_x_1, zone5_x_2, zone5_y_1, zone5_y_2 = 0, 200, 250, 500
zone6_x_1, zone6_x_2, zone6_y_1, zone6_y_2 = 200, 360, 250, 500
zone7_x_1, zone7_x_2, zone7_y_1, zone7_y_2 = 360, 540, 250, 500
zone8_x_1, zone8_x_2, zone8_y_1, zone8_y_2 = 540, 720, 250, 500
zones = [
    (0, 200, 0, 250),
    (200, 360, 0, 250),
    (360, 540, 0, 250),
    (540, 720, 0, 250),
    (0, 200, 250, 500),
    (200, 360, 250, 500),
    (360, 540, 250, 500),
    (540, 720, 250, 500)
]


while True:
    # считывание
    ret, frame = cap.read()
    img2 = cv2.flip(frame, 1)

    frame_re = img2[0:1000, 0:1080]

    # размеры
    frame_resized = cv2.resize(frame_re, (300, 300))

    # Convert the frame to a binary large object file
    blob = cv2.dnn.blobFromImage(frame_resized, 0.007843, (300, 300), (127.5, 127.5, 127.5), False)

    # старат распознавания
    model.setInput(blob)
    detections = model.forward()

    for i in range(detections.shape[2]):
        confidence = detections[0, 0, i, 2]
        if confidence > 0.5:
            class_id = int(detections[0, 0, i, 1])
            class_name = classNames[class_id]
            box = detections[0, 0, i, 3:7] * np.array([frame_re.shape[1], frame_re.shape[0], frame_re.shape[1], frame_re.shape[0]])
            x1, y1, x2, y2 = box.astype('int')
            cv2.rectangle(frame_re, (zone1_x_1, zone1_y_1), (zone1_x_2, zone1_y_2), (255, 0, 0), 1)
            cv2.rectangle(frame_re, (zone2_x_1, zone2_y_1), (zone2_x_2, zone2_y_2), (255, 0, 0), 1)
            cv2.rectangle(frame_re, (zone3_x_1, zone3_y_1), (zone3_x_2, zone3_y_2), (255, 0, 0), 1)
            cv2.rectangle(frame_re, (zone4_x_1, zone4_y_1), (zone4_x_2, zone4_y_2), (255, 0, 0), 1)
            cv2.rectangle(frame_re, (zone5_x_1, zone5_y_1), (zone5_x_2, zone5_y_2), (255, 0, 0), 1)
            cv2.rectangle(frame_re, (zone6_x_1, zone6_y_1), (zone6_x_2, zone6_y_2), (255, 0, 0), 1)
            cv2.rectangle(frame_re, (zone7_x_1, zone7_y_1), (zone7_x_2, zone7_y_2), (255, 0, 0), 1)
            cv2.rectangle(frame_re, (zone8_x_1, zone8_y_1), (zone8_x_2, zone8_y_2), (255, 0, 0), 1)
            if class_name=='person':
                cv2.rectangle(frame_re, (x1, y1), (x2, y2), (0, 0, 255), 2)
                cv2.putText(frame_re, class_name, (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

                
  
                def check_zones(x1, x2, y1, y2): 
                    in_zones = [] 
                    for i, zone in enumerate(zones): 
                        zone_x1, zone_x2, zone_y1, zone_y2 = zone 
                        if (x1 <= zone_x2 and x2 >= zone_x1 and y1 <= zone_y2 and y2 >= zone_y1): 
                            in_zones.append(i + 1) 
                    if in_zones: 
                        return in_zones
                    return zones
                
                
                # Получение номеров зон, в которых находится объект
                in_zones = check_zones(x1, x2, y1, y2)
                
                if len(in_zones) > 1:
                    # соединяем массивы
                    combined_zones = in_zones[0] + in_zones[1]
                else:
                    combined_zones = in_zones
                print(combined_zones) 
                
                for i in range(len(zones)):
                    pin = i + 2  # Номер пина соответствует номеру зоны + 1
                    if i+1 in in_zones:
                        # Если объект находится в зоне, зажигаем светодиод
                        board.digital[pin].write(1)
                    else:
                        pin = i + 2
                        # Если объект не находится в зоне, гасим светодиод
                        board.digital[pin].write(0)
            #else:
                #for i in [2, 3, 4, 5, 6, 7, 8, 9]:
                    #board.digital[i].write(0)  # Гасим светодиод на соответствующем пине

                #print("Номера зон:", in_zones)

        #print(x1, y1)
        cv2.imshow('Object Detection', frame_re)

    # завершение цикла
    if cv2.waitKey(1) & 0xFF == ord('q'):
        board.digital[2].write(0)
        board.digital[3].write(0)
        board.digital[4].write(0)
        board.digital[5].write(0)
        board.digital[6].write(0)
        board.digital[7].write(0)
        board.digital[8].write(0)
        board.digital[9].write(0)
        break

# выключение
cap.release()
cv2.destroyAllWindows()
  • Вопрос задан
  • 841 просмотр
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
for i in range(len(zones)):
                    pin = i + 2  # Номер пина соответствует номеру зоны + 1
                    if i+1 in in_zones:
                        # Если объект находится в зоне, зажигаем светодиод
                        board.digital[pin].write(1)
                    else:
                        pin = i + 2
                        # Если объект не находится в зоне, гасим светодиод  <--- НАПРАСНО
                        board.digital[pin].write(0)

Косяк вот тут. Если текущий объект не находится в зоне, это не значит что никакой другой, ранее найденный объект не находится в этой зоне.
Сделай массив bool по числу зон, в начале итерации выставь все элементы в false. По ходу итерации выставляй элемент в true если в зоне найден человек.
В конце итерации выставляй светодиоды по элементам массива.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы