OpenCV-Python перекрывает границуBoundingRect()

Я пытаюсь исправить ошибку, из-за которой при столкновении двух прямоугольников в видео они сливаются в один большой прямоугольник для оставшихся кадров, с которыми они сталкиваются, вместо того, чтобы сохранять прямоугольники, как раньше:

До столкновения:

После столкновения:

Я хочу сохранить оба прямоугольника даже при столкновении объектов.

Фрагмент основного цикла:

while True:
    ret, frame = vid.read()
    if frame is None:
        break

    # TRESH_OTSU has problems with objects that are very dark
    bright_frame = cv2.addWeighted(
        frame, 4.3, np.zeros(frame.shape, frame.dtype), 0, 20
    )

    # create a mask that will remove the black background from tracking
    gray = cv2.cvtColor(bright_frame, cv2.COLOR_BGR2GRAY)
    _, mask = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

    # get the moving objects
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    detections = []
    for obj in contours:
        area = cv2.contourArea(obj)
        if area > 50:  # filter noise
            perimeter = cv2.arcLength(obj, True)
            approx = cv2.approxPolyDP(obj, 0.02 * perimeter, True)
            object_type = "rectangle" if len(approx) == 4 else "circle"
            x, y, w, h = cv2.boundingRect(obj)
            detections.append(
                DetectedObject(
                    x, y, w, h, get_obj_color(frame, x, y, w, h), object_type
                )
            )

    rects = tracker.update(detections)
    for rect in rects:
        x, y, w, h, id, _, _, time = rect
        cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 255), 5)
        # cv2.putText(
        #     frame, str(id), (x, y - 15), cv2.FONT_HERSHEY_PLAIN, 5, (255, 255, 255)
        # )
        print(rect)
    cv2.imshow("frame", frame)

    key = cv2.waitKey(10)

    # break the loop upon the press of esc
    if key == 27:
        break

Где ваш код идет не так? Вы не сказали нам, в чем проблема с вашим кодом. Почему это не работает?

fmw42 08.05.2024 17:31

используйте cv2.inRange, чтобы отфильтровать каждый объект по отдельной маске и разместить там их ограничивающие рамки...

Tino D 08.05.2024 19:09

@fmw42 вместо разделения прямоугольников при столкновении создает один большой прямоугольник, как показано в описании, я этого не хочу

banan 08.05.2024 19:39

@TinoD это было бы очень неэффективно, не так ли?

banan 08.05.2024 19:46

@banan для твоих целей абсолютная разница во времени будет очень незаметна

Tino D 08.05.2024 19:47

@tinod, но мне нужно будет создать маску для каждого объекта? я не совсем понимаю, что ты пытаешься предложить

banan 08.05.2024 19:52

сколько объектов вы ожидаете? В этом случае, может быть, лучше вместо контуров использовать связанные элементы?

Tino D 08.05.2024 20:02

Давайте продолжим обсуждение в чате.

banan 08.05.2024 20:05
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
8
111
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот иллюстрация того, что я имею в виду. Я сделал небольшой пример, потому что вы не предоставили необработанное изображение:

Отдельно:

Столкновение:

Подход довольно прост:

  1. определять границы
  2. подать заявку cv2.inRange
  3. получить положительные пиксели и получить ограничивающий прямоугольник

Для разлученных:

Для столкновения:

Фрагмент кода:

# define boundary for first object
lower1 = (150,90,30)
upper1 = (170,110,60)
# define boundary for second object
lower2 = (150,150,150)
upper2 = (255,255,255)
# get bounding boxes
boundingRect1 = cv2.boundingRect(cv2.inRange(im,lower1,upper1))
boundingRect2 = cv2.boundingRect(cv2.inRange(im,lower2,upper2))
# draw rectangle on im
cv2.rectangle(im, boundingRect1, (255,0,0), 5)
cv2.rectangle(im, boundingRect2, (0,0,255), 5)

Я не уверен, сколько объектов у вас в конечном итоге будет, и я не уверен, что эти два объекта обязательно можно будет разделить по цвету. В конце концов посмотрите на подключенные компоненты, если у вас всегда чистый объект, как на фотографиях.

Другие вопросы по теме