Receber por email
← Voltar para o catálogo

defect-detection-ai

AI-powered construction defect detection using computer vision. Identify cracks, spalling, corrosion, and other defects in concrete, steel, and building components from images and video.

190estrelas
Atualizado há 8 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/defect-detection-ai/svg)](https://www.skillteca.com.br/skills/defect-detection-ai)
#ai

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

AI Defect Detection

Overview

This skill implements deep learning-based defect detection for construction quality control. Analyze images and video to automatically identify structural and surface defects, classify severity, and generate inspection reports.

Detectable Defects:

  • Concrete: Cracks, spalling, honeycombing, efflorescence
  • Steel: Corrosion, weld defects, deformation
  • Masonry: Mortar deterioration, displacement
  • Finishes: Surface defects, coating failures
  • MEP: Insulation damage, pipe corrosion

Quick Start

import torch
import torch.nn as nn
from torchvision import transforms, models
from PIL import Image
from dataclasses import dataclass
from typing import List, Dict, Tuple
from enum import Enum

class DefectType(Enum):
    CRACK = "crack"
    SPALLING = "spalling"
    CORROSION = "corrosion"
    HONEYCOMBING = "honeycombing"
    EFFLORESCENCE = "efflorescence"
    DEFORMATION = "deformation"
    SURFACE_DAMAGE = "surface_damage"
    NO_DEFECT = "no_defect"

class SeverityLevel(Enum):
    MINOR = "minor"
    MODERATE = "moderate"
    SEVERE = "severe"
    CRITICAL = "critical"

@dataclass
class DefectDetection:
    defect_type: DefectType
    confidence: float
    severity: SeverityLevel
    bounding_box: Tuple[int, int, int, int]  # x1, y1, x2, y2
    area_ratio: float  # Defect area as ratio of image

# Simple classifier using pretrained model
class SimpleDefectClassifier:
    def __init__(self, num_classes: int = 8):
        self.model = models.resnet18(pretrained=True)
        self.model.fc = nn.Linear(self.model.fc.in_features, num_classes)
        self.model.eval()

        self.transform = transforms.Compose([
            transforms.Resize((224, 224)),
            transforms.ToTensor(),
            transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ])

        self.classes = list(DefectType)

    def predict(self, image_path: str) -> DefectDetection:
        """Classify defect in image"""
        image = Image.open(image_path).convert('RGB')
        input_tensor = self.transform(image).unsqueeze(0)

        with torch.no_grad():
            outputs = self.model(input_tensor)
            probs = torch.softmax(outputs, dim=1)
            confidence, predicted = torch.max(probs, 1)

        defect_type = self.classes[predicted.item()]

        return DefectDetection(
            defect_type=defect_type,
            confidence=confidence.item(),
            severity=self._estimate_severity(confidence.item()),
            bounding_box=(0, 0, image.width, image.height),
            area_ratio=1.0
        )

    def _estimate_severity(self, confidence: float) -> SeverityLevel:
        if confidence > 0.9:
            return SeverityLevel.CRITICAL
        elif confidence > 0.7:
            return SeverityLevel.SEVERE
        elif confidence > 0.5:
            return SeverityLevel.MODERATE
        else:
            return SeverityLevel.MINOR

# Usage
classifier = SimpleDefectClassifier()
# result = classifier.predict("concrete_image.jpg")
# print(f"Defect: {result.defect_type.value}, Confidence: {result.confidence:.2%}")

Comprehensive Defect Detection System

Object Detection Model

import torch
import torch.nn as nn
from torchvision import transforms
from torchvision.models.detection import fasterrcnn_resnet50_fpn
from PIL import Image
import numpy as np
from dataclasses import dataclass, field
from typing import List, Dict, Tuple, Optional
from datetime import datetime
import json

@dataclass
class BoundingBox:
    x1: int
    y1: int
    x2: int
    y2: int

    @property
    def width(self) -> int:
        return self.x2 - self.x1

    @property
    def height(self) -> int:
        return self.y2 - self.y1

    @property
    def area(self) -> int:
        return self.width * self.height

    @property
    def center(self) -> Tuple[int, int]:
        return ((self.x1 + self.x2) // 2, (self.y1 + self.y2) // 2)

@dataclass
class DetectedDefect:
    defect_id: str
    defect_type: DefectType
    confidence: float
    severity: SeverityLevel
    bounding_box: BoundingBox
    area_sqm: Optional[float] = None
    dimensions_mm: Optional[Tuple[float, float]] = None
    metadata: Dict = field(default_factory=dict)

@dataclass
class InspectionResult:
    inspection_id: str
    image_path: str
    timestamp: datetime
    location: str
    element_type: str
    defects: List[DetectedDefect]
    overall_condition: str
    recommended_actions: List[str]

class DefectDetectionModel:
    """Deep learning defect detection with object detection"""

    DEFECT_CLASSES = {
        1: DefectType.CRACK,
        2: DefectType.SPALLING,
        3: DefectType.CORROSION,
        4: DefectType.HONEYCOMBING,
        5: DefectType.EFFLORESCENCE,
        6: DefectType.DEFORMATION,
        7: DefectType.SURFACE_DAMAGE
    }

    def __init__(self, model_path: str = None, device: str = 'cpu'):
        self.device = torch.device(device)

        # Initialize Faster R-CNN
        self.model = fasterrcnn_resnet50_fpn(pretrained=True)

        # Modify for our classes
        num_classes = len(self.DEFECT_CLASSES) + 1  # +1 for background
        in_features = self.model.roi_heads.box_predictor.cls_score.in_features
        self.model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)

        if model_path:
            self.model.load_state_dict(torch.load(model_path, map_location=self.device))

        self.model.to(self.device)
        self.model.eval()

        self.transform = transforms.Compose([
            transforms.ToTensor()
        ])

    def detect(self, image_path: str, confidence_threshold: float = 0.5,
               pixels_per_mm: float = None) -> List[DetectedDefect]:
        """Detect defects in image"""
        image = Image.open(image_path).convert('RGB')
        image_tensor = self.transform(image).to(self.device)

        with torch.no_grad():
            predictions = self.model([image_tensor])

        pred = predictions[0]
        defects = []

        for i in range(len(pred['boxes'])):
            score = pred['scores'][i].item()

            if score < confidence_threshold:
                continue

            label = pred['labels'][i].item()
            box = pred['boxes'][i].cpu().numpy()

            defect_type = self.DEFECT_CLASSES.get(label, DefectType.SURFACE_DAMAGE)

            bbox = BoundingBox(
                x1=int(box[0]),
                y1=int(box[1]),
                x2=int(box[2]),
                y2=int(box[3])
            )

            # Calculate dimensions if scale provided
            dimensions_mm = None
            if pixels_per_mm:
                width_mm = bbox.width / pixels_per_mm
                height_mm = bbox.height / pixels_per_mm
                dimensions_mm = (width_mm, height_mm)

            severity = self._classify_severity(defect_type, bbox, image.size)

            defects.append(DetectedDefect(
                defect_id=f"DEF-{i:04d}",
                defect_type=defect_type,
                confidence=score,
                severity=severity,
                bounding_box=bbox,
                dimensions_mm=dimensions_mm
            ))

        return defects

    def _classify_severity(self, defect_type: DefectType,
                          bbox: BoundingBox,
                          image_size: Tuple[int, int]) -> SeverityLevel:
        """Classify defect severity based on type and size"""
        image_area = image_size[0] * image_size[1]
        defect_ratio = bbox.area / image_area

        # Severity thresholds by defect type
        thresholds = {
            DefectType.CRACK: {'critical': 0.1, 'severe': 0.05, 'moderate': 0.02},
            DefectType.SPALLING: {'critical': 0.15, 'severe': 0.08, 'moderate': 0.03},
            DefectType.CORROSION: {'critical': 0.2, 'severe': 0.1, 'moderate': 0.05},
            DefectType.HONEYCOMBING: {'critical': 0.1, 'severe': 0.05, 'moderate': 0.02},
     
Compartilhar X LinkedIn