-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Добро пожаловать в документацию по проекту CVCounter!
CVCounter — это веб-система для детекции, трекинга и подсчёта объектов на видеопотоке. Проект создан как простой и удобный инструмент для мониторинга потоков объектов (например, вход и выход или конвейер).
Это решение не требует установки дополнительного ПО на стороне клиента и работает на любых устройствах с браузером. Проект задуман как легковесное и нетребовательное к ресурсам решение, особенно если не использовать режим с видео.
- Веб-дашборд с карточками счётчиков, поиском, фильтрами по статусу и превью камер
- Обновление счётчиков в реальном времени через Socket.IO
- Просмотр видео с результатом распознавания (MJPEG-поток)
- Текстовые режимы для легкости и экономии ресурсов
- Одновременное отображение N счётчиков (например, для входа и выхода)
- Визуальный редактор одной или нескольких зон подсчёта (полигоны), у каждой свой цвет
- Разбивка количества по классам детекции (партия / всего) на страницах счётчика, multi-view и в отчётах
- Модальное окно настроек камеры на дашборде
- Просмотр отчётов по сохранённым подсчётам (включая итоги по классам и разбивку по партиям)
- Страница системной информации (GPU/CUDA/PyTorch)
- Модульная архитектура с подключаемыми бэкендами детекции
- SORT-трекинг объектов и подсчёт по объединению зон
- Поддержка RTSP-потоков, USB-камер и видеофайлов
Приложение использует фабрику Flask (app.py) с blueprint-модулями:
| Blueprint | Модуль | Назначение |
|---|---|---|
main |
routes/main.py |
Дашборд, статические страницы |
counters |
routes/counters.py |
UI счётчиков, API, MJPEG-поток |
reports |
routes/reports.py |
Отчёты по сохранённым подсчётам |
settings |
routes/settings.py |
Редактор глобальной конфигурации (требует авторизации) |
-
Клонируйте репозиторий:
git clone https://github.com/BespredeL/CVCounter.git
-
Перейдите в директорию проекта:
cd CVCounter -
Создайте виртуальное окружение:
python3 -m venv venv
-
Активируйте виртуальное окружение:
- В Windows:
.\venv\Scripts\activate
- В Linux/Mac:
source venv/bin/activate
- В Windows:
-
Установите зависимости:
pip3 install -r requirements.txt
Примечание: PyTorch не входит в
requirements.txtи устанавливается отдельно для поддержки GPU. См. комментарии вrequirements.txtдля инструкций по CUDA/TensorRT. В Docker-образе PyTorch уже включён. -
Скопируйте файл конфигурации:
В Windows:
mv config/config.example.json config/config.json
copy config\config.example.json config\config.json
-
Настройте
config/config.json: укажите видеоисточники, пути к моделям иmodel_typeдля каждого обнаружения. -
Запустите приложение:
Адрес по умолчанию:
python app.py
http://127.0.0.1:8080
-
Клонируйте репозиторий:
git clone https://github.com/BespredeL/CVCounter.git
-
Перейдите в директорию проекта:
cd CVCounter -
Соберите и запустите с помощью Docker Compose:
docker-compose up --build
Детекторы подключаются через реестр (system/object_detection/registry.py). В конфигурации задаётся поле model_type.
model_type |
Бэкенд | Форматы моделей |
|---|---|---|
yolo |
Ultralytics YOLO | .pt |
opencv, opencv_dnn
|
OpenCV DNN |
.onnx, .pb, Darknet (.weights + .cfg) |
onnx, onnxruntime
|
ONNX Runtime |
.onnx (экспорт YOLO) |
Ultralytics YOLO (по умолчанию):
"model_type": "yolo",
"weights_path": "config/ultralytics/models/yolov8n.pt",
"device": 0OpenCV DNN + ONNX:
"model_type": "opencv",
"weights_path": "config/opencv/models/yolov8n.onnx",
"input_size": 640,
"backend": "CUDA",
"target": "CUDA"Darknet через OpenCV:
"model_type": "opencv_dnn",
"weights_path": "config/opencv_dnn/models/yolov4.weights",
"model_config_path": "config/opencv_dnn/models/yolov4.cfg",
"input_size": 416ONNX Runtime:
"model_type": "onnx",
"weights_path": "config/onnx/models/yolov8n.onnx",
"input_size": 640,
"providers": ["CUDAExecutionProvider", "CPUExecutionProvider"]| Параметр | Применимо к | Описание |
|---|---|---|
weights_path |
все | Путь к файлу модели |
model_config_path |
OpenCV Darknet | Путь к файлу .cfg
|
input_size |
OpenCV, ONNX | Размер входа: число или [width, height], по умолчанию 640
|
backend |
OpenCV |
OPENCV, CUDA, DEFAULT и др. |
target |
OpenCV |
CPU, CUDA, CUDA_FP16 и др. |
providers |
ONNX | Список провайдеров ONNX Runtime |
confidence, iou
|
все | Пороги детекции |
device |
YOLO, ONNX | Устройство (0, cpu и т.д.) |
vid_stride |
YOLO | Шаг кадров при инференсе |
classes |
все | Фильтр и подписи классов, напр. { "0": "person" } (отображаются в «По классам») |
yolo export model=config/ultralytics/models/yolov8n.pt format=onnxДля обучения и экспорта моделей YOLO используйте train.py (отдельно от веб-приложения).
- Создайте класс, наследующий
BaseObjectDetectionService, и декорируйте его@register('my_detector'). - Импортируйте модуль в
system/object_detection/__init__.py. - Укажите
"model_type": "my_detector"в конфигурации.
Все основные настройки хранятся в файле config/config.json (скопируйте из config/config.example.json).
| Параметр | Описание | Значение по умолчанию |
|---|---|---|
debug |
Включить режим отладки | true |
system_check |
Вывод информации о GPU/CUDA/PyTorch при старте | true |
log_path |
Путь к файлу журнала | storage/logs/cvcounter.log |
log_level |
Минимальный уровень журнала | INFO |
log_console |
Включить вывод журнала в консоль | false |
default_language |
Язык по умолчанию (ru, en) |
ru |
allow_unsafe_werkzeug |
Разрешить небезопасные операции в Werkzeug | false |
button_change_theme |
Показать кнопку изменения темы | true |
button_fullscreen |
Показать кнопку перехода в полноэкранный режим | true |
button_backward |
Показать кнопку назад | false |
button_save_capture |
Показать кнопку ручного сохранения кадра | false |
collapsed_keyboard |
Показать клавиатуры свернутыми | true |
| Параметр | Описание | Значение по умолчанию |
|---|---|---|
host |
Адрес сервера | 0.0.0.0 |
port |
Порт сервера | 8080 |
use_reloader |
Включить режим перезагрузки | false |
log_output |
Включить вывод журнала | false |
secret_key |
Секретный ключ Flask (генерируется автоматически, если пуст) | "" |
allowed_origins |
Разрешённый адрес для Access-Control-Allow-Origin | * |
socketio_async_mode |
Режим async Socket.IO | threading |
socketio_transports |
Список транспортов Socket.IO | ["polling", "websocket"] |
socketio_upgrade |
Разрешить апгрейд транспорта | true |
| Параметр | Описание | Значение по умолчанию |
|---|---|---|
admin |
Имя пользователя → хэш пароля (scrypt) | scrypt-хэш (пароль по умолчанию: admin) |
Пароли хранятся в виде scrypt-хэшей, а не в открытом виде. Учётные данные по умолчанию:
admin/admin.
| Параметр | Описание | Значение по умолчанию |
|---|---|---|
uri |
Подключение к базе данных | sqlite:///system/db/database.sqlite |
prefix |
Префикс таблиц | "" |
Опциональная обезличенная диагностика на ваш HTTP API. См. telemetry_api.md.
| Параметр | Описание | Значение по умолчанию |
|---|---|---|
enabled |
Автоотправка usage/errors | false |
endpoint |
URL HTTPS endpoint | https://bespredel.name/api/cvcounter/telemetry |
send_errors |
Отправлять исключения | true |
send_usage |
Отправлять события использования | true |
flush_interval_sec |
Интервал фоновой отправки | 300 |
max_batch_size |
Макс. событий в POST | 50 |
max_queue_size |
Ёмкость очереди в памяти (drop при переполнении) | 200 |
max_stack_chars |
Макс. длина stack | 8000 |
error_dedup_sec |
Окно дедупликации шумных событий | 120 |
timeout_sec |
Таймаут HTTP | 5 |
hmac_secret |
Опциональный секрет для X-CVCounter-Signature
|
"" |
Ручная отправка и скачивание JSON доступны на странице «Информация о системе», даже если enabled = false.
| Параметр | Описание | Значение по умолчанию |
|---|---|---|
defect_show |
Показать форму брака | true |
correct_show |
Показать форму коррекции | true |
custom_fields |
Определения пользовательских полей (объект) | см. config.example.json
|
custom_fields — объект, где каждый ключ — идентификатор поля. Поддерживаемые типы: text, date, datetime-local, textarea, select (с массивом options).
| Параметр | Описание | Значение по умолчанию |
|---|---|---|
model_type |
Тип модели | yolo |
weights_path |
Путь к модели | config/ultralytics/models/yolov8n.pt |
confidence |
Порог доверия | 0.7 |
iou |
Порог IOU | 0.7 |
device |
Устройство для вычислений | 0 |
vid_stride |
Шаг видеопотока | 1 |
indicator_size |
Размер индикатора | 10 |
video_show_scale |
Масштаб вывода видео на странице (%) | 70 |
video_show_quality |
Качество вывода видео на странице (%) | 50 |
video_fps |
Ручная установка FPS (0 — автоматически) | 0 |
video_reconnect_attempts |
Макс. попыток подключения к камере при старте и после обрыва потока; счётчик останавливается при исчерпании | 5 |
counting_areas |
Предпочтительный список зон (points + опциональный BGR color) |
см. config.example.json
|
counting_area |
Legacy: один полигон (алиас первой зоны) | [[0,0],[100,0],[100,100],[0,100]] |
counting_area_color |
Legacy: цвет первой зоны (BGR) | [67, 211, 255] |
classes |
Фильтр классов и подписи для UI «По классам» | {} |
| Параметр | Описание | Значение по умолчанию |
|---|---|---|
enable |
Включить запись | false |
path |
Путь сохранения видео | storage/saved_recordings |
scale |
Размер видео (в процентах) | 50 |
quality |
Качество видео | 70 |
Каждый ключ в detections — это location счётчика (латиница, используется в URL).
| Параметр | Описание | Значение по умолчанию |
|---|---|---|
label |
Наименование подсчёта | Label ExampleCam |
start_total_count |
Начальное значение подсчёта | 0 |
video_path |
Путь к видеофайлу или источнику камеры | "" |
model_type |
Тип модели | yolo |
weights_path |
Путь к модели | config/ultralytics/models/yolov8n.pt |
confidence |
Порог доверия | 0.7 |
iou |
Порог IOU | 0.7 |
device |
Устройство для вычислений | 0 |
vid_stride |
Шаг видеопотока | 1 |
indicator_size |
Размер индикатора | 10 |
video_show_scale |
Масштаб вывода видео (%) | 70 |
video_show_quality |
Качество вывода видео (%) | 30 |
video_fps |
Ручная установка FPS (0 — автоматически) | 0 |
video_reconnect_attempts |
Макс. попыток подключения (наследуется из detection_default, если не указано) |
5 |
counting_areas |
Список зон подсчёта (объединение; объект считается в любой зоне) | см. config.example.json
|
counting_area |
Legacy: один полигон (алиас первой зоны) | [[0,0],[100,0],[100,100],[0,100]] |
counting_area_color |
Legacy: цвет первой зоны (BGR) | [255, 64, 0] |
classes |
Фильтр классов и подписи для UI «По классам» | {} |
dataset_create.enable |
Включить создание набора данных | true |
dataset_create.probability |
Вероятность сохранения изображения (0.01–1) | 0.05 |
dataset_create.path |
Путь для сохранения набора данных | storage/saved_images/ExampleCam |
recording.enable |
Включить запись | true |
recording.path |
Путь сохранения видео (наследуется из detection_default, если не указан) |
storage/saved_recordings |
recording.scale |
Размер видео (в процентах) | 80 |
recording.quality |
Качество видео | 60 |
Базовый URL по умолчанию: http://127.0.0.1:8080
Главная страница с карточками счётчиков, статусами (работает/пауза/остановлен), поиском, фильтрами, превью камер и кнопками управления (запуск/пауза/стоп).
URL:
http://127.0.0.1:8080/
На странице отображается видео с камеры и счётчики объектов. Основной интерфейс для мониторинга в реальном времени. В сайдбаре — итог, текущая партия и разворачиваемый список По классам (партия / всего для каждого класса детекции).
URL:
http://127.0.0.1:8080/counter/{location}
или
http://127.0.0.1:8080/counter/{location}/video
Отображаются только значения счётчиков без видео. Подходит для устройств с низкими ресурсами. Использует тот же сайдбар с разбивкой По классам.
URL:
http://127.0.0.1:8080/counter/{location}/text
Одновременное отображение N счётчиков на одном полноэкранном экране. Заменяет устаревший dual-режим. На каждой карточке — текущая партия, общий итог и разворачиваемый список по классам; значения обновляются через Socket.IO.
URL:
http://127.0.0.1:8080/counter_multi/text?locations=Cam1,Cam2
Устаревший:
/counter_dual/text/{location_first}/{location_second}перенаправляет на мульти-счётчик.
Визуальный редактор одной или нескольких полигональных зон. В качестве фона используется снимок с видеопотока.
- Добавить зону / Удалить зону — управление несколькими областями
- Переключение активной зоны кнопками Зона 1, Зона 2, …
- Рисование и правка активного полигона (точки, перетаскивание, прямоугольник, весь кадр)
- У каждой зоны свой цвет; неактивные зоны рисуются приглушённо
- Объект считается, если его центр попал в любую зону (объединение масок)
- При сохранении пишется
counting_areas, а legacy-поляcounting_area/counting_area_colorсинхронизируются с первой зоной
URL:
http://127.0.0.1:8080/counter/{location}/counting_area
Просмотр сохранённых записей подсчётов с пагинацией. В карточке отчёта — блок По классам по сессии и разбивка по классам внутри каждой партии (если данные сохранены).
URL:
http://127.0.0.1:8080/reports
http://127.0.0.1:8080/reports/{location}
http://127.0.0.1:8080/reports/{location}/{report_id}
Редактор глобальной конфигурации и информация о GPU/системе. Требует HTTP Basic Auth.
На странице системной информации можно отправить обезличенную диагностику на endpoint телеметрии или скачать локальный JSON. См. telemetry_api.md.
URL:
http://127.0.0.1:8080/settings
http://127.0.0.1:8080/system_info
http://127.0.0.1:8080/settings/telemetry/send (POST)
http://127.0.0.1:8080/settings/telemetry/download
Встроенная страница помощи.
URL:
http://127.0.0.1:8080/page/help
Эндпоинты управления счётчиками (авторизация не требуется, если не указано иное):
| Метод | Путь | Описание |
|---|---|---|
| GET | /counter/{location}/bootstrap |
Запуск потока счётчика в фоне |
| GET | /start_count/{location} |
Возобновить подсчёт |
| GET | /pause_count/{location} |
Приостановить подсчёт |
| GET | /stop_count/{location} |
Остановить поток и очистить ресурсы |
| POST | /save_count/{location} |
Сохранить подсчёт и пользовательские поля в БД |
| GET | /reset_count/{location} |
Сбросить общий счётчик |
| POST | /reset_count_current/{location} |
Сбросить счётчик текущей сессии |
| GET | /save_capture/{location} |
Сохранить текущий кадр |
| GET | /counter_get_frames/{location} |
MJPEG-видеопоток |
| GET | /counter/{location}/preview |
JPEG-превью для дашборда |
| GET | /counter/{location}/settings/form |
HTML-фрагмент для модального окна настроек |
| POST | /counter/{location}/settings |
Сохранить настройки детекции камеры |
| GET | /counter/{location}/counting_area/data |
JSON: counting_areas (+ legacy counting_area / цвет) |
| GET | /counter/{location}/counting_area/snapshot |
Один JPEG-кадр для редактора |
| POST | /counter/{location}/counting_area |
Сохранить зоны (counting_areas в JSON; legacy-поля синхронизируются) |
| POST | /settings_save |
Сохранить глобальную конфигурацию (требует авторизации) |
Приложение использует HTTP Basic Auth (Flask-HTTPAuth). Пароли хранятся в виде scrypt-хэшей в config/config.json в секции users.
Защищённые маршруты:
/settings/settings_save/system_info
Публичные маршруты: страницы счётчиков, отчёты, дашборд и все API-эндпоинты счётчиков.
Сервер отправляет события подключённым клиентам (обработчиков от клиента к серверу нет):
| Событие | Источник | Данные |
|---|---|---|
{location}_count |
ObjectCounter | {total, current, defect, correct, pending_*, by_class: [{id, name, total, current}, ...]} |
{location}_notification |
NotificationManager | {type, message} |
counter_status_event |
NotificationManager | {data: {status, location}} |
Статусы счётчика: started, paused, stopped, error.
Транспорт Socket.IO настраивается через server.socketio_async_mode, server.socketio_transports и server.socketio_upgrade в конфигурации.
Я всегда рад новому вкладу в развитие проекта! Чтобы внести изменения, выполните следующие шаги:
- Форкните этот репозиторий.
- Создайте новую ветку.
git checkout -b feature/your-feature
- Внесите изменения и закоммитьте их.
git commit -m "Добавил новую функцию" - Запушьте изменения.
git push origin feature/your-feature
- Отправьте PR (Pull Request) на review.
Перед отправкой убедитесь, что ваши изменения не нарушают существующий функционал.
- Процессор: Современный 4-ядерный процессор (например, Intel Core i5 или AMD Ryzen 5).
- Оперативная память: Минимум 8 ГБ (рекомендуется 16 ГБ и выше для стабильной работы с потоковым видео).
- Хранилище: SSD для хранения набора данных и логов.
-
Видеокарта: Наличие GPU значительно ускоряет обработку и снижает нагрузку на систему. Минимальные требования к видеокарте:
- NVIDIA GTX 1050 (2 ГБ VRAM): минимально достаточна для обработки изображений с низкой частотой кадров.
- NVIDIA GTX 1660 (6 ГБ VRAM): рекомендуется для работы с видеопотоком в реальном времени и обработки видео высокого разрешения (до 720p).
- NVIDIA RTX 2060 или выше (6 ГБ+ VRAM): для стабильного запуска моделей YOLO в реальном времени на разрешениях от 1080p и выше.
Примечание: YOLO поддерживает вычисления на видеокартах NVIDIA с использованием CUDA. Видеокарты от других производителей (например, AMD) могут работать, но это требует дополнительных настроек, и производительность может быть ниже.
Любое устройство с веб-браузером, в котором разрешено выполнение JavaScript.
Добавьте новую запись в секцию detections в config/config.json. Ключ станет location, используемым в URL (только латиница). Перезапустите приложение или запустите счётчик с дашборда.
Используйте мульти-счётчик:
http://127.0.0.1:8080/counter_multi/text?locations=Cam1,Cam2,Cam3
Также можно выбрать несколько счётчиков на дашборде и открыть их вместе.
Проверьте работу камеры и её подключение. Убедитесь, что video_path указан правильно в конфигурации. Если камера недоступна, счётчик повторяет подключение до video_reconnect_attempts раз (по умолчанию 5, задаётся в detection_default или для конкретного счётчика), затем останавливается со статусом ошибки. Проверьте логи в storage/logs/cvcounter.log.
Проверьте server.socketio_async_mode (используйте threading с Werkzeug), server.socketio_transports (включите polling для совместимости) и server.allowed_origins.
Путь к логам по умолчанию: storage/logs/cvcounter.log (настраивается через general.log_path).
Вы можете запускать браузер в режиме киоска для предотвращения выхода из него (например, для Google Chrome при запуске укажите --kiosk --start-fullscreen).
Проект распространяется под лицензией AGPL-3.0. Подробности можно найти в файле LICENSE.