В основе приложения подсчета посетителей лежит использование широко-известной библиотеки OpenCV, которое имеет огромное количество алгоритмов компьютерного зрения и позволяет легко и быстро обрабатывать входной видеопоток.
В общем виде задачу можно представить в виде нескольких модулей:
- Выделение движущихся объектов из общего видеопотока
- Сегментация объектов и поиск людей среди них
- Разделение групп на отдельных людей
- Трекинг людей
- Подсчет прохождения посетителей через определенные ворота
В целом имеется множество примеров, где эта задача решаются тем или иным способом и без труда можно найти код, где простой питон-скрипт на пару страниц экрана умеет выделять посетителей и ввести их подсчет. Однако, для реального применения нам этих алгоритмов оказалось недостаточно и пришлось искать способы их улучшения.
Основные проблемы стоящие перед нами были следующие:
- По требованию заказчика необходимо было оставить только минимальное количество настроек. так чтобы клиент мог установить “up board” на разной высоте (например — 3-5 м) и оно само могло бы начать считать людей без настройки. То есть необходимо было упростить выбор настраиваемых параметров и сделать алгоритм более устойчивым к их изменениям.
- Процессорная мощность выбранных устройств было достаточно малой и алгоритм быстро работающий на среднем компьютере становился ужасно медленным при запуске на тестовых модулях.
- Поток людей в торговых центрах часто приводит к тому, что люди проходят слишком близко друг от друга и требуется их разделение на отдельных людей, что обычно не рассматривается в подобных задачах. Имеются возможности использовать различные детекторы людей для их разделения, но они также требовательны к производительности.
Рассмотрим основные принципы решения озвученных проблем в нашем приложении.
Удаление заднего фона
Стандартный подход OpenCV к выделению движущихся объектов заключается в использовании готового фильтра “Background Subtraction”, который автоматически решает данную проблему, однако, эксперимент на видео, присланных заказчиком показал, что его возможностей оказалось недостаточно и нам нужен был более гибкий подход. Так требовалось более качественное выделение объектов, гибкое время “затирания остановившихся объектов”, подбор параметров и прочее. Для решения этой задачи нами был успешно применен алгоритм Vibe с нашей собственной реализацией. Его использование позволило улучшить выделение объектов и более широко варьировать параметры детектирования.
Сегментация объектов
После получения маски движущихся объектов необходимо выделить из нее отдельные элементы. В целом эта задача достаточно стандартная. Для этих целей полученная маска объектов сначала обрабатывается с использованием морфологических операций для удаления шумов, а затем сегментируется с помощью выделения контуров. Размер контуров можно фильтровать в соответствии с видимыми размерами человека на изображении и отбрасывать посторонние объекты.
Разделение людей
Среди полученных элементов мы должны определить конкретных людей. Проблема заключается в том, что во первых маска человека зачастую разбита на множество мелких элементов (из-за схожести одежды с фоном) и тогда части маски нужно объединять в один объект. Во вторых имеет обратный случай, когда несколько людей идущих рядом выглядят единым объектом.
Решение первой задачи было частью решения трекинга людей описанного ниже, а для решение второй задачи потребовалось проведение множества экспериментов и разработку быстрого и эффективного алгоритма. В нашем случае предполагалась, что камера будет установлена в коридорах, на выходе из магазина и т.д, т.е поток людей в кадре направлен в основном вертикально. Такое предположение позволяло разделять людей по анализе формы объектов. Так, в исходном контуре объекта считалась его толщина в направлении движения людей и полученный графика анализировался на наличие выделенных пиков. Если имелось несколько пиков, размер между которыми сравним с размером людей, то весьма вероятно, что они соответствуют отдельным людям.
Трекинг людей
После выделения человека вокруг него отображается условный прямоугольник, задача состояла в том, чтобы сравнивать соседние кадры и по нему определять куда он движется. Имея идеальную маску задача получается тривиальной, необходимо только найти пересечения прямоугольников и мы можем определить направление движения.
Но в общем случае задача осложнялась тем, что часто часть человека сливается с фоном и маска получается рваной. При этом отдельные части тела становятся слишком малыми и это надо учитывать при анализе размера объектов. Имея такую маску даже человеку сложно выявить людей на изображении.
Для решения этой задачи мы использовали данные о предыдущих кадрах, комбинируя которые мы смогли получить более целостную маску человека без проблемных мест.
Подсчет людей
Последней задачей был подсчет количества прошедших людей. Для этого задавались две условные линии, образующих “ворота”. При пересечении этих линий по порядку считалось что человек вошел или вышел. При решении этой задачи также возникли проблемы связанные с ошибками получения маски, а также с хаотичным движением человека. Так маска могла пропасть на паре кадров (например человек слился с фоном), потом появится за линией. Или же человек может пройти одну линию, а потом сразу вернутся. Часто при выходе с кассы люди проходят друг за другом и сливаются в один объект, а затем разделяются на два, что приводит к магическому появлению нового человека.
Совокупность таких вопросов решалась комплексно как отслеживанием человека, если он блуждает между линиями, так и созданием дополнительных немного смещенных ворот, Что уменьшало вероятность ошибки. В целом это привело к увеличению точности подсчета в сложных случаях до 85-90%.
Кроме перечисленных выше решений в проекте экспериментировали с другими подходами к задачам. Очень перспективным было использование стереокамер для точного разделения людей. Для этой цели мы тестировали kinect в качестве камеры, что позволило значительно улучшить точность разделения группы людей. Однако заказчику важно было иметь именно монолитное дешевое устройство с одной камерой и поэтому пришлось отказаться от данного подхода.
Ещё интересными моментами в проекте была необходимость низкоуровневой оптимизации алгоритмов, для получения приемлемых 30 кадров в секунду. Например, такая незначительная часть как оптимизация генератора случайных чисел позволила увеличить скорость выделения объектов в 2 раза, а общую производительность подняла на 20-25%. Также при построении графика толщины маски изначально просто суммировалось количество точек вручную, что достаточно медленною. Впоследствии алгоритм был усложнен за счет старого доброго алгоритма Брезенхема для нахождения точек контура вручную, что значительно улучшило скорость этого модуля.
Не обошлось в проекте и без казусов. Так мы долгое время оптимизировали расчет для приемлемых скоростей на тестовых видео, но когда делали отчетное видео на последних примерах заказчика, то видна была некоторая заторможенность, что вызывала его претензии. После анализа ситуации выяснилось, что эти видео были сделаны на экшн камеру с 60 к/c. Простое переформатирование до стандартных 30 к/c сразу привело к тому, что люди на видео стали передвигаться чуть ли не бегом.
Таким образом, наша команда получила опыт решения задач детектирования людей в видеопотоке с приемлемой скоростью на портативных устройствах типа «Up-board». А разработанное программное обеспечение позволило заказчику внедрять и продавать системы подсчета людей как отдельные легко-встраиваемые модули.
Комментарии (3)
SSul Автор
28.05.2018 15:54Про кинект в статье как раз упомянуто и использовали его для экспериментов. Однако заказчику требовалось простое и дешевое решение в виде отдельного модуля. Также изначально высоте подвеса и направление камеры было непоределено и могло достигать 10 и более метров. Соответственно кинект уже становится недостаточным для анализа.
Аналогично использование камер intel real sense не входило в сферу наших интересов, поскольку мы должны были встраивать наши алгоритмы в то, что имелось у заказчика.
smallghost
29.05.2018 13:52И сколько же стоила заказчику такая разработка? Ведь есть множество камер уже со встроенной аналитикой подсчёта людей. Причем от простых, где ведётся подсчет пересечения объектом виртуальной линии, до сложных, где у каждого субъекта алгоритм ищет голову и плечи.
dennyoi
Так есть же готовые велосипеды типа MS Kinect или Intel Real Sense. Там в SDK все реализовано уже.