Реализация AI-распознавания повреждений автомобиля по фото в мобильном приложении
Страховой инспектор фотографирует повреждённый автомобиль — AI за секунды локализует царапины, вмятины и трещины на изображении. Это не просто «нашли и обвели»: чтобы результат был принят страховой компанией, система должна давать воспроизводимые, аргументированные результаты, устойчивые к попыткам мошенничества.
Задача: детекция, сегментация и классификация
Три уровня анализа повреждений:
Детекция — bounding box вокруг повреждения. YOLOv8 или RT-DETR справляются хорошо, если обучены на соответствующем датасете (CarDD, COCO-format разметка с 6–8 классами: scratch, dent, crack, broken_glass, paint_damage, deformation, missing_part).
Сегментация — попиксельная маска повреждения. Instance segmentation даёт площадь в пикселях → при известном масштабе → площадь в см². YOLOv8-seg, Mask R-CNN.
Классификация серьёзности — surface scratch, deep scratch, dent, structural damage. От неё зависит ремонтный сценарий (полировка, кузовной ремонт, замена).
// iOS: запрос к backend для анализа повреждений
struct DamageAnalysisRequest: Codable {
let imageBase64: String
let vehicleInfo: VehicleInfo? // марка, модель, год — для контекста
let captureMetadata: CaptureMetadata
}
struct CaptureMetadata: Codable {
let angle: CaptureAngle // front, rear, side_left, side_right, roof
let lightingCondition: String // auto-detected
let gpsCoordinates: CLLocationCoordinate2D?
let timestamp: Date
let deviceModel: String
}
Метаданные съёмки — не опциональная деталь для страхового контекста. Геолокация и временная метка создают цифровой след, который затрудняет подачу старых повреждений как новых.
Протокол многоракурсной съёмки
Одного фото недостаточно для полной оценки ущерба. Правильная реализация — guided photo flow:
enum DamageInspectionStep: CaseIterable {
case overview_front // общий вид спереди
case overview_rear // общий вид сзади
case overview_side_left // левая сторона
case overview_side_right // правая сторона
case damage_closeup_1 // крупный план #1 (пользователь указывает зону)
case damage_closeup_2 // крупный план #2
case odometer // пробег
case vin // VIN-номер
var instruction: String { /* ... */ }
var requiredDistance: DistanceRange { /* approx 2m, 0.3m, etc */ }
}
AR-оверлей показывает, где стоять и какую зону снимать — через ARKit/ARCore позиционирование. Это уменьшает процент повторных съёмок из-за неправильного ракурса.
Детекция попыток манипуляции
Страховое мошенничество — реальная проблема. Несколько проверок на уровне приложения:
struct AntifraudChecks {
// 1. Метаданные EXIF: фото должно быть сделано сейчас, не из галереи
func isLiveCapture(_ image: UIImage) -> Bool {
guard let exifData = image.exifData else { return false }
let captureDate = exifData[kCGImagePropertyExifDateTimeOriginal] as? String
return isWithinLastMinutes(captureDate, minutes: 5)
}
// 2. Проверка GPS: координаты должны совпадать с заявленным местом ДТП
func isLocationConsistent(_ metadata: CaptureMetadata, claimedLocation: CLLocation) -> Bool {
guard let gps = metadata.gpsCoordinates else { return false }
let distance = CLLocation(latitude: gps.latitude, longitude: gps.longitude)
.distance(from: claimedLocation)
return distance < 500 // допуск 500м
}
// 3. Детекция фото фото (фото экрана с чужим повреждением)
func isScreenPhoto(_ image: UIImage) -> Bool {
// Анализ моаре-паттернов и пиксельной сетки экрана
return moareDetector.detect(image) > 0.7
}
}
Backend: детекция повреждений
На сервере модель детекции работает на GPU. Для продакшн-нагрузки — TorchServe или Triton Inference Server.
# YOLOv8-seg inference для повреждений
from ultralytics import YOLO
model = YOLO("car_damage_seg_v8x.pt") # x-variant для максимальной точности
def analyze_damage(image_path: str) -> DamageReport:
results = model.predict(
image_path,
conf=0.25, # нижний порог confidence
iou=0.45, # NMS threshold
imgsz=1280, # высокое разрешение важно для мелких царапин
retina_masks=True # высокоточные маски
)
detections = []
for result in results[0].boxes:
mask = results[0].masks[i] if results[0].masks else None
detections.append(DamageDetection(
class_name=model.names[int(result.cls)],
confidence=float(result.conf),
bbox=result.xyxy[0].tolist(),
mask_area_px=mask.area if mask else None,
severity=classify_severity(result.cls, result.conf)
))
return DamageReport(
detections=detections,
overall_severity=aggregate_severity(detections),
processing_time_ms=results[0].speed["inference"]
)
imgsz=1280 вместо дефолтного 640 принципиально для мелких царапин (2–5 мм на фото). На дефолтном разрешении поверхностные царапины детектируются примерно в 40% случаев, на 1280 — в 75%+.
Визуализация результатов
// Android: overlay повреждений на фото
@Composable
fun DamageAnnotationView(
image: ImageBitmap,
detections: List<DamageDetection>
) {
Box {
Image(bitmap = image, contentDescription = null)
Canvas(modifier = Modifier.matchParentSize()) {
detections.forEach { detection ->
// Bounding box с цветом по серьёзности
val color = when (detection.severity) {
Severity.MINOR -> Color(0xFF4CAF50)
Severity.MODERATE -> Color(0xFFFFC107)
Severity.MAJOR -> Color(0xFFFF5722)
Severity.STRUCTURAL -> Color(0xFFD32F2F)
}
drawRect(
color = color,
topLeft = detection.bbox.topLeft(size),
size = detection.bbox.size(size),
style = Stroke(width = 3f)
)
// Лейбл с классом и confidence
drawDamageLabel(detection, color)
}
}
}
}
Ориентиры по срокам
Backend с YOLOv8 детекцией и базовым мобильным клиентом — 2–3 недели. Полная система с guided photo flow, AR-позиционированием, антифрод проверками, сегментацией, оценкой площади повреждений, интеграцией с CRM страховщика и поддержкой iOS + Android — 1–3 месяца в зависимости от требований к интеграции.







