Back to guides
2
8-9 min

Fabric Defect Detection

YOLOv8 Vision Systems, Loom Vibration Analytics, and 4-Point Grading Automation

The Cost of a Missed Defect

In Tirupur's knit fabric export ecosystem, a single contaminated roll reaching the cutting table wastes not just the fabric but the cutting marker — sometimes 800–1,200 metres of laid fabric from a complex multi-style marker. The defect detection window is narrow: inline on the loom or circular knitting machine, at the inspection table after greige fabric exit, and again post-process at the finished goods stage. AI vision systems intervening at the first window eliminate the downstream cascade. This chapter builds the detection pipeline from sensor placement through inference architecture to 4-point grading automation.

Open data/fabric-defect-images/ in the code panel. It contains 3,200 annotated images from a Surat weaving mill — warp breaks, weft drops, float picks, reed marks, and oil stains — exported as a COCO-format JSON alongside the raw 4K frames at 30 fps from the loom-mounted camera rig.

Defect Taxonomy for Woven and Knit Fabrics

Vision models need per-class training data, and class imbalance is severe in defect datasets — clean fabric is 98–99% of production. Understanding which defect types matter most per fabric construction:

Defect TypeConstructionRoot Cause4-Point Penalty
Warp breakWovenWeak yarn lot, incorrect sizing2–4 pts depending on length
Weft drop / missing pickWovenWeft feeder jam, stop-motion failure2–4 pts
Float / float pattern errorWoven (dobby/jacquard)Harness misread, broken heddle4 pts (pattern critical)
Reed markWovenBent reed dent, improper sett1–2 pts
Hole / needle breakKnitBroken latch needle, sinker failure4 pts (any size)
Drop stitchKnitYarn tension variation, cam wear2–3 pts
Lycra run-outKnitCore-spun yarn break4 pts if > 25 cm
Patta (streak)BothSliver thick/thin, creel tension1–2 pts per cm width
Oil stainBothMachine lubrication fault2–4 pts depending on size

The 4-point grading system (ASTM D5430) caps penalty at 4 points per linear yard regardless of defect count. The accept/reject threshold is typically 40 points per 100 linear yards for export quality. Automating this grading reduces inspector subjectivity and creates a traceable audit trail.

YOLOv8 Deployment Architecture

Camera Rig and Lighting

Detection accuracy depends heavily on the imaging setup before any model training:

  • Line scan vs. area scan: Line scan cameras (Basler raL2048) capture fabric continuously at loom speed without motion blur. Area scan cameras at 30–60 fps work for post-weave inspection tables at 20–40 m/min fabric speed.
  • Dark-field illumination: For surface defects (pilling, neps, reed marks), dark-field (oblique) lighting at 15–20° angle creates high contrast. Transmitted light works for structural defects (holes, missing picks) in lighter fabrics.
  • Resolution requirement: 0.1 mm/pixel minimum to detect single broken filament in a filament fabric. For cotton woven, 0.2 mm/pixel is sufficient.
  • Model Training Pipeline

    from ultralytics import YOLO
    import yaml
    
    # Dataset config — COCO-format annotations from data/fabric-defect-images/
    dataset_config = {
        "path": "data/fabric-defect-images",
        "train": "images/train",
        "val": "images/val",
        "nc": 9,  # defect classes per taxonomy above
        "names": ["warp_break", "weft_drop", "float", "reed_mark",
                  "hole", "drop_stitch", "lycra_runout", "patta", "oil_stain"]
    }
    
    with open("defect_dataset.yaml", "w") as f:
        yaml.dump(dataset_config, f)
    
    # Fine-tune YOLOv8m on defect dataset
    model = YOLO("yolov8m.pt")  # medium: 25M params, 640px input
    results = model.train(
        data="defect_dataset.yaml",
        epochs=150,
        imgsz=640,
        batch=16,
        patience=20,           # early stopping
        augment=True,
        hsv_h=0.015,           # hue aug: minimal — colour shifts confuse defect vs. design
        hsv_s=0.4,
        degrees=0,             # no rotation — fabric orientation is fixed
        flipud=0.0,            # no vertical flip — warp/weft direction matters
        fliplr=0.5,            # horizontal flip is safe
        mosaic=0.5,
    )

    Handling Class Imbalance

    With 98% clean fabric, naive training produces a model that never detects defects (high accuracy, zero recall). Countermeasures:

  • Focal loss (already default in YOLOv8) down-weights easy negatives.
  • Oversampling defect patches: Extract 640×640 crops centred on annotated defects; augment each 8–12× with brightness, blur, and affine transforms.
  • Hard negative mining: After initial training, run inference on clean fabric rolls and add false-positive crops to the negative training set.
  • Class weights in loss: Set weights inversely proportional to class frequency — hole (rare, high cost) gets 3× weight vs. reed_mark (common, lower cost).
  • Loom Vibration Monitoring for Predictive Defect Onset

    Defects often have mechanical precursors. A reed that develops a bent dent produces increasing reed-mark density over 2–4 hours before the mark becomes fully visible. Vibration signatures from accelerometers mounted on the loom breast beam detect these mechanical anomalies before they manifest as visible defects.

    Open data/loom-vibration-log.csv for 30 days of 3-axis accelerometer data (1 kHz sampling) from 12 rapier looms at a Bhilwara suiting mill, annotated with the timestamp of each quality intervention.

    Vibration Feature Extraction

    import numpy as np
    from scipy import signal
    
    def extract_vibration_features(accel_window: np.ndarray, fs: int = 1000) -> dict:
        """
        accel_window: (N, 3) array of x, y, z acceleration (g)
        fs: sampling frequency in Hz
        Returns dict of spectral and statistical features per axis
        """
        features = {}
        for i, axis in enumerate(["x", "y", "z"]):
            a = accel_window[:, i]
            # RMS
            features[f"{axis}_rms"] = float(np.sqrt(np.mean(a**2)))
            # Peak-to-peak
            features[f"{axis}_pp"] = float(np.ptp(a))
            # Spectral centroid
            freqs, psd = signal.welch(a, fs=fs, nperseg=256)
            features[f"{axis}_spectral_centroid"] = float(
                np.sum(freqs * psd) / np.sum(psd)
            )
            # Energy in loom beat-up frequency band (typically 4–8 Hz for rapier)
            mask = (freqs >= 4) & (freqs <= 8)
            features[f"{axis}_beatup_energy"] = float(np.trapz(psd[mask], freqs[mask]))
        return features

    An LSTM trained on rolling 10-minute vibration windows with binary labels (intervention in next 60 minutes: yes/no) achieves AUC ~0.82 on the Bhilwara dataset — enough to trigger a preventive maintenance alert 45–60 minutes before a defect pattern emerges.

    Knitting Defect Classification in Tirupur

    Tirupur processes ~900 metric tonnes of knit fabric per day. Circular knitting machines (Mayer & Cie, Fukuhara) run at 25–40 RPM with 1,800–3,600 needles per cylinder. Camera systems mounted above the fabric take-down roller capture a ring of fabric every machine revolution.

    Prompt: "I have a knitting defect detection model deployed on a 30-inch diameter, 2,400-needle
    circular knitting machine running Ne 40s combed cotton at 30 RPM. The camera captures a 180mm ×
    80mm fabric patch per revolution at 1080p. My current model (YOLOv8n) has 94% precision but
    72% recall on drop-stitch defects. The false negatives cluster around course 18–22 in the
    fabric (roughly 60% of the way across the camera FOV). Diagnose 3 likely causes for this
    localised recall drop and propose concrete remediation steps for each."

    Automated 4-Point Grading Integration

    Once the vision model produces bounding boxes with class and confidence, the grading engine applies ASTM D5430 rules:

    from dataclasses import dataclass, field
    
    @dataclass
    class FabricRoll:
        roll_id: str
        total_length_yards: float
        width_inches: float
        detections: list[dict] = field(default_factory=list)  # [{class, x_yard, y_inch, length_cm, width_cm, conf}]
    
    FOUR_POINT_PENALTIES = {
        "warp_break":    lambda l_cm: 2 if l_cm <= 23 else (3 if l_cm <= 46 else 4),
        "weft_drop":     lambda l_cm: 2 if l_cm <= 23 else (3 if l_cm <= 46 else 4),
        "float":         lambda l_cm: 4,  # pattern-critical: always max
        "reed_mark":     lambda l_cm: 1 if l_cm <= 10 else 2,
        "hole":          lambda l_cm: 4,
        "drop_stitch":   lambda l_cm: 2 if l_cm <= 10 else 3,
        "lycra_runout":  lambda l_cm: 2 if l_cm <= 25 else 4,
        "patta":         lambda l_cm: 1 if l_cm <= 10 else 2,
        "oil_stain":     lambda l_cm: 2 if l_cm <= 6 else 4,
    }
    
    def score_roll(roll: FabricRoll, threshold_per_100yd: int = 40) -> dict:
        total_points = 0
        per_yard: dict[int, int] = {}
        for det in roll.detections:
            yard_idx = int(det["x_yard"])
            penalty_fn = FOUR_POINT_PENALTIES.get(det["class"], lambda l: 2)
            pts = penalty_fn(det.get("length_cm", 10))
            pts = min(pts, 4)  # cap per defect
            yard_pts = per_yard.get(yard_idx, 0)
            if yard_pts < 4:  # cap per yard
                pts = min(pts, 4 - yard_pts)
                per_yard[yard_idx] = yard_pts + pts
                total_points += pts
    
        points_per_100yd = (total_points / roll.total_length_yards) * 100
        return {
            "roll_id": roll.roll_id,
            "total_points": total_points,
            "points_per_100yd": round(points_per_100yd, 1),
            "grade": "A" if points_per_100yd <= 20 else ("B" if points_per_100yd <= 40 else "C"),
            "pass": points_per_100yd <= threshold_per_100yd,
        }

    Mill-Level Deployment Notes

    Surat weaving mills running filament polyester and viscose need illumination tuned to filament sheen — specular reflection from flat-weave satin constructions creates false positives. A polarising filter on the lens combined with a cross-polarised light source eliminates the glare problem.

    Tirupur knit exporters face a different challenge: frequent style changeovers mean the defect appearance changes with yarn count and stitch density. Transfer learning from a base defect model, fine-tuned with 200–300 images per new style, reduces per-style data collection from weeks to 2–3 days.

    SITRA (South India Textile Research Association) in Coimbatore operates a shared defect image library for member mills — a resource that reduces individual annotation burden significantly for smaller Tirupur units running < 50 machines.

    Key Takeaways

  • Lighting and optics come before model architecture. A correctly set up dark-field line scan rig with a YOLOv8n model beats a poorly lit rig with YOLOv8x.
  • Class imbalance is the primary modelling challenge — oversampling defect patches and hard negative mining are both required, not optional.
  • Vibration monitoring adds a predictive layer that visible-defect detection alone cannot provide — a 45-minute advance warning changes the economics of preventive maintenance.
  • 4-point grading automation creates traceable, buyer-auditable quality records — critical for Tirupur exporters under GOTS and OEKO-TEX buyer scrutiny.
  • Style changeover is a deployment challenge — transfer learning with 200–300 images per style makes Tirupur's high-mix production tractable.
  • This is chapter 2 of AI for Textile & Apparel.

    Get the full hands-on course — free during early access. Build the complete system. Your projects become your portfolio.

    View course details