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

Функция Gif обнаружения движущихся объектов с помощью OpenCV
обнаружение движущихся объектов с помощью opencv – LearnOpenCV

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

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

Что такое обнаружение движущихся объектов?

Обнаружение движущихся объектов в компьютерном зрении включает в себя локализацию динамических объектов в видеопоследовательностях. Он продвинулся от базового различения кадров и вычитания фона со статическими камерами к сложным моделям глубокого обучения, способным обрабатывать динамические сцены с движущимися камерами. Классические методы компьютерного зрения, такие как модели гауссовой смеси, изначально использовались для статического фонового моделирования. При обнаружении объектов обычно использовались такие методы, как сопоставление с шаблоном, каскад Хаара, обнаружение объектов и сопоставление с помощью SIFT или SURF, детектор HOG и модель на основе деформируемых деталей (DPM) — появление методов, основанных на оптическом потоке, позволило обнаруживать по относительному движению камеры.

gif для обнаружения движущихся объектов
Обнаружение движущихся объектов

Интеграция глубокого обучения, в частности сверточных нейронных сетей (CNN), сыграла ключевую роль в обнаружении движущихся объектов, повысив точность и обеспечив обработку данных в режиме реального времени с помощью таких систем, как YOLO и SSD. Трансформеры усовершенствовали эту область, преуспев в обработке сложных сцен за счет захвата зависимостей на большом расстоянии.

В нашем конкретном сценарии мы будем использовать OpenCV для обнаружения движущихся объектов из стабильного положения камеры без методов глубокого обучения.

Наш подход к обнаружению движущихся объектов

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

блок-схема для обнаружения движущихся объектов
РИСУНОК 1 – Блок-схема конвейера обнаружения объектов

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

Что такое вычитание фона?

Первым шагом обнаружения движущихся объектов является вычитание фона. Использование статической камеры — распространенный и широко используемый метод для создания маски переднего плана (а именно двоичного изображения, содержащего пиксели, принадлежащие движущимся объектам в сцене).

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

Вычитание фона изображения в OpenCV
Вычитание фона в OpenCV

Фоновое моделирование состоит из двух основных этапов:

  1. Фоновая инициализация.

  2. Фоновое обновление.

На первом этапе вычисляется исходная модель фона, в то время как на втором этапе модель обновляется, чтобы адаптироваться к возможным изменениям в сцене. Оценка фона также может применяться к приложениям для отслеживания движения, таким как анализ трафика, обнаружение людей и т. д. Эта статья о оценке фона для отслеживания движения, несомненно, поможет вам лучше понять.

Обнаружение контуров в OpenCV

Контуры можно объяснить просто как кривую, соединяющую все непрерывные точки (вдоль границы), имеющие одинаковый цвет или интенсивность. Контуры полезны для анализа формы, обнаружения объектов и распознавания. OpenCV позволяет легко находить и рисовать контуры на изображениях.

Он предоставляет две простые функции: findContours() и drawContours()

Кроме того, в нем есть два разных алгоритма для определения контуров: CHAIN_APPROX_SIMPLE и CHAIN_APPROX_NONE

Обнаружение контуров при обнаружении движущихся объектов с помощью opencv
Обнаружение контуров OpenCV

Чтобы узнать больше о контурах, вы можете прочитать подробную статью о обнаружении контуров в OpenCV.

Настройка среды

Прежде чем перейти к коду обнаружения движущихся объектов, мы должны настроить нашу среду. Итак, у вас должен быть Python и предпочитаемая IDE на вашем компьютере, и все. Вы готовы к работе!

Необходимое программное обеспечение и библиотеки

Как мы обсуждали ранее, нам нужно установить только OpenCV в качестве основного драйвера кода, и мы установим Gradio для создания веб‑приложения на его основе, поскольку мы всегда верим в практические и реальные подходы.

Установка OpenCV и Gradio

Нам необходимо установить эти библиотеки в нашу среду Python. Мы предлагаем вам создать виртуальную среду и установить все зависимости для лучшего контроля версий.

! pip install opencv-python gradio

Импорт всех библиотек

import cv2
import gradio as gr
import numpy as np
import matplotlib.pyplot as plt

Мы импортируем все библиотеки, а затем переходим к основному коду.

Реализация вычитания фона

cap = cv2.VideoCapture(vid_path)
backSub = cv2.createBackgroundSubtractorMOG2()
if not cap.isOpened():
    print("Error opening video file")
    while cap.isOpened():
        # Захват кадр за кадром
          ret, frame = cap.read()
          if ret:
            # Вычитание фона
            fg_mask = backSub.apply(frame)

Сначала нам нужно захватить все видеокадры и передать их в конвейер кода. Следовательно, мы создали объект видеозахвата с помощью cv2.VideoCapture. Для вычитания фона мы создали другой объект, используя cv2.createBackgroundSubtractorMOG2. Далее мы проверяем, правильно ли работает наша шапка объекта или нет. После этого мы начнем захватывать все видеокадры один за другим, используя метод cap.read() . Теперь мы применим вычитание фона к каждому видеокадру, используя метод backSub.apply().

Вычитание фона для обнаружения движущихся объектов в видео
РИСУНОК 2 – Вычитание фона с помощью OpenCV

Как мы можем видеть, обнаруживаются все движущиеся пиксели между двумя последовательными кадрами. Сюда входят автомобили, тени и некоторые крошечные белые точки. Вы задавались вопросом, почему также присутствуют эти крошечные белые точки? В этих местах ничего не движется, верно!

При работе с реальными сценариями различные факторы окружающей среды могут повлиять на видеозапись с камер видеонаблюдения. Это могут быть погодные условия, такие как сильный ветер.

Обнаружение и рисование контуров

# Поиск контура
contours, hierarchy = cv2.findContours(fg_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# print(contours)
frame_ct = cv2.drawContours(frame, contours, -1, (0, 255, 0), 2)
# показать итоговый кадр
cv2.imshow('Frame_final', frame_ct)

После вычитания фона у нас теперь есть четкая двоичная маска нашей ROI (области интереса). Итак, мы перейдем к обнаружению контура. Приведенный выше блок кода описывает процесс.

Для этого мы должны передать маску переднего плана (fg_mask) в качестве входных данных в cv2.findContours функции, чтобы найти все возможные точки контура. Это произойдет для всех обнаруженных объектов в текущем кадре. После этого мы передадим все точки контура в cv2.drawContours функцию для рисования контуров для каждого обнаруженного контура.

обнаружение контура приводит к обнаружению движущегося объекта opencv
РИСУНОК 3 – Обнаружение контуров с помощью OpenCV

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

Улучшение обнаружения контуров с помощью порогового значения изображения и морфологических операций

Зашумленные контуры появляются из-за движения теней и камеры. Мы должны убрать все шумы, чтобы получить четкий кадр с обнаруженным контуром нашего ROI (автомобиля).

Для решения проблемы мы выполняем 3 разных шага. Это:

  • Пороговое значение

  • Эрозия и расширение

  • Контурная фильтрация

Пороговое значение

# устанавливаем глобальный порог для удаления теней
 retval, mask_thresh = cv2.threshold( fg_mask, 180, 255, cv2.THRESH_BINARY)

Для определения порога мы будем использовать функцию cv2.threshold и передавать все маски переднего плана в качестве входных данных. Мы устанавливаем пороговое значение на 180 и максимальное значение на 255, и это просто заменит все значения ниже 180 на 0 и удалит все тени. И вы можете увидеть результат, который мы получили после операции определения порога.

Установление порогового значения в opencv для обнаружения движущихся объектов
РИСУНОК 4 – Пороговое значение в OpenCV

Эрозия и расширение

После применения порогового значения теперь у нас есть маска бинарного изображения. Она состоит из маски автомобилей переднего плана без каких‑либо теней. Тем не менее, маленькие белые точки остаются в маске. Следующим шагом будет удаление контуров вокруг этих маленьких точек.

# вычисление ядра
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
# Apply erosion
mask_eroded = cv2.morphologyEx(mask_thresh, cv2.MORPH_OPEN, kernel)

Теперь, чтобы удалить эти маленькие белые точки, мы применим эрозию, а затем расширим изображение для получения лучшей и более широкой маски. Для этого мы будем использовать cv2.morphologyEx и use cv2.MORPH_OPEN в качестве MorphType и передадим в него маску с пороговым значением mask_thresh. Давайте проверим результаты после двух вышеуказанных операций.

эрозия и расширение при обнаружении движущихся объектов
РИСУНОК 5 – Эрозия и расширение в OpenCV

Теперь мы получили гораздо более чистое изображение. Остальную очистку можно выполнить, просто отфильтровав контуры небольшими участками.

Фильтрация контуров

min_contour_area = 500  # Define your minimum area threshold
large_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > min_contour_area]

Фильтрация контуров иногда может быть методом проб и ошибок. Мы обнаружили, что для нашего варианта использования лучше всего подходит контур площадью 500. Следующий блок кода будет отфильтровывать любые контуры размером менее 500 пикселей. Этот подход позволяет сохранить наиболее заметные автомобили, при этом отфильтровывая линию полосы движения.

Фильтрация контуров при обнаружении движущихся объектов
РИСУНОК 6 – Фильтрация контуров с помощью OpenCV

Окончательный результат вы можете увидеть здесь, теперь у нас есть гораздо лучшие методы обнаружения.

Нарисуйте ограничивающие рамки

frame_out = frame.copy()
for cnt in large_contours:
    x, y, w, h = cv2.boundingRect(cnt)
    frame_out = cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 200), 3)
 
# отображаем результат
cv2.imshow('Frame_final', frame_out)

Следующим этапом обнаружения движущихся объектов является рисование ограничивающих рамок вокруг оставшихся контуров. Именно здесь происходит обнаружение объектов. Для этого сначала мы извлекаем все координаты прямоугольника с помощью cv2.boundingRect функции. Затем мы нарисуем ограничивающие рамки для всех обнаруженных объектов для каждого видеокадра с помощью cv2.rectangle. Давайте взглянем на результаты после рисования ограничивающих рамок.

Рисование ограничивающей рамки в обнаружении движущихся объектов opencv
РИСУНОК 7 – Рисование ограничивающей рамки с помощью OpenCV

Разве не удивительно, что мы можем достичь всего этого с помощью простой обработки изображений и OpenCV?

Вывод видео для обнаружения движущихся объектов
РИСУНОК 8 – Итоговое выходное видео

Ниже приведен вывод всего видео для обнаружения движущихся объектов с помощью OpenCV.

Создание приложения Gradio

Теперь наш конвейер кода идеально подходит для создания качественного выходного видео с любого входного сигнала с стабильным кадром камеры. Что, если мы сможем сделать немного больше и создать веб‑приложение на основе этого пути программирования?

Круто, правда? Итак, мы создали это веб‑приложение с помощью Gradio и разместили его на облачном сервере.

демонстрация gradio для обнаружения движущихся объектов с помощью opencv
РИСУНОК 9 – Демонстрация Gradio

Ссылка на демонстрацию Gradio

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

Реальные приложения

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

Пример использования в реальном мире
Пример использования в реальном мире

Интеллектуальные среды

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

Видеонаблюдение и мониторинг активности человека

Обнаружение движущихся объектов широко используется в системе видеонаблюдения для мониторинга деятельности человека. Его можно применять в различных условиях, от общественных мест до частных владений, в целях безопасности и мониторинга. Технология также может использоваться для ухода на дому, предоставляя средство для мониторинга благополучия жителей, особенно пожилых людей или лиц с особыми потребностями.

Промышленное применение

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

Управление дорожным движением и обнаружение транспортных средств

Технология играет важную роль в обнаружении транспортных средств, что является важнейшим компонентом интеллектуальных систем управления дорожным движением. Это помогает в мониторинге транспортного потока, обнаружении нарушений правил дорожного движения и эффективном управлении сигналами светофора.

Визуальный анализ контента

Обнаружение движущихся объектов включает в себя такие приложения, как обнаружение действий и распознавание, а также судебную экспертизу видеоконтента после события. Это полезно при анализе отснятого видео для различных целей, от спортивного анализа до юридических расследований.

Ограничения обнаружения движущихся объектов

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

Чувствительность к изменениям окружающей среды

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

Предположение о статическом фоне

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

Ограниченное представление объектов

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

Плохая адаптация к закрытиям

Традиционные методы борются с перекрытиями, когда объект частично или полностью скрыт. Им не хватает понимания контекста для обнаружения объектов во время и после перекрытия.

Невозможность обработки движения камеры

Когда движется сама камера, различение движения, вызванного движением камеры, и движения объекта становится сложной задачей для этих методов.

Ограниченная масштабируемость и гибкость

Традиционные алгоритмы часто разрабатываются для конкретных сценариев и им не хватает гибкости для адаптации к новым, невидимым средам или типам объектов без обширного реинжиниринга или переподготовки.

Низкая надежность в сложных сценах

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

Сложности обнаружения как неподвижных, так и движущихся объектов в сценах, снятых движущейся камерой, требуют передовых методов, выходящих за рамки возможностей традиционных методов. CNN и Transformers, с их надежным выделением признаков, пониманием контекста и адаптивностью, предлагают значительные улучшения в работе с такими сложными сценариями, прокладывая путь к более точным и надежным системам обнаружения объектов в динамичных средах.

Комментарии (8)


  1. Jury_78
    15.01.2024 09:40

    Разве не удивительно, что мы можем достичь всего этого с помощью простой обработки изображений и OpenCV?

    Разве не для таких задач она создавалась?


    1. dimanosov007 Автор
      15.01.2024 09:40
      +1

      Для этого, но в статье так написано, решил оставить)


  1. U235a
    15.01.2024 09:40

    Можно вообще контуры не использовать.

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


  1. ivankudryavtsev
    15.01.2024 09:40
    +1

    Давайте сделаем скидку на то, что это перевод, а переводчик, как известно, аналитикой не блещет. Однако, стоит отметить, что OpenCV в своем составе имеет готоые к использованию функции вычисления фона/объектов.

    Например, MOG2:

    https://dev.to/azure/opencv-background-subtraction-in-a-camera-feed-using-mog2-3dg8

    import cv2
    
    backSub_mog = cv2.createBackgroundSubtractorMOG2()
    
    # open camera 
    cap = cv2.VideoCapture(1)
    
    while True:
        # read image
        ret, img = cap.read()
    
        #resize office to 640x480
        img = cv2.resize(img, (320, 240))
        imgNoBg =  backSub_mog.apply(img)
    
        # show both images
        cv2.imshow('office',img)
        cv2.imshow('office no bg MOG2',imgNoBg)
    
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    # close camera
    cap.release()
    cv2.destroyAllWindows()

    И, например, MOG2 очень неплохо работает на CUDA - 1000 FPS на 4060 Laptop легко. В работе: https://www.youtube.com/watch?v=P9w-WS6HLew&ab_channel=IvanKud


    1. Jury_78
      15.01.2024 09:40

      Справедливости для... В этой же статье написано:

      Для вычитания фона мы создали другой объект, используя cv2.createBackgroundSubtractorMOG2.


      1. ivankudryavtsev
        15.01.2024 09:40

        Ой, я сказочно затупил :)


  1. Borjomy
    15.01.2024 09:40

    Интересно, а что будет при наличии дыма местами? Контраст-то падает.


  1. fiksii
    15.01.2024 09:40

    Есть ещё одна проблема - сжатие видеопотока, из-за этого фон каждый раз чуть-чуть разный