![](https://habrastorage.org/getpro/habr/upload_files/093/ab5/495/093ab5495161214c354340e2dfde8478.png)
Стоит признать, мы таки живем в эпоху киберпанка. Он не похож (пока) на мрачные миры Ридли Скотта и сестёр Вачовски, но вполне отвечает меткому определению: high tech, low life. К третьему десятилетию двадцать первого века российская провинция так и не научилась содержать пешеходную инфраструктуру в достойном состоянии, но плотно обвешалась уличными веб‑камерами, круглосуточно взирающими на пробирающихся по заснеженным тропинкам пешеходов.
Небольшое исследование сети подсказывает, что системы аналитики качества уборки дорог и тротуаров зимой на основе данных камер уже внедрено, например, в Москве и Казани. Но то ли это тайна реализации, то ли на самом деле оно так и есть, озвучено отслеживание (в том числе визуально) именно уборочной техники, а главная метрика — счастье пешехода, осталась без внимания. Хотя делается это именно для пешеходов, и параметры их движения (скорость, направление и т. д.), кажется, должны полностью характеризовать качество работы служб ЖКХ.
В это же время мы уже имеем громадные сети камер в наших городах, захватывающих большу́ю часть дорожной инфраструктуры вместе с переходами и тротуарами. К потоку и записям с этих камер имеется доступ, что позволяет применить алгоритмы компьютерного зрения для анализа движения пешеходов.
![Онлайн-камеры на карте города Онлайн-камеры на карте города](https://habrastorage.org/getpro/habr/upload_files/e88/267/cad/e88267caddc79cdc6bb1eca6da38cfa1.png)
Проберёмся к истине сквозь сугробы видео-анализа. Откроем карту города, выберем несколько камер, выгрузим видеопоток, полученный в одинаковое время в будние дни. Сделаем это при разных погодных условиях: после снегопада, в гололедицу и при небольшой плюсовой температуре. За идеал возьмём сухой и ясный день.
![Различные погодные условия в контексте которых будем сравнивать движение пешеходов Различные погодные условия в контексте которых будем сравнивать движение пешеходов](https://habrastorage.org/getpro/habr/upload_files/6c0/30f/338/6c030f338c5f991125f2b62369e1b7ca.jpg)
Далее описывается процесс поэтапной обработки видео-данных и последующего извлечения из них метрик, отражающих качество поддержания пешеходной среды.
Шаг первый: детектируем пешеходов
Чтобы не быть голословным, сразу статья: Object Detection in 2023: The Definitive Guide. Тема очень популярная, написано по ней немало. Подходы делятся на два периода. Первый — традиционный, главное из него: детектор Виолы — Джонса (2001), детектор на основе гистограммы направленных градиентов (2006), а также детектор на основе модели деформируемых деталей (2008). После 2014 года безоговорочную власть в этой области захватили алгоритмы на основе свёрточных нейронных сетей. Среди последних выигрывает YOLO, он точен и достаточно быстр (есть шустрая tiny‑версия, немного жертвующая точностью).
![Точность детектирования - Average Precision (AP). Из статьи, озвученной выше. Точность детектирования - Average Precision (AP). Из статьи, озвученной выше.](https://habrastorage.org/getpro/habr/upload_files/41a/a57/2bb/41aa572bbd63c07e6f57806917c690a5.jpg)
Не долго думая, решаем в сторону YOLO. Он живет на GitHub, где можно скачать веса предобученных моделей. В нашей задаче вполне достаточно tiny‑версии, по причине, которую озвучу позже.
Шаг второй: отслеживаем пешеходов
Итак, пешеходов на видео нашли. Но этого не достаточно, чтобы отследить их передвижение — пока что все детектированные объекты на видео — один и тот же квантовый пешеход. С задачей трекинга в связке с YOLO отлично справляется алгоритм DeepSort. Связывание строится на основе внешних признаков объектов и их динамики движения. Есть статья на Хабре, есть готовый код на GitHub.
![Результат работы YOLOv4 и DeepSort Результат работы YOLOv4 и DeepSort](https://habrastorage.org/getpro/habr/upload_files/498/e0e/dd0/498e0edd0414831271930f4abefc69da.gif)
Отлично, теперь мы знаем о перемещениях пешеходов по изображению. Можем измерить пиксели за кадр. Чего, конечно, делать не будем, а проследуем в реальный мир с метрами и секундами.
Шаг третий: исправляем дисторсию
Если приглядеться к имеющимся «пикселям за кадр», видно, что ближе к краю изображения пешеходы двигаются медленнее. В реальности это, естественно, не так — объектив камеры деформирует изображение по типу «бочка», сжимая объекты на периферии кадра. В идеальном мире, каждая камера калибруется отдельно и дисторсия компенсируется на основе полученных данных. В реальности, зная модель камеры, можно найти в сети ее коэффициенты дисторсии и довольствоваться этим.
В коде с использованием OpenCV в Python это выглядит следующим образом
import numpy as np
import cv2
# исходное изображение
src = cv2.imread("frame.jpg")
width = src.shape[1]
height = src.shape[0]
# коэффициенты дисторсии
distCoeff = np.zeros((4, 1),np.float64)
# уникальны для конкретной модели
k1 = -1.0e-5;
k2 = 0.0;
p1 = 0.0;
p2 = 0.0;
distCoeff[0,0] = k1;
distCoeff[1,0] = k2;
distCoeff[2,0] = p1;
distCoeff[3,0] = p2;
# внутренняя матрица камеры
cam = np.eye(3, dtype=np.float32)
cam[0,2] = width/2.0 # центр по x
cam[1,2] = height/2.0 # центр по y
cam[0,0] = 10. # фокусное расстояние по x
cam[1,1] = 10. # фокусное расстояние по y
# исправленное изображение
dst = cv2.undistort(src, cam, distCoeff)
![Исходное изображение и результат коррекции дисторсии Исходное изображение и результат коррекции дисторсии](https://habrastorage.org/getpro/habr/upload_files/ec2/49a/f51/ec249af516aa2e69d2349e7a3191463f.jpg)
Интересный момент. Зная, что пешеходы, при достаточном количестве накопленных данных, должны двигаться с одинаковой средней скоростью по всей площади кадра (при условии схожих условий), можно, измеряя их скорость, калибровать камеры. Задача преобразования изображений сводится в этом случае к выравниванию средней скорости по всей площади кадра.
Шаг четвертый: проецируем землю
Тот прямоугольник поверхности земли, который мы видим в кадре в реальности имеет очертания вытянутой трапеции. Перевести координаты пешеходов в плоскость земной поверхности призвана перспективная проекция.
![Поле зрения камеры Поле зрения камеры](https://habrastorage.org/getpro/habr/upload_files/797/049/3b6/7970493b6a2dcf2576355e952b40aefe.jpg)
Преобразование выполняется путем умножения на трехмерную матрицу проекции, коэффициенты которой можно получить, взяв несколько точек из кадра и задав соответствующие им точки в плоскости проекции. Я для этого взял два объекта: один на переднем, другой на заднем плане, имеющие одинаковый в действительности размер.
Как преобразование выглядит в коде
import cv2
import numpy as np
points_from = [[15, 225], ...] # исходные точки
points_to = [[960, 225], ...] # точки после преобразования
src = np.float32(points_from)
dst = np.float32(points_to)
M = cv2.getPerspectiveTransform(src, dst) # прямая матрица трансформации
Minv = cv2.getPerspectiveTransform(dst, src) # обратная матрица трансформации
Перемножая координаты в плоскости кадра на полученную матрицу мы переводим их в координаты земной поверхности. Наглядно это можно увидеть, подействовав матрицей на изображение с помощью функции OpenCV warpPerspective
. При этом получается следующее изображение, примерно отвечающее виду сверху на рассматриваемую сцену:
![Проекция кадра в плоскость земной поверхности Проекция кадра в плоскость земной поверхности](https://habrastorage.org/getpro/habr/upload_files/196/3d0/63a/1963d063aae981751118729fab06f0f4.jpg)
Проекция импровизированной координатной сетки с помощью обратной матрицы трансформации в плоскость кадра дает следующий результат:
![Проекция координатной сетки в плоскость кадра Проекция координатной сетки в плоскость кадра](https://habrastorage.org/getpro/habr/upload_files/e9b/544/940/e9b544940b8f260fd33dbe294f65499a.jpg)
Шаг пятый: вычисляем скорость
Теперь все готово — массив точек, полученный на выходе алгоритма трекинга, мы подвергаем двум последовательным преобразованиям, сначала исправляя дисторсию, а затем выполняя перспективную проекцию. Эти координаты можно использовать для анализа движения пешеходов.
Для каждой из полученных координат мы сохранили соответствующий порядковый номер кадра. Это спасает нас в ситуации, когда детектор пропускал цель один или несколько кадров подряд. Этим грешит tiny‑версия YOLO. Но пешеходы, как правило, движутся прямолинейно, и сохраненный номер кадра позволяет вычислить скорость даже с пропущенным в процессе движения координатами.
Как выглядит вычисление скорости
PX_PER_METER = 235 # пикселей на метр в проекции
FRAMES_PER_SECOND = 14.4 # частота кадров в видео
distance = 6 # на сколько пикселей сместился пешеход между кадрами
frames_passed = 2 # сколько кадров сменилось между последовательными детектированиями
speed = (distance / frames_passed) * (FRAMES_PER_SECOND / PX_PER_METER)
Для перевода полученного значения скорости в км/ч его остается домножить полученную величину на 3.6.
Шаг шестой: считаем метрики
В голову приходят две метрики, отражающие насколько быстро движутся пешеходы и насколько скученно и прямолинейно пролегают траектории их движения.
Средняя скорость пешеходов.
Суммарная площадь траекторий.
Прямолинейность траекторий.
Для получения средних значений скорость усредняем по медиане, нивелируя выбросы вроде стоящих на одном месте людей и ошибок трекинга, площадь считаем, суммируя координаты с движением.
Шаг седьмой: рисуем картинки и графики
Переходим к тепловым картам и графикам. Как уже было указано выше, были выбраны четыре типа погодных условий:
после снегопада (тротуары не расчищены);
гололедица (тротуары не обработаны);
небольшая плюсовая температура;
сухой и ясный день;
Последнее в списке состояние считаем базовым, когда ничего не затрудняет движение пешеходов.
Посмотрим поведение пешеходов при "плохих" условиях. Наносим вычисленные значения на координатную сетку (цвет кодирует среднюю скорость движения, яркость — плотность движения в этой области).
![Пешеходное движение при небольшой плюсовой температуре и слякоти Пешеходное движение при небольшой плюсовой температуре и слякоти](https://habrastorage.org/getpro/habr/upload_files/bee/bef/2c6/beebef2c694f593b36503b1630e8507b.png)
Далее смотрим на движение в гололедицу и замечаем как заметно падает скорость и плотность передвижения пешеходов.
![Пешеходное движение в гололедицу Пешеходное движение в гололедицу](https://habrastorage.org/getpro/habr/upload_files/430/279/512/4302795125de8faaf1e0e0e8e94f3bf2.png)
Теперь попробуем другой печальный вариант — не убранный после сильного снегопада снег. Пешеходы в этом случае придерживаются тропинок, что, впрочем, не сильно сказывается на скорости.
![Пешеходное движение по снегу Пешеходное движение по снегу](https://habrastorage.org/getpro/habr/upload_files/bc3/59e/51a/bc359e51a25ae5b30dab29cda4e755e6.png)
Посмотрим на числовые значения скорости и площади. Скорость в километрах в час, площадь в «попугаях» — координатах импровизированной координатной сетки.
![Скорость и площадь области передвижения пешеходов Скорость и площадь области передвижения пешеходов](https://habrastorage.org/getpro/habr/upload_files/1ac/896/b6f/1ac896b6f2d58e2a06b54c7ca8d7e96d.png)
Ничего сверхъестественного, но забавно. В гололед мы передвигаемся медленнее всего. По снежным тропинкам быстрее, хотя и не сильно. Но двигаемся при этом очень скученно вдоль протоптанных направлений. В гололед же разбредаемся максимально широко, минуя встречных прохожих и в поисках лучшего сцепления.
Еще раз взглянем на все тепловые карты вместе с идеально чистым асфальтом.
![Тепловые карты движения пешеходов при разных погодных условиях Тепловые карты движения пешеходов при разных погодных условиях](https://habrastorage.org/getpro/habr/upload_files/452/8fa/ce1/4528face14ccfa0fa9a27523f2916605.jpg)
Никаких сюрпризов. По сухому асфальту люди передвигаются значительно быстрее и свободны выбирать любые направления. Тепловая карта в этом случае похожа на полученную в условиях гололеда, но является более зеленой-быстрой. Сумма закрашенных квадратов сетки в обратной зависимости отражает то, насколько скученны траектории пешеходов.
Посмотрим на третью метрику: прямолинейность движения. Берем первую и последнюю точку каждой траектории (человек вошел в кадр — человек вышел из кадра). По этим двум точкам нормируем все полученные траектории на одну прямую. Картина выходит следующей.
![Средние нормированные траектории движения пешеходов при разных погодных условиях Средние нормированные траектории движения пешеходов при разных погодных условиях](https://habrastorage.org/getpro/habr/upload_files/178/69e/da5/17869eda5ada9d91a46ffe2818c01445.jpg)
Считаем среднеквадратичное отклонение от центра для самых удаленных от центра точек траекторий. Что имеем: прямолинейнее всего пешеходы перемещаются в условиях сухого асфальта и гололеда. В слякоть люди выбирают маршрут более придирчиво и чаще отклоняются от условной прямой. Самыми же кривыми путями в нашем случае пешеходы ходили по тропинкам в снегу (такие вот получились тропинки). В конечном счете эти значения, естественно, сильно зависят от характера среды в моменте, но при усреднении по району или городу, вероятно, должны показывать примерно постоянную картину.
Нанесём полученные результаты на пузырьковую диаграмму. Главный показатель, скорость, отражает размер круга. По осям — прямолинейность движения и скученность траекторий.
![Метрики движения пешеходов при разных погодных условиях Метрики движения пешеходов при разных погодных условиях](https://habrastorage.org/getpro/habr/upload_files/db6/ce1/12d/db6ce112d9645ed024297c43991f9e44.png)
Численные результаты отнормированны на максимальные значения в серии. Чем бо́льшую площадь занимают траектории на тепловой карте — тем меньше скученность движения. И, в свою очередь, чем сильнее в среднем траектория отклоняется от условной прямой, соединяющей первую и последнюю её точки — тем меньше прямолинейность движения пешехода.
Итого
Небольшое упражнение на несколько вечеров показывает, что анализируя видео с городских уличных камер, можно на основе нескольких метрик оценить насколько качественно справляются со своей работой службы ЖКХ. Где не убран снег, а где не обработан лед. Потенциально эта оценка отражает именно то, для чего и производится уборка — комфорт передвижения пешеходов.
Позднее было бы интересно провести расчёты на всех доступных городских камерах, что дало бы полную картину, а также подтвердило или опровергло надежность выбранных метрик в задаче оценки качества содержания городской среды.