AI-powered drone-based infrastructure inspection system
Inspecting high-voltage power lines, bridges, oil pipelines, and wind turbines can take days of manual labor by industrial climbers or even lead to equipment shutdowns. A drone equipped with AI analytics can complete the same route in hours, capturing defects that a human would miss during a cursory inspection.
Typical inspection tasks
| Object | Detectable defects | Method |
|---|---|---|
| Power lines, supports | Corrosion, tilt of the support, breakage | Segmentation + anomaly detection |
| Wind turbine blades | Cracks, delamination, ice build-up | High-resolution defect detection |
| Bridge, overpass | Cracks, spalling, corrosion of reinforcement | Crack detection + classification |
| Pipeline | Dents, corrosion spots, leaks (heat) | RGB + thermal imager |
| Roof of the building | Leaks (thermal anomalies), defects | Thermal imager |
Defect detection: crack detection as a basic task
import torch
import numpy as np
from PIL import Image
from torchvision import transforms
import segmentation_models_pytorch as smp
class InfrastructureDefectDetector:
def __init__(self, model_path: str, task: str = 'crack'):
# Для трещин — сегментационная задача (пиксельная точность)
# UNet++ с EfficientNet-B4 encoder = хорошее соотношение
self.model = smp.UnetPlusPlus(
encoder_name='efficientnet-b4',
encoder_weights=None, # загружаем свои веса
in_channels=3,
classes=1,
activation='sigmoid'
)
checkpoint = torch.load(model_path, map_location='cpu')
self.model.load_state_dict(checkpoint['model_state_dict'])
self.model.eval()
self.transform = transforms.Compose([
transforms.Resize((512, 512)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406],
[0.229, 0.224, 0.225])
])
self.task = task
@torch.no_grad()
def detect(self, image: np.ndarray,
threshold: float = 0.5) -> dict:
img_pil = Image.fromarray(image)
tensor = self.transform(img_pil).unsqueeze(0)
pred = self.model(tensor)[0, 0].numpy() # (H, W)
mask = (pred > threshold).astype(np.uint8)
# Анализ маски
crack_pixels = int(mask.sum())
total_pixels = mask.size
crack_ratio = crack_pixels / total_pixels
# Контуры трещин
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
crack_regions = []
for cnt in contours:
area = cv2.contourArea(cnt)
if area < 50: # фильтр шума
continue
x, y, w, h = cv2.boundingRect(cnt)
length = cv2.arcLength(cnt, False)
crack_regions.append({
'bbox': [x, y, x+w, y+h],
'area_px': int(area),
'length_px': float(length),
'severity': self._classify_severity(area, length)
})
return {
'defect_ratio': crack_ratio,
'crack_regions': crack_regions,
'severity': 'HIGH' if crack_ratio > 0.02 else
'MEDIUM' if crack_ratio > 0.005 else 'LOW',
'raw_mask': mask
}
def _classify_severity(self, area: float,
length: float) -> str:
if length > 200 or area > 500:
return 'CRITICAL'
elif length > 80 or area > 100:
return 'HIGH'
return 'MEDIUM'
Thermal imaging inspection: finding leaks and overheating
class ThermalInspector:
def __init__(self, baseline_temp: float = 20.0):
self.baseline = baseline_temp
def analyze(self, thermal_frame: np.ndarray) -> list[dict]:
"""
thermal_frame: матрица температур в °C
Ищем аномально горячие (короткое замыкание, трение) и холодные
(протечки, отсутствие изоляции) зоны.
"""
anomalies = []
# Статистика кадра
mean_t = float(np.mean(thermal_frame))
std_t = float(np.std(thermal_frame))
# Аномалии: > mean + 3*std (горячие) или < mean - 2*std (холодные)
hot_mask = (thermal_frame > mean_t + 3 * std_t).astype(np.uint8)
cold_mask = (thermal_frame < mean_t - 2 * std_t).astype(np.uint8)
for mask_type, mask in [('hot', hot_mask), ('cold', cold_mask)]:
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
if cv2.contourArea(cnt) < 20:
continue
x, y, w, h = cv2.boundingRect(cnt)
roi_temps = thermal_frame[y:y+h, x:x+w]
anomalies.append({
'type': mask_type,
'bbox': [x, y, x+w, y+h],
'max_temp': float(roi_temps.max()),
'min_temp': float(roi_temps.min()),
'delta': float(abs(roi_temps.mean() - mean_t))
})
return anomalies
Photogrammetry and 3D model of the object
For a detailed analysis of cracks and deformations, we construct a 3D model using a series of overlapping drone images. Tools used: Agisoft Metashape (commercial), OpenDroneMap (open-source), and COLMAP.
- Image overlap: 80% anterior-lateral, 60% lateral
- GSD (Ground Sample Distance) for cracks: 1–3 mm/pixel
- Drone with Sony RX1R II camera (42 MP): GSD 1 mm/pixel from a height of 8 m
Case: Inspection of 40 km of Power Lines
Task: Quarterly inspection of a 40-km high-voltage power line. Previously: 3 teams of 2 people, 5 working days.
After implementation: DJI M300 RTK drone + Zenmuse H20T (RGB 20MP + thermal imager), autonomous flight along a GPS route, altitude 30m above the wire.
- Data collection time: 6–7 hours per 40 km (2 days including relocations)
- AI analysis: YOLOv8l, retrained on 3200 images of defects in poles and wires
- Found during the first inspection: 14 supports with corrosion > 20%, 3 tension clamps with cracks, 8 abnormal thermal spots
| Type of inspection | Development period |
|---|---|
| Single type defect detector | 4–6 weeks |
| Integrated inspection system | 8–14 weeks |
| With photogrammetry and 3D reports | 12–20 weeks |







