Владельцы торговых центров и управляющие мероприятиями часто сталкиваются с проблемой точного подсчёта посетителей. Старые счётчики на входе дают погрешность до 20%, а данные о перемещении внутри помещений отсутствуют. Мы разработали систему на основе компьютерного зрения, которая решает эти задачи: мы строим систему подсчёта посетителей под ключ, используя современные методы детекции и трекинга. Наш опыт — более 5 лет в видеоаналитике, 50+ реализованных проектов.
Почему верхний обзор (top-view) оптимален?
Камера, установленная на потолке перпендикулярно полу, даёт минимальные перекрытия объектов. Люди видны как силуэты, что упрощает детекцию. Это стандартный подход для people counting: точность достигает 97–99%. Мы используем модели YOLO (Ultralytics) с трекингом ByteTrack, что позволяет отслеживать каждого посетителя.
from ultralytics import YOLO
import numpy as np
import cv2
class PeopleCounter:
def __init__(self, model_path: str,
count_line: tuple, # ((x1,y1), (x2,y2))
direction: str = 'both'): # 'in', 'out', 'both'
self.model = YOLO(model_path)
self.count_line = count_line
self.direction = direction
# ByteTrack встроен в Ultralytics
self.tracker_config = 'bytetrack.yaml'
self.track_history = {}
self.count_in = 0
self.count_out = 0
self.counted_ids = set()
def process(self, frame: np.ndarray) -> dict:
# Детекция людей с трекингом
results = self.model.track(
frame,
persist=True,
conf=0.4,
classes=[0], # только люди
tracker=self.tracker_config
)
if results[0].boxes.id is None:
return self._get_counts()
for box, track_id in zip(results[0].boxes.xyxy,
results[0].boxes.id):
tid = int(track_id)
x1, y1, x2, y2 = map(int, box)
cx, cy = (x1 + x2) // 2, (y1 + y2) // 2
if tid not in self.track_history:
self.track_history[tid] = []
self.track_history[tid].append((cx, cy))
# Проверяем пересечение линии
if len(self.track_history[tid]) >= 2 and tid not in self.counted_ids:
prev_pos = self.track_history[tid][-2]
curr_pos = self.track_history[tid][-1]
crossing = self._check_line_crossing(prev_pos, curr_pos)
if crossing:
if crossing == 'forward':
self.count_in += 1
else:
self.count_out += 1
self.counted_ids.add(tid)
return self._get_counts()
def _check_line_crossing(self, prev: tuple, curr: tuple) -> str | None:
"""Определение факта и направления пересечения линии"""
lx1, ly1 = self.count_line[0]
lx2, ly2 = self.count_line[1]
# Векторное произведение для определения стороны
d1 = self._cross_product(prev, (lx1, ly1), (lx2, ly2))
d2 = self._cross_product(curr, (lx1, ly1), (lx2, ly2))
if d1 * d2 < 0: # пересечение
return 'forward' if d1 < 0 else 'backward'
return None
def _cross_product(self, point, line_start, line_end):
return ((line_end[0] - line_start[0]) * (point[1] - line_start[1]) -
(line_end[1] - line_start[1]) * (point[0] - line_start[0]))
def _get_counts(self) -> dict:
return {
'count_in': self.count_in,
'count_out': self.count_out,
'current_occupancy': self.count_in - self.count_out
}
Тепловая карта передвижений
Для анализа зон притяжения мы строим тепловые карты. Аккумулятор накапливает позиции треков с экспоненциальным забыванием. Данные сглаживаются GaussianBlur и накладываются на видеокадр.
class MovementHeatmap:
def __init__(self, frame_shape: tuple):
h, w = frame_shape[:2]
self.accumulator = np.zeros((h, w), dtype=np.float32)
self.decay = 0.995 # забываем старые данные
def update(self, track_positions: list[tuple]):
self.accumulator *= self.decay
for x, y in track_positions:
if 0 <= x < self.accumulator.shape[1] and \
0 <= y < self.accumulator.shape[0]:
self.accumulator[y, x] += 1.0
# Gaussian blur для сглаживания
self.accumulator = cv2.GaussianBlur(
self.accumulator, (21, 21), 0
)
def get_heatmap(self, frame: np.ndarray) -> np.ndarray:
normalized = cv2.normalize(
self.accumulator, None, 0, 255, cv2.NORM_MINMAX
).astype(np.uint8)
colormap = cv2.applyColorMap(normalized, cv2.COLORMAP_JET)
return cv2.addWeighted(frame, 0.6, colormap, 0.4, 0)
Аналитика и отчётность
Данные подсчёта идут в time-series базу InfluxDB и доступны в Grafana. Мы настраиваем дашборды с трафиком за день/неделю/месяц, пиковыми часами, конверсионной воронкой по зонам и контролем наполняемости.
Точность систем подсчёта
| Условия |
Accuracy |
| Top-view, хорошее освещение |
97–99% |
| Боковой обзор, умеренная плотность |
93–96% |
| Плотные толпы (>30 чел/м²) |
85–91% |
| Плохое освещение |
88–93% |
| Масштаб |
Срок |
| 1–4 входа, базовый подсчёт |
2–3 недели |
| Торговый центр, тепловые карты |
4–7 недель |
| Сеть объектов + аналитика |
7–12 недель |
Что входит в разработку
- Обследование помещения и согласование расположения камер.
- Установка и настройка оборудования.
- Разработка модели детекции и трекинга под ваши условия.
- Интеграция с InfluxDB, Grafana, вашей CRM или BI.
- Тестирование и калибровка точности.
- Обучение персонала и документация.
Многокамерная система: синхронизация и дедупликация
Для объектов с несколькими входами данные с каждой камеры суммируются, но важно исключить двойной счёт при переходе посетителя из зоны в зону. Мы используем глобальный трекер на основе Re-ID (ReID): каждый посетитель получает уникальный эмбеддинг по внешнему виду (BoT-SoRT / StrongSORT), сохраняется в Redis и проверяется при появлении в другой камере в течение заданного временного окна.
Пример конфигурации для торгового центра с 8 входами:
- Камеры: 8 × Hikvision DS-2CD2185G1 (8 МП, 30fps).
- Сервер обработки: 1 × NVIDIA A10G (24 ГБ VRAM), обрабатывает все 8 потоков с задержкой менее 150 мс.
- Redis TTL для дедупликации: 30 минут (время перехода между входами).
- Точность дедупликации: >97% при хорошем освещении.
Интеграция с BI и прогнозирование посещаемости
Данные о посещаемости ценны не только в реальном времени, но и как исторический ряд для планирования. Мы строим pipeline от счётчика до BI-дашборда:
- InfluxDB — хранение time-series данных (вход/выход по 5-минутным интервалам).
- Apache Superset или Power BI — дашборды для менеджмента: трафик по дням, часовые пики, аномалии.
- Prophet / SARIMA — прогноз посещаемости на следующую неделю с точностью MAE < 8%.
Прогнозы используются для оптимизации расписания персонала: при ожидаемом пике система рекомендует увеличить число кассиров или открыть дополнительный вход.
Соответствие нормам: GDPR и защита персональных данных
Система не хранит персональных данных: трекинг ведётся по анонимным ID, изображения посетителей не сохраняются на диск. Для дополнительной защиты предусмотрено размытие лиц в режиме реального времени (face blur). Это соответствует требованиям GDPR и российского законодательства о персональных данных. При необходимости — готовим документацию для DPO и проводим оценку воздействия на защиту данных (DPIA).
Типичные ошибки при развёртывании
- Установка камер с горизонтальным углом вместо строго вертикального: точность падает на 10–15%.
- Недостаточное освещение в ночное время: ставим IR-подсветку или используем камеры с WDR.
- Пересечение зон захвата двух камер без дедупликации: двойной счёт одного посетителя.
- Игнорирование дрейфа модели: через 3–6 месяцев при изменении условий освещения или одежды точность снижается — нужно дообучение.
Мы гарантируем точность не ниже заявленной, предоставляем поддержку после запуска. Оценим ваш проект за 2 дня — свяжитесь с нами. Получите консультацию по внедрению системы подсчёта посетителей.
Как distribution shift убивает метрики CV-модели в промышленности
На производстве ставят камеру, контролируют качество продукции. Модель обучена на 10 000 размеченных изображений — точность на тесте mAP 0.84. Запускают в продакшен — и в первую же неделю пропускают 30 % дефектов. Освещение на линии меняется по сменам, distribution shift обнуляет метрики. Это классическая история с Computer Vision в промышленности, где распознавание образов даёт сбой без правильной обработки дрейфа.
Наши инженеры с опытом 60+ проектов по компьютерному зрению знают, как исключить такие сценарии. Гарантируем стабильную работу модели под реальными условиями.
Детекция объектов: YOLO, RT‑DETR и всё что между ними
YOLO — стандарт для real‑time детекции. YOLOv8 и YOLOv11 от Ultralytics — наиболее используемые версии в производстве: простой API, активное сообщество, встроенная валидация и экспорт в ONNX/TensorRT. Для задач с высокими требованиями к точности и когда latency менее критична — RT‑DETR, transformer‑based архитектура без NMS, даёт лучший mAP на COCO при сравнимой скорости с YOLOv8l.
| Архитектура |
mAP на COCO (val2017) |
FPS (A10G, FP16) |
Сложность деплоя |
| YOLOv8n |
37.3 |
700+ |
Низкая (ONNX/TensorRT) |
| YOLOv8m |
50.2 |
250 |
Низкая |
| RT‑DETR-L |
53.0 |
140 |
Средняя (требует PyTorch) |
| Mask R‑CNN |
38.2 (bbox) |
30 |
Высокая |
Типичная ошибка при обучении детектора: датасет 8000 изображений, 3 класса, fine‑tune YOLOv8m — F1 0.73 на валидации. Смотрим confusion matrix — один класс почти никогда не детектируется. Причина: дисбаланс 1:23. Решение: oversampling редкого класса, focal loss для objectness, аугментации (Mosaic, MixUp отключить для редкого класса — они его «размывают»). Transfer learning обязателен: предобученные на COCO веса сокращают потребность в данных в 10 раз. Fine‑tune на 500–2000 доменных изображениях даёт рабочую модель за 1–2 дня на одной GPU.
Для edge deployment: экспорт в ONNX → TensorRT engine. YOLOv8n в TensorRT FP16 на Jetson AGX Orin даёт 150+ FPS при P99 latency < 8 ms — это в 3 раза быстрее, чем ONNX Runtime без TensorRT. На сервере A10G: 700+ FPS для YOLOv8n в TensorRT INT8.
Как fine‑tuning YOLO помогает в распознавании образов?
Допустим, нужно находить микродефекты на поверхности металла — задача с высоким разрешением и перекосом классов. Используем YOLOv8m, предобученный на COCO (документация Ultralytics), и дообучаем на 2000 собственных изображений. Применяем аугментации Mosaic, MixUp, random perspective. После 200 эпох mAP 0.5 достигает 0.93. Ключевые приёмы:
-
focal loss для objectness головы — уменьшает вклад легко классифицируемых примеров.
-
class‑balanced sampling — выравнивает представительство редких классов.
-
Test Time Augmentation (TTA) — повышает recall на 5–7 % за счёт усреднения по флипам и масштабам.
Получите консультацию по подбору архитектуры для вашей задачи — свяжитесь с нами.
Сегментация: SAM, Mask R‑CNN и instance segmentation
SAM (Segment Anything Model) от Meta изменил подход к сегментации. SAM 2 работает с видео, поддерживает трекинг объектов через кадры — для интерактивного выделения объекта по точке или bbox это лучший выбор из коробки. Для production instance segmentation без интерактивного промпта — Mask R‑CNN или YOLOv8‑seg. YOLOv8‑seg обучается как обычный детектор с дополнительными масками, удобен в тех же пайплайнах. Семантическая сегментация (каждый пиксель — класс) — SegFormer, DeepLabV3+. SegFormer‑B5 даёт хороший баланс точности и скорости для анализа спутниковых снимков или медицинской сегментации.
Кейс: сегментация клеток на микроскопических изображениях. Датасет 400 изображений с ручной разметкой. Обучение Mask R‑CNN на ResNet‑50 backbone дало IoU 0.61 — плохо. Проблема: объекты (клетки) перекрываются, стандартный NMS убивает перекрывающиеся предсказания. Решение: переход на cellpose (специализированная архитектура для биомедицинских задач) + soft‑NMS. IoU вырос до 0.79.
OCR: когда Tesseract не справляется
Tesseract — отправная точка для простых задач: печатный текст, хорошее освещение, ровное расположение. Как только появляются рукописные элементы, нестандартные шрифты, перспективные искажения или многоколоночный макет — Tesseract деградирует быстро.
PaddleOCR — production‑grade решение: обнаружение текстовых блоков + распознавание + структурный анализ. Работает из коробки для 80+ языков, включая русский. Поддерживает таблицы и документы со сложной структурой. Wikipedia: Оптическое распознавание символов. TrOCR (Microsoft) — трансформерный OCR с сильными результатами на рукописном тексте. Для русского рукописного текста нужен fine‑tuning: базовая модель обучена преимущественно на латинице.
Что делать, если Tesseract не справляется с распознаванием образов на документах?
Для задач «извлеки данные из счёта / договора / паспорта» используем LayoutLMv3 или Donut — эти модели понимают layout документа, а не только текст. Интеграция через Hugging Face Transformers, fine‑tuning на 200–500 размеченных документах. Типичный pipeline:
- Preprocessing: deskew, denoising, binarization через OpenCV.
- Обнаружение текстовых блоков: PaddleOCR detection или CRAFT.
- Распознавание: PaddleOCR recognition или TrOCR.
- Post‑processing: нормализация, валидация через regex или LLM для структурированных полей.
Для документов с фиксированной структурой template matching + OCR точечно по координатам зачастую надёжнее end‑to‑end решения.
Face Recognition: идентификация и верификация
Face recognition = detection + alignment + embedding + matching. Каждый этап важен.
Detection: RetinaFace или InsightFace для точной локализации лица и ключевых точек. MTCNN — более старое, но надёжное решение. Embedding: ArcFace (InsightFace) — state‑of‑the‑art для face recognition embeddings. Модели iresnet50/iresnet100 предобучены на MS1MV3 (5M идентичностей). Эмбеддинг‑вектор 512 float32, сравнение по cosine similarity. Threshold tuning: порог решения — критический параметр. При threshold 0.6 типичный FPR на LFW benchmark — 0.001, TPR — 0.985. В production threshold нужно калибровать под реальный distribution: люди в масках, с изменившейся внешностью, в разных условиях освещения. Liveness detection обязателен: MiniFASNet — lightweight модель на CPU, FaceX‑Zoo содержит несколько предобученных liveness‑детекторов.
Видеоаналитика
Видео — последовательность кадров плюс временное измерение. Наивный подход — детектировать на каждом кадре — дорого.
Трекинг: ByteTrack и BoT‑SORT — стандарт для multi‑object tracking. Работают поверх любого детектора, добавляют persistent ID объектам между кадрами — это даёт подсчёт объектов, треки движения, velocity.
Оптимизация: не нужно обрабатывать каждый кадр. Для статичных сцен детекция на каждом 5–10 кадре, между ними — трекер. Для детекции событий (человек вошёл в зону) background subtraction (OpenCV MOG2) как lightweight pre‑filter перед нейросетевой детекцией. Action Recognition: SlowFast, VideoMAE для классификации действий. Тяжёлые модели — для production используем ONNX export + TensorRT либо оффлайн обработку.
Как измерить качество модели распознавания образов в продакшене?
Мониторинг качества — ключевой элемент MLOps. Отслеживаем:
- распределение prediction confidence;
- долю low‑confidence предсказаний (индикатор OOD‑данных);
- дрейф входных изображений через feature distribution (embeddings из backbone).
Падение средней confidence с 0.87 до 0.71 за неделю — ранний сигнал о distribution shift. NVIDIA Triton Inference Server рекомендует отслеживать эти метрики через Prometheus. Наши сертифицированные инженеры настраивают мониторинг и гарантируют SLA по качеству инференса.
Деплой CV‑моделей
Для онлайн инференса используем Triton Inference Server (NVIDIA) — production‑стандарт для serving CV‑моделей. Поддерживает TensorRT, ONNX, PyTorch, dynamic batching, multiple instances. REST и gRPC API. Гарантируем стабильную работу под нагрузкой.
Edge deployment: ONNX Runtime на ARM/x86 CPU. TensorFlow Lite для мобильных устройств. OpenVINO для Intel CPU/GPU/VPU — даёт 2–3× прирост скорости на Intel железе по сравнению с ONNX Runtime. После деплоя передаём модель с документацией и обучаем персонал.
Что входит в работу
| Этап |
Содержание |
Ориентировочный срок |
| Анализ |
Техническое задание, подбор архитектуры, оценка данных |
3–5 дней |
| Разметка |
Сбор изображений, аннотирование (до 5000 объектов) |
1–3 недели |
| Обучение |
Fine‑tuning модели, валидация на тестовой выборке |
1–2 недели |
| Оптимизация |
Экспорт в ONNX/TensorRT/OpenVINO, тестирование на целевом железе |
1–2 недели |
| Интеграция |
REST/gRPC API, интеграция с существующей инфраструктурой |
1–2 недели |
| Деплой |
Развёртывание на сервере или edge‑устройстве, нагрузочное тестирование |
1 неделя |
| Документация и обучение |
Инструкции, обучение персонала, передача кода и модели |
3–5 дней |
| Поддержка |
Техническая поддержка на 3 месяца после запуска |
— |
Сроки и стоимость
Прототип детектора на существующих данных — 1–2 недели. Production‑система с оптимизацией под целевое железо — 4–8 недель. Полный цикл включая разметку данных (1000–5000 изображений) — 2–4 месяца. Стоимость рассчитывается индивидуально под каждую задачу. Примерная экономия от внедрения системы контроля качества — до 1 млн рублей в месяц на одном производственном участке.
Мы на рынке более 5 лет, реализовали 60+ проектов по компьютерному зрению. Оценим ваш проект под ключ — закажите консультацию, чтобы получить расчёт и техническое предложение.