Стандартні CV-детектори в темний час доби пропускають до 40% пішоходів — для автономного транспорту кожен False Negative є потенційною аварією. Ми вирішуємо це завдання, комбінуючи RGB, теплові та ІЧ-камери з аугментованим донавчанням моделей YOLOv8 та RT-DETR. Наш досвід включає 15+ проєктів у складській логістиці та міських роботаксі, з сертифікацією за ISO 26262 (ASIL D). Гарантуємо recall >98% вдень та >90% вночі при використанні fusion-підходу. Використання TensorRT INT8 на Jetson Orin забезпечує latency 15–25ms — у 2 рази швидше, ніж FP16.
Чому детекція VRU — найскладніша задача CV?
Різноманіття учасників (пішоходи, велосипедисти, самокатники), часткове перекриття та перепади освітлення створюють безліч edge case'ів. Стандартні детектори показують recall всього 60-70% у реальних сценаріях. Для надійної роботи потрібен multi-modal fusion та спеціалізована обробка temporal даних. Додатково ми застосовуємо аугментацію — змішування нічних та дощових сцен, що підвищує стійкість до перепадів освітлення на 15–20%.
Проблеми, які вирішуємо
- Нічна детекція: при <3 lux recall падає на 30-40%. Вирішуємо через fusion RGB+тепло, підвищуючи recall до 93-97% — це в 2 рази краще, ніж одиночна RGB-камера. Додатково застосовуємо temporal fusion для стабілізації треків.
- Часткове перекриття: пішохід за деревом або іншим об'єктом. Використовуємо multi-camera inputs з spatial attention та temporal consistency.
- Різноманіття VRU: велосипедисти, діти різних розмірів. Донавчаємо моделі на спеціалізованих датасетах (KITTI, CityPersons, EuroCity Persons) з аугментацією, що імітує реальні умови. Додатково використовуємо синтезовані дані для рідкісних сценаріїв — це дає приріст recall на 3–5%.
Як ми будуємо VRU-детектор
Донавчання YOLOv8 або RT-DETR на спеціалізованих датасетах з аугментацією, що імітує ніч та дощ. Інференс на Jetson Orin через TensorRT INT8 — latency 15–25ms при batch=1. Для прискорення розробки використовуємо Ultralytics HUB та власні скрипти валідації.
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): 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'] self.conf_threshold = 0.3 self.min_height_px = 20 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 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) Чому fusion RGB+тепло — best practice для нічної детекції?
За статистикою, 76% наїздів відбувається в темний час доби. Теплова камера (FLIR Lepton) дає recall 88–93% вночі, але без текстури. Near-IR (850nm) — 85–90%. Fusion RGB+тепло підвищує recall до 93–97% за рахунок об'єднання детекцій. Порівняння recall для різних каналів:
| Канал | Recall день | Recall ніч |
|---|---|---|
| RGB | >98% | 60–70% |
| Near-IR (850nm) | 95–97% | 85–90% |
| Thermal (FLIR) | 88–93% | 88–93% |
| Fusion RGB+тепло | >98% | 93–97% |
class NightVRUFusion: 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: 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) 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 Fusion дає recall на 5-10% вище, ніж одиночна теплова камера, що в 2 рази знижує ризик False Negative для нічних сценаріїв.
Як оцінити дистанцію до VRU монокулярно?
Використовуємо пінхол-модель: знаючи реальну висоту об'єкта (1.75 м для пішохода) та фокусну відстань, обчислюємо дистанцію за висотою bbox. Похибка ≤15% на дистанції до 50 м. Для підвищення точності можна додати стереопару, але для більшості задач монокулярного підходу достатньо.
Метрики якості
| Умова | Recall мета | Precision мета |
|---|---|---|
| День | >98% | >90% |
| Ніч (ІЧ) | >88% | >78% |
| Дощ | >92% | >82% |
З практики: автономний навантажувач на складі
Клієнт — логістична компанія, склад 15 тис. м². Вимагалася зупинка при появі людини в радіусі 3 м. Використали YOLOv8n + TensorRT INT8 на Jetson Orin NX (latency 18ms). Recall на тестовому наборі — 99.1%, 0 пропусків. FAR — 2–3 хибні спрацювання за зміну. Економія на тестуванні порівняно з традиційними методами — до 40%. Зв'яжіться з нами, щоб обговорити аналогічний сценарій.
Процес роботи
- Аналітика та збір даних (1000+ кадрів на сценарій)
- Розмітка та аугментація (дощ, ніч, відблиски)
- Навчання з валідацією на hold-out
- Оптимізація інференсу (INT8, TensorRT, pruning)
- Інтеграція на борт (ROS 2 / CAN bus)
- Валідація на маршрутах (детальний log)
Терміни та вартість
| Тип системи | Термін |
|---|---|
| Базовий детектор | 4–7 тижнів |
| З нічною детекцією | 8–14 тижнів |
| Fusion RGB+тепло | 4–8 місяців |
Вартість розраховується індивідуально під сценарій. Бюджет проєкту визначається на етапі аудиту. Отримайте консультацію з архітектури системи — це безкоштовно.
Що входить у результат
- Готова модель (TensorRT/ONNX)
- API та документація
- Навчання команди (2 дні)
- Підтримка пілоту (2 тижні)
Замовте пілотний проєкт для вашого сценарію — ми оцінимо умови та запропонуємо оптимальне рішення. Зв'яжіться з нами, щоб обговорити технічне завдання.







