Разработка AI-системы детекции пешеходов и велосипедистов для автономного транспорта

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Разработка AI-системы детекции пешеходов и велосипедистов для автономного транспорта
Сложная
~1-2 недели
Часто задаваемые вопросы
Направления 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
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    854
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

Детекция пешеходов и велосипедистов для автономных систем

Уязвимые участники дорожного движения — пешеходы, велосипедисты, самокатчики — главная причина смертей в ДТП с участием автономных систем. Detect failure здесь не просто метрика в отчёте: это человеческая жизнь. Отсюда требования на порядок строже, чем для обычного CV: recall > 98% при любых условиях, включая ночь, дождь, частичное перекрытие.

Проблемы специфичные для VRU (Vulnerable Road Users)

Велосипедист с байком — вытянутый объект нестандартной формы. Самокатчик в 30 метрах занимает 15×40 пикселей. Пешеход за припаркованным автомобилем виден наполовину. Ребёнок ростом 100 см в 20 метрах — bbox 20×30 пикселей.

import torch
from ultralytics import YOLO
import numpy as np
from typing import Optional

class VRUDetector:
    def __init__(self, model_path: str, camera_params: dict):
        # YOLOv8l или RT-DETR-L для VRU: нужна высокая чувствительность
        self.model = YOLO(model_path)
        self.focal_length = camera_params['focal_length']
        self.sensor_height = camera_params['sensor_height']
        self.image_height_px = camera_params['image_height']

        # Жёсткие пороги для VRU
        self.conf_threshold = 0.3    # ниже, чем обычно — лучше лишний FP
        self.min_height_px = 20      # минимальный размер для обнаружения

        # Классы VRU
        self.vru_classes = {0: 'person', 1: 'bicycle', 3: 'motorcycle'}

    def detect(self, frame: np.ndarray,
                min_distance_m: float = 1.0,
                max_distance_m: float = 80.0) -> list[dict]:
        results = self.model(frame, conf=self.conf_threshold,
                              classes=list(self.vru_classes.keys()))
        vru_detections = []

        for box in results[0].boxes:
            x1, y1, x2, y2 = map(int, box.xyxy[0])
            h_px = y2 - y1
            cls_id = int(box.cls)

            if h_px < self.min_height_px:
                continue  # слишком маленький объект

            # Оценка дистанции по высоте bbox
            distance = self._estimate_distance(h_px, cls_id)

            if not (min_distance_m <= distance <= max_distance_m):
                continue

            vru_detections.append({
                'class': self.vru_classes[cls_id],
                'confidence': float(box.conf),
                'bbox': [x1, y1, x2, y2],
                'distance_m': distance,
                'height_px': h_px,
                'priority': 'HIGH' if cls_id == 0 else 'MEDIUM'
            })

        return sorted(vru_detections, key=lambda x: x['distance_m'])

    def _estimate_distance(self, height_px: int, cls_id: int) -> float:
        """Простая монокулярная оценка по пинхол-модели"""
        real_heights = {0: 1.75, 1: 1.05, 3: 1.10}  # метры
        real_h = real_heights.get(cls_id, 1.5)
        return (real_h * self.focal_length) / (height_px * self.sensor_height
                                                / self.image_height_px)

Ночная детекция: критический сценарий

По статистике, 76% смертельных наездов на пешеходов происходит в тёмное время суток. Стандартные RGB модели при освещённости < 3 lux теряют 30–40% recall.

Решения:

1. Тепловая камера (FLIR Lepton, Bosch BTC): тело человека при 37°C хорошо выделяется на фоне асфальта. Recall в полной темноте: 88–93%. Недостаток — нет текстуры, сложнее различить велосипед/самокат.

2. Near-IR камера (850nm): автомобильные фары с ИК компонентой освещают 60–80м. YOLOv8 дообученный на ИК-данных (FLIR ADAS dataset содержит IR-канал) держит recall 85–90% ночью.

3. Fusion RGB + тепло: лучший результат, но сложнее и дороже.

class NightVRUFusion:
    """Поздний fusion: объединяем детекции с RGB и тепловой камеры"""

    def fuse(self, rgb_dets: list, thermal_dets: list,
              iou_threshold: float = 0.3) -> list:
        all_dets = []
        used_thermal = set()

        for rgb in rgb_dets:
            best_thermal = None
            best_iou = 0.0

            for i, therm in enumerate(thermal_dets):
                iou = self._compute_iou(rgb['bbox'], therm['bbox'])
                if iou > best_iou and iou > iou_threshold:
                    best_iou = iou
                    best_thermal = i

            if best_thermal is not None:
                # Объединяем confidence
                fused = rgb.copy()
                fused['confidence'] = min(
                    1.0, rgb['confidence'] * 0.6 +
                    thermal_dets[best_thermal]['confidence'] * 0.7
                )
                fused['source'] = 'fusion'
                used_thermal.add(best_thermal)
                all_dets.append(fused)
            else:
                all_dets.append(rgb)

        # Детекции только из тепловой (объекты без RGB-эквивалента)
        for i, therm in enumerate(thermal_dets):
            if i not in used_thermal and therm['confidence'] > 0.5:
                all_dets.append(therm)

        return all_dets

Метрики качества VRU-детектора

Условие Recall цель Precision цель
День, хорошая видимость > 98% > 90%
Сумерки > 95% > 85%
Ночь (ИК-фары) > 88% > 78%
Дождь средний > 92% > 82%
Частичное перекрытие (< 40%) > 94% > 83%

Оценка на стандартных бенчмарках: KITTI Pedestrian, CityPersons, EuroCity Persons (специализирован для сложных условий).

Кейс: промышленный автопогрузчик

Автономный погрузчик на складе 15 тыс. м². Задача: остановиться при появлении человека в радиусе 3 метров. Использовали YOLOv8n + TensorRT INT8 на Jetson Orin NX: latency 18ms. При recall 99.1% на тестовом наборе из 400 сценариев — 0 пропущенных людей. FAR: 2–3 ложных срабатывания в смену (рабочий инструмент похожей формы).

Тип системы Срок
Детектор для конкретного сценария 4–7 недель
Полная VRU-система с ночной детекцией 8–14 недель
Fusion RGB+тепло с сертификацией 4–8 месяцев