织物缺陷检测:基于OpenCV与深度学习的纺织品质量控制

0 阅读8分钟

核心软硬件配置

硬件设备

  • 线扫相机

  • LED照明设备

  • 工业计算机

  • 输送系统

软件栈

Python、OpenCV、YOLO、TensorFlow、PyTorch

适用场景

纺织品制造、织物检测、机织质量控制、针织质量控制

引言

纺织品制造的生产速度极快,人工检测几乎无法实现。即使是经验丰富的检测人员,也会因疲劳、检测速度和缺陷特征不明显等因素,遗漏15%-25%的缺陷。

基于计算机视觉的自动化视觉检测技术能识别更多缺陷,保证检测一致性,还能实现实时质量控制。本指南将介绍从基础OpenCV技术到工业级深度学习系统的各类缺陷检测方法。

常见织物缺陷

机织缺陷

缺陷类型缺陷描述视觉特征
断经纵向纱线缺失纵向线条/缝隙
断纬横向纱线缺失横向线条/缝隙
缺纬漏插纬纱细横向条纹
浮线纱线错搭纱线翘起/松弛
筘痕打纬不均竖向条纹图案
边撑痕边缘张力异常边缘变形

针织缺陷

缺陷类型缺陷描述视觉特征
漏针线圈缺失破洞/梯状纹路
勾丝纱线被扯起表面形成线圈
横档条纹图案异常横向色带
针路织针故障纵向线条
破洞多处线圈脱落明显缝隙

表面缺陷

缺陷类型缺陷描述检测难点
污渍织物变色颜色分析
油渍设备污染附着纹理变化识别
杂质/异物外部污染物颜色与纹理双重分析
折痕织物折印阴影与纹理识别
起球表面形成毛球纹理分析

成像系统搭建

相机选型

  1. 线扫相机(生产推荐)

    • 逐行采集图像

    • 超高分辨率(4K-16K像素宽度)

    • 适用于连续织物幅面检测

    • 需与织物运行速度精准同步

  2. 面扫相机(原型开发适用)

    • 标准帧式采集

    • 搭建难度低

    • 高速度下易遗漏帧间缺陷

    • 适合学习与开发阶段使用

分辨率要求

基本原则:最小缺陷维度至少对应3-5个像素。

缺陷尺寸1米幅宽所需分辨率
1mm3000-5000像素/米
0.5mm6000-10000像素/米
0.25mm12000-20000像素/米

照明方式

1. 透射光(背光源)


   [相机]

      ↓

═══════════════  ← 织物

      ↑

   [光源]

  • 最适用于破洞检测

  • 可清晰显示纱线密度变化

  • 要求织物具备透光性

2. 正面光


   [光源] [相机] [光源]

      ↘      ↓      ↙

═══════════════════════════  ← 织物

  • 可检测表面缺陷

  • 适用于颜色与污渍检测

  • 适配所有类型织物

3. 斜射光/掠射光


                [相机][光源]→  ═══════════════════  ← 织物

  • 突出纹理类缺陷

  • 可显示机织结构不规则问题

  • 适用于起球检测

传统计算机视觉方法

基于Gabor滤波器的纹理分析

Gabor滤波器非常适合检测重复纹理中的结构性缺陷。


import cv2

import numpy as np

def create_gabor_filters(num_orientations=8, wavelengths=[4, 8, 16]):

    """

    构建用于纹理分析的Gabor滤波器组

    """

    filters = []

    for wavelength in wavelengths:

        for i in range(num_orientations):

            theta = i * np.pi / num_orientations

            kernel = cv2.getGaborKernel(

                ksize=(31, 31),

                sigma=4.0,

                theta=theta,

                lambd=wavelength,

                gamma=0.5,

                psi=0

            )

            filters.append(kernel)

    return filters

def apply_gabor_filters(image, filters):

    """

    应用Gabor滤波器组并返回响应结果

    """

    responses = []

    for kernel in filters:

        filtered = cv2.filter2D(image, cv2.CV_64F, kernel)

        responses.append(filtered)

    return responses

def detect_texture_defects(image, filters, threshold_factor=2.5):

    """

    基于正常纹理响应的偏差检测缺陷

    """

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) == 3 else image

    # 获取Gabor滤波器响应

    responses = apply_gabor_filters(gray, filters)

    # 融合响应结果

    combined = np.zeros_like(gray, dtype=np.float64)

    for response in responses:

        combined += np.abs(response)

    # 归一化处理

    combined = combined / len(responses)

    # 识别异常区域(与均值的偏差)

    mean_response = np.mean(combined)

    std_response = np.std(combined)

    # 缺陷阈值筛选

    defect_mask = np.abs(combined - mean_response) > (threshold_factor * std_response)

    return defect_mask.astype(np.uint8) * 255

基于傅里叶分析的周期性图案检测

织物具有规则的周期性结构,缺陷会破坏该结构特征。


def detect_periodic_defects(image, sensitivity=0.3):

    """

    基于傅里叶分析检测缺陷

    适用于具有规则图案的机织织物

    """

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) == 3 else image

    gray = gray.astype(np.float32)

    # 计算快速傅里叶变换

    f = np.fft.fft2(gray)

    fshift = np.fft.fftshift(f)

    # 获取幅度谱

    magnitude = np.abs(fshift)

    # 识别主频率(织物图案特征,在频域表现为亮斑)

    mean_mag = np.mean(magnitude)

    pattern_mask = magnitude > (mean_mag * 10)

    # 去除图案频率(仅保留异常信息)

    fshift_filtered = fshift.copy()

    fshift_filtered[pattern_mask] = 0

    # 逆傅里叶变换

    f_ishift = np.fft.ifftshift(fshift_filtered)

    img_back = np.fft.ifft2(f_ishift)

    img_back = np.abs(img_back)

    # 阈值筛选缺陷

    threshold = np.mean(img_back) + sensitivity * np.std(img_back)

    defect_mask = img_back > threshold

    # 图像形态学处理

    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))

    defect_mask = cv2.morphologyEx(

        defect_mask.astype(np.uint8) * 255,

        cv2.MORPH_CLOSE, kernel

    )

    return defect_mask

破洞与缝隙检测

用于检测织物破洞和纱线缺失问题:


def detect_holes(image, min_area=50):

    """

    基于阈值分割和轮廓分析检测破洞

    搭配背光源使用效果最佳

    """

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) == 3 else image

    # 自适应阈值分割

    thresh = cv2.adaptiveThreshold(

        gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,

        cv2.THRESH_BINARY_INV, 11, 2

    )

    # 形态学运算

    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))

    thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

    thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

    # 查找轮廓

    contours, _ = cv2.findContours(

        thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE

    )

    holes = []

    for contour in contours:

        area = cv2.contourArea(contour)

        if area > min_area:

            x, y, w, h = cv2.boundingRect(contour)

            holes.append({

                '边界框': (x, y, w, h),

                '面积': area,

                '轮廓': contour,

                '类型': '破洞'

            })

    return holes

污渍与颜色缺陷检测


def detect_stains(image, reference_color=None, threshold=30):

    """

    基于与织物基准颜色的偏差检测污渍

    """

    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

    if reference_color is None:

        # 以中值作为基准颜色

        reference_color = np.median(hsv, axis=(0, 1))

    # 计算颜色距离

    diff = np.abs(hsv.astype(np.float32) - reference_color)

    # 通道加权(色相通道对污渍检测最重要)

    weights = [2.0, 1.0, 0.5]  # 色相、饱和度、明度

    weighted_diff = sum(diff[:,:,i] * weights[i] for i in range(3))

    # 阈值筛选

    stain_mask = weighted_diff > threshold

    # 图像形态学处理

    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))

    stain_mask = cv2.morphologyEx(

        stain_mask.astype(np.uint8) * 255,

        cv2.MORPH_CLOSE, kernel

    )

    stain_mask = cv2.morphologyEx(stain_mask, cv2.MORPH_OPEN, kernel)

    return stain_mask

深度学习方法

基于YOLO的缺陷检测

训练YOLO模型实现织物缺陷的检测与分类:


from ultralytics import YOLO

# 数据集配置

"""

# fabric_defects.yaml

path: /data/fabric_defects

train: images/train

val: images/val

names:

  0: 破洞

  1: 污渍

  2: 断纱

  3: 折痕

  4: 油渍

  5: 异物

  6: 起球

  7: 勾丝

"""

# 模型训练

model = YOLO('yolov8m.pt')

results = model.train(

    data='fabric_defects.yaml',

    epochs=200,

    imgsz=640,

    batch=16,

    augment=True,

    # 织物检测专属数据增强

    degrees=5,       # 小角度旋转

    translate=0.1,   # 平移

    scale=0.2,       # 缩放

    fliplr=0.5,      # 水平翻转

    flipud=0.0,      # 垂直翻转(对织物检测无明显帮助)

    mosaic=0.5       # 马赛克增强

)

分类网络

用于织物合格/不合格的二分类检测:


import torch

import torch.nn as nn

from torchvision import models, transforms

class FabricClassifier(nn.Module):

    def __init__(self, num_classes=8, pretrained=True):

        super().__init__()

        # 以EfficientNet为骨干网络

        self.backbone = models.efficientnet_b0(

            weights='DEFAULT' if pretrained else None

        )

        # 替换分类头

        in_features = self.backbone.classifier[1].in_features

        self.backbone.classifier = nn.Sequential(

            nn.Dropout(0.3),

            nn.Linear(in_features, 256),

            nn.ReLU(),

            nn.Dropout(0.2),

            nn.Linear(256, num_classes)

        )

    def forward(self, x):

        return self.backbone(x)

# 训练循环

def train_classifier(model, train_loader, val_loader, epochs=50):

    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    model = model.to(device)

    criterion = nn.CrossEntropyLoss()

    optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4)

    scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(

        optimizer, T_max=epochs

    )

    for epoch in range(epochs):

        model.train()

        for images, labels in train_loader:

            images, labels = images.to(device), labels.to(device)

            optimizer.zero_grad()

            outputs = model(images)

            loss = criterion(outputs, labels)

            loss.backward()

            optimizer.step()

        scheduler.step()

        # 模型验证

        model.eval()

        correct = 0

        total = 0

        with torch.no_grad():

            for images, labels in val_loader:

                images, labels = images.to(device), labels.to(device)

                outputs = model(images)

                _, predicted = torch.max(outputs, 1)

                total += labels.size(0)

                correct += (predicted == labels).sum().item()

        print(f'第{epoch+1}轮训练:验证集准确率 = {100*correct/total:.2f}%')

生产系统架构

在线检测系统


                    ┌───────────────┐

                    │    线扫相机    │

                    └───────┬───────┘


   ┌────────────────────────▼────────────────────────┐

───│═══════════════════════════════════════════════════│───

   │                   织物幅面                        │

───│═══════════════════════════════════════════════════│───

   └────────────────────────┬────────────────────────┘


                    ┌───────▼───────┐

                    │    LED灯条    │

                    └───────────────┘

                    ┌───────────────┐

                    │    工业计算机  │

                    │    (分析端)  │

                    └───────┬───────┘


            ┌───────────────┼───────────────┐

            ▼               ▼               ▼

       ┌─────────┐    ┌─────────┐    ┌─────────┐

       │ 显示终端 │    │ 可编程控制器 │    │ 数据库  │

       │ (报警) │    │ (控制) │    │ (日志) │

       └─────────┘    └─────────┘    └─────────┘

速度同步


def calculate_scan_rate(fabric_speed_mpm, camera_resolution_px, width_mm):

    """

    计算相机所需扫描速率

    fabric_speed_mpm: 织物运行速度(米/分钟)

    camera_resolution_px: 相机像素宽度

    width_mm: 检测幅宽(毫米)

    """

    # 每毫米像素数

    px_per_mm = camera_resolution_px / width_mm

    # 织物运行速度(毫米/秒)

    speed_mmps = (fabric_speed_mpm * 1000) / 60

    # 所需扫描速率(行/秒)

    scan_rate = speed_mmps * px_per_mm

    return scan_rate

# 示例:

# 织物速度50米/分钟

# 相机分辨率8192像素

# 检测幅宽1600毫米

# 所需扫描速率:约4267行/秒

训练数据集

公共数据集

| 数据集 | 缺陷类型 | 数据量 | 获取方式 |

| :--- | :--- | :--- | :--- |

| AITEX | 破洞、污渍、断纱 | 245张图像 | AITEX数据库 |

| TILDA | 多种机织缺陷 | 3200张图像 | 科研渠道获取 |

| Kaggle织物数据集 | 各类缺陷 | 数量不定 | Kaggle平台搜索 |

自建数据集方法

推荐策略

  1. 从生产线采集实际图像

  2. 包含多种织物类型

  3. 均衡各缺陷类别样本量

  4. 加入边缘案例样本

  5. 由行业专家验证样本有效性

最小样本量要求

  • 每个缺陷类别200-500张图像

  • 合格织物图像500张以上

  • 包含多种照明条件下的样本

  • 覆盖不同织物图案

性能基准

典型检测准确率

检测方法准确率检测速度训练数据量
调优后传统计算机视觉85%-92%实时检测无需训练数据
训练后YOLO模型92%-98%30帧/秒以上1000张以上图像
分类卷积神经网络90%-96%100帧/秒以上500张以上图像

生产指标要求

指标目标值
缺陷检出率>98%
误检率<2%
处理吞吐量与生产线速度匹配
检测延迟<100毫秒

硬件推荐

开发环境

硬件组件
工业USB3相机
LED灯条
织物样本
带GPU的计算机

生产环境

硬件组件
8K线扫相机
相机链路/同轴高清接口
LED线光源
工业计算机
安装支架与防护外壳
系统集成与软件

入门步骤

  1. 采集目标织物类型的样本图像

  2. 从OpenCV方法入手,理解缺陷特征

  3. 使用Roboflow或CVAT工具标注训练数据

  4. 针对特定缺陷训练YOLO模型

  5. 基于独立测试集验证模型性能

  6. 搭配合适硬件部署检测系统