Высокопроизводительный детектор движения с подавлением шума на Python, OpenCV и Numba

Детекция движения – актуальная проблема в решении задач видеоаналитики. Часто она осуществляется за счет сравнения изменяемой части изображения с неизменяемой, что позволяет выделить фон и движущийся объект. Простой детектор движения можно легко найти на просторах интернета, например, на сайте Pyimagesearch.com. Это примитивный детектор, который не обрабатывает:

  • изменчивость окружающей среды;
  • шум видеопотока, который может возникать в связи с различными факторами.

В статье мы рассмотрим реализацию подвинутого детектора на Python, который подходит для использования на зашумленных потоках с высоким FPS. Реализация будет опираться на библиотеку OpenCV для работы с изображениями и видео, библиотеку NumPy, используемую для проведения операций над матричным представлением фреймов, и на Numba, которая применяется для ускорения части операций, которые выполняются в Python.

Шум – это природное или техническое явление, наблюдаемое в видеопотоке, которое не формирует полезного информационного фона, вызывая ложные срабатывания детектора. Пример шума:

  • блики солнечного света;
  • отражения предметов от прозрачных стеклянных поверхностей;
  • колебания мелких объектов в кадре – листва, трава, пыль;
  • дрожжание камеры за счет внешних мелких вибраций;
  • мерцание осветительных приборов дневного света;
  • дефекты изображения за счет низкой светосилы, качества матрицы камеры;
  • рассыпание картинки из-за сетевых помех или наводок при использовании аналоговых камер.

Вариантов шума много, результат один – микроизменения в изображении, которые возникают даже в отсутствии явного движения в кадре. Базовые алгоритмы не обрабатывают данные эффекты. Алгоритм, рассматриваемый в данной статье позволяет успешно справляться с последствиями шума. Пример шума можно видеть на следующем фрагменте видео с частотой кадров 60 FPS:

Базовый алгоритм определения движения

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

  1. сжатие изображения для удаления лишних деталей с интерполяцией для лучшего усреднения;
  2. гаусовское размытие для удаления лишних деталей и снижения уровня зашумленности;
  3. вычитание из текущего фрейма фрейма фона;
  4. отсечение “тусклых” фрагментов, которые характерны для фона;
  5. выравнивание цвета “ярких” фрагментов, которые характерны для движения;
  6. поиск контуров движущихся объектов.

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

В описываемом ниже детекторе недостатки базового алгоритма будут устранены.

Продвинутый алгоритм определения движения

Общая схема алгоритма приведена на следующем рисунке:

Рассмотрим шаги алгоритма.

Шаг 1: Сжатие. На данном шаге происходит сжатие исходного изображения, что позволяет удалить мелкие детали и снизить уровень шума. Кроме того, это позволяет ускорить последующие операции и уменьшить количество потребляемой оперативной памяти.

Шаг 2: Размытие. Уменьшенный фрейм подвергается гауссовскому размытию для того, чтобы еще более сгладить детали, выровнять фон, уменьшить шум и снизить влияние незначительных колебаний фона.

Шаг 3: Добавление в буфер движения. Циклический буфер движения используется для того, чтобы снизить уровень шума фона за счет усреднения. При этом в данном буфере новые кадры считаются более релевантными, чем старые. После того, как кадр вытесняется из буфера движения, он перемещается в циклический буфер фона. Размер буфера движения – от 3-5-10 фреймов (до 1/3 секунды). Чем больше кадров в буфере движения, тем выше вероятность обнаружения, но больше погрешность за счет включения в область движения “хвоста” объекта.

Шаг 4: Добавление в буфер фона. Буфер фона – объемный буфер, в котором кадры формируют усредненную картину прошлого состояния среды за более продолжительное время, например, за 1 секунду для изменчивой среды, за 10 секунд для более стабильной среды. Чем больше кадров в истории буферного фона, тем меньший уровень шума создают краткосрочные изменения пространства, например, движение листвы, но дольше влияют объекты, которые продолжительное место находятся в кадре, например, высаживающая людей машина. Кадры, вытесняемые из буфера движения перемещаются в буфер фона, что позволяет задать “отставание” сцены фона от сцены движения.

Шаг 5: Усреднение фона. Операция усреднения фона производится как среднее арифметическое среди кадров в буфере фона.

Шаг 6: Усреднение движения. Операция усреднения движения производится в форме суммы кадров буфера движения с коэффициентами арифметической прогрессии, которая нормируется на сумму арифметической прогрессии. Это позволяет повысить значимость самых “свежих” кадров и понизить значимость старых кадров.

Шаг 7: Вычитания фона из движения. На этом этапе производится определение мест, в которых фон отличается от анализируемого кадра, что соответствует движению. Результирующее изображение содержит ряд “цветных” пятен, которые соответствуют движущемуся предмету. На следующем изображении можно видеть результат данной операции в правом верхнем окне.

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

Далее, отсекаются “тусклые” части изображения, которые характеризуют или “хвосты” или зашумления. Отсечение производится по порогу белого цвета. Чем выше порог отсечения, тем большее количество движений будет проигнорировано – в частности, при движении объектов, цвет которых слабо отличается от цвета фона, они будут игнорироваться.

Шаг 8: Уменьшение размера кадра движения. Алгоритм построения контуров объектов зависит от площади “белого” в кадре. Кроме того, на шаге “7” объекты могут содержать “трещины”, “просветы”, могут наблюдаться мелкие движения, которые должны игнорироваться (например, лист бумаги перемещается ветром), что может вести к детекции “шума”, ухудшению качества детекции, низкой производительности алгоритма. Для предотвращения этой ситуации, выполним дальнейшее уменьшение кадра – кадр снизу справа из примера.

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

Примеры работы алгоритма:

Инструментарий

При разработке алгоритма использовался следующий инструментарий Python:

  • OpenCV – обработка видео;
  • Numba – оптимизация ресурсоемких операций;
  • NumPy – работа с матрицами.

Репозиторий с кодом на GitHub

Вы можете скачать алгоритм или предложить свои улучшения в него на GitHub по адресу https://github.com/bwsw/rt-motion-detection-opencv-python.