Production версия с множеством камер, базой данных временных рядов Influx и дашбордами в Grafana
Данная программа осуществляет анализ входящего трафика на участке кругового движения. Алгоритм определяет загруженность примыкающих дорог и выводит интерактивную статистику.
Подробный туториал по проекту - ссылка на видео
Склонируйте репозиторий:
git clone https://github.com/Koldim2001/TrafficAnalyzer.git
После этого необходимо в главной директории проекта создать файл с переменными окружения, которые будут прокинуты в контейнеры Grafana и Influx. Для этого создайте файл .env
и укажите подобный текст с паролями и логинами к сервисам:
INFLUXDB_ADMIN_USER=admin
INFLUXDB_ADMIN_PASSWORD=admin
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=admin
Далее запустите проект с помощью этой команды:
docker compose -p traffic_analyzer up -d --build
Для того, чтобы попасть на дашборд в Grafana надо после запуска компоуза перейти по этой ссылке. Введите логин admin
и пароль admin
.
У каждой камеры свой дашборд между которыми можно переходит по кнопке:
Каждая новая камера добавляется в компоузе как +1 инстанс бекенда traffic_analyzer_camera_{n}, в котором надо указать лишь разные scr и конфигурации через переменные окружения сервиса.
# ставим библиотеки:
python -m pip install --upgrade pip
pip install "numpy<2"
pip install cython_bbox==0.1.5 lap==0.4.0
pip install torch==2.3.1 torchvision==0.18.1 --index-url https://download.pytorch.org/whl/cu121
pip install -r requirements.txt
# запускаем код:
python main_optimized.py pipeline.send_info_kafka=False
Результат работы программы можно увидеть, перейдя по ссылке
Проект представляет собой систему для анализа видео в реальном времени, работающую с RTSP-стримами или MP4-файлами. Основной сервис traffic_analyzer_camera_{n} обрабатывает кадры, извлекает аналитические данные (например, число машин на круговом участке, загруженность примыкающих дорог) и отправляет их в брокер сообщений Kafka. Для каждой камеры записись realtime статистики ведется в свой топик statistics_{n}. Данные из Kafka автоматически записываются в базу временных рядов InfluxDB с помощью Telegraf. InfluxDB оптимальна для хранения потоковых данных благодаря высокой производительности и поддержке больших объемов информации.
Для визуализации данных используется Grafana, которая подключается к InfluxDB и отображает аналитику в виде интерактивных дашбордов. Это позволяет отслеживать ключевые метрики в реальном времени, строить графики и анализировать тренды.
- traffic_analyzer_camera_{n}: обрабатывает видеопоток по номеру n, отправляет данные в Kafka.
- Kafka: временное хранение и передача данных.
- Telegraf: перенос данных из Kafka в InfluxDB.
- InfluxDB: хранение аналитических данных.
- Grafana: визуализация данных из InfluxDB в интерактивных дашбордах.
- Nginx: выступает в роли реверс-прокси для объединения всех результирующих Flask-стримов обработанного видео на одном порту с разными эндпоинтами. Это позволяет удобно управлять доступом к видеостримам и обеспечивает единую точку входа для всех камер.
Каждый кадр (объект FrameElement) последовательно проходит через ноды, и в атрибуты этого объекта постепенно добавляется все больше и больше информации.
graph TD;
A["VideoReader<br>Считывает кадры из видеопотока"] --> B["DetectionTrackingNodes<br>Реализует детектирование машин + трекинг"];
B --> C["TrackerInfoUpdateNode<br>Обновляет информацию об актуальных треках"];
C --> D["CalcStatisticsNode<br>Вычисляет загруженность дорог"];
D --send_info_kafka==False --> F;
D --send_info_kafka==True --> E["KafkaProducerNode<br>Отправляет результаты в Kafka"];
E --> F["ShowNode<br>Реализует визуализацию результатов"];
F --save_video==True --> H["VideoSaverNode<br>Сохраняет обработанные кадры"];
F --show_in_web==True & save_video==False --> L["FlaskServerVideoNode<br>Выводит обработанные кадры в веб-интерфейсе"];
H --show_in_web==True --> L
Перед запуском необходимо в файле configs/app_config.yaml указать все желаемые параметры. Далее можно запускать код.
Чтобы запустить проект с определенным видео, необходимо указать путь к нему в докер компоузе переменной окружения. Можно вместо пути к файлу указать ссыку на rtsp поток. Там же в переменных окружения контейнера можно указать путь до json файла с указанными координатами полигонов прилегающих дорог.
main.py - основной код проекта, реализующий в цикле прогон кадров через все ноды.
main_optimized.py - Оптимизированный код main.py с помошью multiprocessing. Позволяет достичь более высокой скорости обработки (свыше 35 кадров в секунду), поскольку все ресурсоемкие операции распределены между независимыми процессами, работающими параллельно.
main_stream_optimized.py — версия для работы с потоковым видео в реальном времени, которая обеспечивает обработку только самых актуальных кадров без использования буфера. Это достигается за счет того, что кадры обрабатываются в отдельном процессе, а основной процесс всегда берет для обработки только последний доступный кадр.
main_stream_optimized_v2.py — улучшенная версия main_stream_optimized.py. Основное отличие заключается в том, что при завершении или сбое одного из процессов автоматически завершается и второй процесс. Контроль за состоянием процессов осуществляется через метод process.is_alive()
, что обеспечивает более надежное управление жизненным циклом процессов.
Пример работы алгоритма c выводом статистики: каждая машина отображается цветом, соответствующим дороге, с которой она прибыла к круговому движению + выводится значение числа видимых машин + значения интенсивности входного потока (число машин в минуту с каждой входящей дороги).
Отображается таким образом при выборе в конфигурации show_node.show_info_statistics=True
Отключить отображение окна со статистикой можно при выборе в конфигурации show_node.show_info_statistics=False
Чтобы наблюдать fps обработки как в первом представленном примере, необходимо в конфиге указать show_node.draw_fps_info=True.
Пример режима демонстрации результатов трекинга машин (каждый id своим уникальным цветом отображается)
Отображается таким образом при выборе в конфигурации show_node.show_track_id_different_colors=True
В проекте специально предусмотрено множество веток, реализующих разные уровни разработки масштабного Computer Vision проекта.
Например, в ветке main Docker Compose позволяет поднять сторонние сервисы (Grafana для визуализации и базу данных PostgreSQL). Однако основной код, реализующий бекенд, необходимо запускать локально с помощью имеющегося на компьютере Python. Туториал по этой версии кода - YouTube
Дальнейшее развитие проекта заключается в реализации полного Docker Compose из всех имеющихся сервисов, включая сам бекенд. Такая версия доступна в ветке prod_docker_version. Код из этой ветки очень просто запустить, и не требуется ничего иметь на компьютере, кроме Docker. Проект запускается единственной командой: docker compose -p traffic_analyzer up -d --build
. Туториал по этой версии кода - YouTube
Следующим этапом развития проекта стало появление ветки multicamera. В ней реализовано всё то же, что и в ветке prod_docker_version, но теперь есть удобная возможность масштабировать проект на большое число камер. Для этого потребуется лишь в файле docker-compose добавить новые контейнеры бекенда с указанием пути до нового видео ресурса. При этом вся обработка будет выполняться нативно внутри контейнеров бекенда, включая инференс самой сети. Под каждую новую камеру автоматически поднимается новый инстанс сети YOLO, реализующий детекцию транспорта. Туториал по этой версии кода - YouTube
Еще одним дальнейшим вариантом развития стало появление ветки feature/triton. По сути это та же ветка multicamera, но теперь все контейнеры бекенда не реализуют инференс сети внутри, а лишь отправляют запросы по gRPC на дополнительный сервис под названием Triton Inference Server. Благодаря этому можно масштабировать проект без значительного увеличения нагрузки (хотя значения FPS будет чуть ниже из-за того, что теперь для инференса надо отправлять запрос на сервис и получать ответы с него). Однако теперь лишь один контейнер взаимодействует с видеокартой, и инстансы бекенда не требуют GPU для работы.
Еще одним дальнейшим вариантом развития стало появление ветки feature/influx. Это как раз та ветка, в которой вы сейчас находитесь. По сути это та же ветка multicamera, но теперь база данных изменена с PostgreSQL на базу данных врмененных рядов InfluxDB. Данная база данных лучше подходит для работы с потоковыми данными, которые записываются с бекенда. При этом запись в InfluxDB осуществляется с помощью сервиса Telegraf, который читает топик брокера сообщений Kafka, в который отправляет бекенд, и производит автоматическое сохранение данных в Influx. Туториал по этой версии кода - YouTube
Структура ветвления Git проекта представлена ниже:
main
└── prod_docker_version
└── multicamera
├── feature/triton
└── feature/influx