Разработка системы подсчёта объектов в кадре (Object Counting)

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Разработка системы подсчёта объектов в кадре (Object Counting)
Средняя
от 1 недели до 3 месяцев
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1218
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    853
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

Разработка системы подсчёта объектов в кадре (Object Counting)

Подсчёт объектов на изображении или видео — задача с нюансами. Простой подход «детектируй и посчитай боксы» работает только при малом количестве объектов и хорошей видимости каждого. При плотных скоплениях (толпа, урожай на поле, клетки под микроскопом, автомобили на парковке) детекторы теряют производительность. Для таких случаев применяют специализированные подходы: density maps и crowd counting модели.

Подход 1: Детекция + подсчёт

Для разреженных объектов (< 50 в кадре, объекты не перекрываются сильно) — YOLOv8/YOLO11 + подсчёт боксов:

from ultralytics import YOLO

model = YOLO('yolov8m.pt')

def count_objects(image_path: str, target_class: str) -> int:
    results = model(image_path, conf=0.4, iou=0.5)
    class_names = model.names
    target_id = [k for k, v in class_names.items() if v == target_class][0]

    count = 0
    for result in results:
        for cls in result.boxes.cls:
            if cls.item() == target_id:
                count += 1
    return count

Подход 2: Density Map для плотных скоплений

Для задач с сотнями и тысячами объектов в кадре: подсчёт людей в толпе, зёрен на поле, клеток под микроскопом.

Density map — изображение, где каждый пиксель содержит «плотность» объектов в окрестности. Интеграл по density map = количество объектов.

import torch
import torch.nn as nn
from torchvision.models import vgg16

class CSRNet(nn.Module):
    """Crowd Scene Recognition Network для подсчёта людей"""
    def __init__(self):
        super().__init__()
        # Frontend: VGG16 без FC слоёв
        vgg = vgg16(pretrained=True)
        self.frontend = nn.Sequential(*list(vgg.features.children())[:23])

        # Backend: dilated convolutions для multi-scale context
        self.backend = nn.Sequential(
            nn.Conv2d(512, 512, 3, padding=2, dilation=2),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 256, 3, padding=2, dilation=2),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 128, 3, padding=2, dilation=2),
            nn.ReLU(inplace=True),
            nn.Conv2d(128, 64, 3, padding=2, dilation=2),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 1, 1)
        )

    def forward(self, x):
        x = self.frontend(x)
        density_map = self.backend(x)
        count = density_map.sum()
        return density_map, count

Разметка для обучения: точечные аннотации (dot annotations) — по одной точке на каждый объект. Из точек генерируем density map через Gaussian kernel.

Подход 3: Counting через линию (Line Crossing)

Для видео-подсчёта транспорта, людей в дверях: трекинг + виртуальная линия.

class LineCrossingCounter:
    def __init__(self, line_start, line_end):
        self.line = (line_start, line_end)
        self.counted_ids = set()
        self.count = 0
        self.prev_positions = {}

    def update(self, track_id, center_x, center_y):
        if track_id in self.prev_positions:
            prev_pos = self.prev_positions[track_id]
            if self._crosses_line(prev_pos, (center_x, center_y)):
                if track_id not in self.counted_ids:
                    self.count += 1
                    self.counted_ids.add(track_id)
        self.prev_positions[track_id] = (center_x, center_y)

Применения и метрики

Применение Подход Метрика
Подсчёт транспорта на дороге Трекинг + линия Accuracy, false count rate
Подсчёт людей в толпе Density map (CSRNet) MAE, RMSE
Подсчёт клеток под микроскопом Density map MAE
Подсчёт фруктов на плантации YOLO + counting mAP, MAE
Инвентаризация товаров на полке YOLO + counting Accuracy

Типичные метрики CSRNet на Shanghai Tech dataset:

  • Part A (плотные толпы): MAE 68.2, RMSE 115.0
  • Part B (разреженные): MAE 10.6, RMSE 16.0
Задача Срок
Подсчёт через детекцию, готовая модель 1–2 недели
Density map, кастомный домен 3–5 недель
Комплексная система (видео + аналитика) 4–7 недель