Детекція пішоходів та велосипедистів для автономних систем
Вразливі учасники дорожнього руху – пішоходи, велосипедисти, самокатники – головна причина смертей у ДТП за участю автономних систем. 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 місяців |







