Разработка системы подсчёта посетителей (People Counting)

Владельцы торговых центров и управляющие мероприятиями часто сталкиваются с проблемой точного подсчёта посетителей. Старые счётчики на входе дают погрешность до 20%, а данные о перемещении внутри помещений отсутствуют. Мы разработали систему на основе компьютерного зрения, которая решает эти задачи:

Направления AI-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1006

Владельцы торговых центров и управляющие мероприятиями часто сталкиваются с проблемой точного подсчёта посетителей. Старые счётчики на входе дают погрешность до 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-дашборда:

  1. InfluxDB — хранение time-series данных (вход/выход по 5-минутным интервалам).
  2. Apache Superset или Power BI — дашборды для менеджмента: трафик по дням, часовые пики, аномалии.
  3. Prophet / SARIMA — прогноз посещаемости на следующую неделю с точностью MAE < 8%.

Прогнозы используются для оптимизации расписания персонала: при ожидаемом пике система рекомендует увеличить число кассиров или открыть дополнительный вход.

Соответствие нормам: GDPR и защита персональных данных

Система не хранит персональных данных: трекинг ведётся по анонимным ID, изображения посетителей не сохраняются на диск. Для дополнительной защиты предусмотрено размытие лиц в режиме реального времени (face blur). Это соответствует требованиям GDPR и российского законодательства о персональных данных. При необходимости — готовим документацию для DPO и проводим оценку воздействия на защиту данных (DPIA).

Типичные ошибки при развёртывании

  • Установка камер с горизонтальным углом вместо строго вертикального: точность падает на 10–15%.
  • Недостаточное освещение в ночное время: ставим IR-подсветку или используем камеры с WDR.
  • Пересечение зон захвата двух камер без дедупликации: двойной счёт одного посетителя.
  • Игнорирование дрейфа модели: через 3–6 месяцев при изменении условий освещения или одежды точность снижается — нужно дообучение.

Мы гарантируем точность не ниже заявленной, предоставляем поддержку после запуска. Оценим ваш проект за 2 дня — свяжитесь с нами. Получите консультацию по внедрению системы подсчёта посетителей.