Розробка AI-системи автоматичної інспекції дорожнього покриття

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1566 послуг
Розробка AI-системи автоматичної інспекції дорожнього покриття
Середній
~1-2 тижні
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1284
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1196
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    901
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

AI-система інспекції дорожнього покриття

Ями, тріщини, вибоїни - щорічні витрати на їхнє усунення обчислюються мільярдами. Проблема в тому, що на момент візуального виявлення дорожнім робітникам, дефект уже перейшов у критичну стадію. AI-інспекція з камер транспортних засобів або спеціальних машин дозволяє виявляти ранні ознаки деградації покриття та пріоритизувати ремонт.

Класифікація дефектів дорожнього покриття

Стандарт ASTM D6433 виділяє 20 типів дистресу. На практиці працюємо з 7-8 ключовими:

Тип дефекту Метод виявлення Складність
Ями (potholes) Object detection (bbox) Середня
Поздовжні тріщини Segmentation Висока
Поперечні тріщини Segmentation Середня
Сітчасті тріщини (alligator) Texture classification Висока
Колійність (rutting) 3D профіль / stereo Дуже висока
Вибоїни (raveling) Texture + anomaly Середня
Просідання (depression) 3D профіль Висока

Модель детекції та сегментації

import torch
import numpy as np
import segmentation_models_pytorch as smp
from ultralytics import YOLO
import cv2

class PavementInspector:
    def __init__(self, seg_model_path: str, det_model_path: str):
        # Сегментация трещин: UNet++ с ResNet50 энкодером
        # Дообучен на RDD2022 (Road Damage Dataset, 47k изображений)
        self.seg_model = smp.UnetPlusPlus(
            encoder_name='resnet50',
            encoder_weights=None,
            in_channels=3,
            classes=4,  # background, longitudinal, transverse, alligator
        )
        seg_ckpt = torch.load(seg_model_path)
        self.seg_model.load_state_dict(seg_ckpt)
        self.seg_model.eval()

        # YOLOv8m для ям и выбоин (bbox достаточно)
        self.det_model = YOLO(det_model_path)

        # Маппинг классов сегментации
        self.seg_classes = {
            0: 'background',
            1: 'longitudinal_crack',
            2: 'transverse_crack',
            3: 'alligator_crack'
        }

        # Маппинг для оценки тяжести (PCI-based)
        self.severity_thresholds = {
            'pothole': {'low': 0.01, 'medium': 0.05},    # % площади кадра
            'crack': {'low': 0.02, 'medium': 0.08}
        }

    @torch.no_grad()
    def inspect(self, frame: np.ndarray) -> dict:
        h, w = frame.shape[:2]

        # 1. Сегментация трещин
        input_tensor = self._preprocess(frame)
        seg_output = self.seg_model(input_tensor)
        seg_mask = seg_output.argmax(dim=1)[0].numpy()

        crack_analysis = self._analyze_cracks(seg_mask, w * h)

        # 2. Детекция ям
        det_results = self.det_model(frame, conf=0.45)
        potholes = self._analyze_potholes(det_results, w * h)

        # 3. Индекс состояния покрытия (упрощённый PCI)
        pci = self._compute_pci(crack_analysis, potholes)

        return {
            'crack_analysis': crack_analysis,
            'potholes': potholes,
            'pci_score': pci,
            'condition': self._pci_to_condition(pci),
            'seg_mask': seg_mask
        }

    def _analyze_cracks(self, mask: np.ndarray,
                          total_pixels: int) -> dict:
        analysis = {}
        for cls_id, cls_name in self.seg_classes.items():
            if cls_id == 0:
                continue
            crack_pixels = int((mask == cls_id).sum())
            ratio = crack_pixels / total_pixels
            analysis[cls_name] = {
                'pixel_count': crack_pixels,
                'area_ratio': ratio,
                'severity': 'high' if ratio > 0.08 else
                             'medium' if ratio > 0.02 else 'low'
            }
        return analysis

    def _compute_pci(self, cracks: dict, potholes: list) -> float:
        """
        PCI 0–100: 100 = идеальное покрытие, 0 = полная деградация.
        Упрощённая формула на основе ASTM D6433.
        """
        deduct = 0.0
        for crack_type, data in cracks.items():
            ratio = data['area_ratio']
            if ratio > 0.08:
                deduct += 25
            elif ratio > 0.02:
                deduct += 12
            elif ratio > 0.005:
                deduct += 5

        for pothole in potholes:
            area = pothole['area_ratio']
            if area > 0.03:
                deduct += 30
            elif area > 0.01:
                deduct += 15

        return max(0, 100 - deduct)

    def _pci_to_condition(self, pci: float) -> str:
        if pci >= 85:   return 'excellent'
        elif pci >= 70: return 'good'
        elif pci >= 55: return 'fair'
        elif pci >= 40: return 'poor'
        elif pci >= 25: return 'very_poor'
        else:           return 'failed'

Мобільна інспекція: камера на транспортному засобі

Для доріг загального користування камера під переднім бампером або в решітці радіатора, запис зі швидкістю 25fps, прив'язка до GPS. Додатково акселерометр для автоматичної фіксації ям по вібрації.

class MobileRoadSurvey:
    def __init__(self, gps_logger, inspector: PavementInspector):
        self.gps = gps_logger
        self.inspector = inspector
        self.survey_log = []

    def process_frame_with_geotagging(self, frame: np.ndarray,
                                       timestamp: float) -> dict:
        gps_coords = self.gps.get_coords(timestamp)
        results = self.inspector.inspect(frame)

        record = {
            'timestamp': timestamp,
            'lat': gps_coords['lat'],
            'lon': gps_coords['lon'],
            'pci': results['pci_score'],
            'condition': results['condition'],
            'defects': results
        }
        self.survey_log.append(record)
        return record

Кейс: інспекція 120 км доріг міста

Завдання: пріоритизація дорожнього ремонту. Інструмент: Ford Transit з 4 камерами (перед + 2 борти + зад), GPS RTK. За 3 дні зйомки вкрито 120 км.

  • оброблено: 1.2 млн кадрів
  • Виявлено: 3400 ям (P > 0.5), 47 км тріщин (сегментація)
  • З них критичних (PCI < 25): 8.2 км - першочерговий ремонт
  • Економія порівняно з ручним обстеженням: 12 робочих днів → 6 годин обробки + 3 години верифікації
Тип проекту Термін
Детектор ям (базовий) 3-5 тижнів
Повна інспекційна система (+ тріщини, PCI) 7–12 тижнів
Мобільна система з GIS-інтеграцією 10-16 тижнів