计算机视觉实战:从零搭建一个工业质检系统

Await等等我
2025-06-25 01:34
阅读 316

开篇:为什么我要写这篇文章?

开篇:为什么我要写这篇文章?

作为技术团队负责人,这几年我带着小伙伴们做了不少计算机视觉(CV)项目,其中让我印象最深的,是一个为制造业客户定制的工业零件缺陷检测系统。这个项目不仅让我们深入理解了CV技术在实际业务中的落地难点,也暴露了不少之前没怎么想过的挑战——比如数据少、模型泛化差、部署不稳定等等。

今天我想结合我们团队的实际经验,把这个项目的整个过程完整复盘一遍,包括:

  • 项目背景和业务需求
  • 遇到的技术难题
  • 我们选择的技术方案
  • 模型训练和调优的关键点
  • 真实踩坑经历
  • 最终上线效果与收益

希望这篇文章能给刚入行或者正在做CV项目的同学一点启发,少走一些我们曾经踩过的弯路。


背景介绍:客户需要什么?

背景介绍:客户需要什么?

我们的客户是一家生产小型金属零部件的企业,他们每天的生产量非常大,但传统的质检流程完全依赖人工。这种模式存在几个明显问题:

  1. 效率低:质检员容易疲劳,漏检率高;
  2. 成本高:人力成本逐年上涨;
  3. 标准化难:不同工人判断标准不一致。

因此,他们提出要搭建一套自动化质量检测系统,用相机拍下产品图像,通过算法自动判断是否合格。具体要求如下:

  • 能够识别出常见的六类缺陷(如划痕、气泡、缺边等);
  • 单帧处理延迟控制在50ms以内;
  • 支持离线部署,避免断网影响;
  • 要有可视化界面,方便产线人员操作。

听起来很像是一个标准的分类或目标检测任务,但实际上远比教科书上的例子复杂得多。


问题描述:现实远比想象复杂

刚开始接手项目的时候,我们信心满满,觉得目标检测嘛,YOLO一跑,再加个后处理,应该没问题。结果真正开始调研和开发之后,发现一堆难题扑面而来:

1. 数据太小太偏

客户能提供给我们的初始样本只有不到 500张带标注的图片,而且这些图片全部来自同一批次的产品,光照条件和角度都比较一致,导致后续测试时在真实环境中表现很差。

当时有个同事调侃说:“这哪是深度学习,这是深度记忆。”

2. 缺陷种类分布极度不均衡

虽然定义了6种缺陷类型,但在训练集中某几种类别只出现了一两次,几乎无法让模型学习到它们的特征。

3. 工业环境干扰严重

实际应用中,产线上光线变化大、反光严重,还有灰尘遮挡的问题,导致输入图像质量波动很大,直接影响模型判断。

4. 边缘设备部署受限

客户希望直接在产线机器上进行推理,而不是上传云端。这意味着我们必须使用轻量级模型,并且保证推理速度满足实时性要求。


解决方案:技术选型与架构设计

面对这些问题,我们逐步形成了一套完整的解决方案:

1. 整体系统架构设计

最终我们搭建了一个“边缘端+服务器端”协作的系统架构:

  • 边缘端(NVIDIA Jetson设备):负责图像采集、预处理和模型推理。
  • 服务器端(内网私有服务器):用于模型管理、数据回流、异常分析。
  • 用户可通过浏览器访问 Web 界面查看结果、配置参数、导出报表。

这样既解决了部署问题,又能收集现场反馈数据进行迭代优化。

2. 图像处理策略优化

为了提升图像稳定性,我们在边缘端做了三件事:

  • 直方图均衡化 + 白平衡校正:增强图像对比度、减少光照干扰
  • 动态滤波去噪:根据不同光照情况自适应调整滤波参数
  • ROI 提取:将感兴趣区域裁剪放大以提高小缺陷检测精度

这部分的图像预处理对模型性能提升非常明显,尤其是在反光场景下效果显著。

3. 模型选择与调优

我们初期尝试了几种主流的目标检测模型:

模型 FPS mAP@0.5 备注
Faster R-CNN ~8 0.73 准确率高但慢,不适配边缘
SSD Mobilenet v2 ~25 0.61 轻量化好,召回率偏低
YOLOv5s ~30 0.68 综合表现不错
YOLOv8n ~28 0.70 官方优化更好

最终选择了 YOLOv5s 作为基础模型,因为它在 Jetson 上部署兼容性最好,同时官方生态完善,社区资源丰富,便于后续维护。

4. 数据增强与合成数据补充

由于原始数据太少,我们采取了以下几种方式扩充数据:

  • 传统图像变换:旋转、翻转、亮度调整、添加噪声等
  • MixUp / CutOut / Mosaic:这些数据增强手段对小样本非常有效
  • GAN生成缺陷样本:用 StyleGAN3 基于已有正常图像生成模拟缺陷样本
  • 引入开源数据集辅助训练:例如 DTD、COCO 中的相关纹理数据作为迁移学习起点

通过上述方法,我们将可用训练样本扩充到接近 5000 张,并且类别分布也更加均衡。

5. 模型微调策略

训练过程中我们也尝试了一些有效的调参技巧:

  • 冻结 backbone 层,先 fine-tune head 层
  • 使用 cosine scheduler + warmup 学习率衰减
  • 损失函数采用 CIoU 替代 GIoU(收敛更快)
  • 增加 Focal Loss 分支(针对不平衡类别)

此外,我们还使用了 AutoAnchor 自动聚类 anchor box 参数,提升了小目标检测的准确性。


关键代码片段分享

以下是一些核心代码片段,供你参考:

图像预处理部分(OpenCV)

def preprocess_image(img):
    # 白平衡校正
    img = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
    avg_a = np.mean(img[:, :, 1])
    avg_b = np.mean(img[:, :, 2])
    img[:, :, 1] = img[:, :, 1] - ((avg_a - 128) * (img[:, :, 0] / 255.0) * 1.1)
    img[:, :, 2] = img[:, :, 2] - ((avg_b - 128) * (img[:, :, 0] / 255.0) * 1.1)
    img = cv2.cvtColor(img, cv2.COLOR_LAB2BGR)

    # 对比度拉伸
    lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
    l, a, b = cv2.split(lab)
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
    cl = clahe.apply(l)
    limg = cv2.merge((cl,a,b))
    final = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)

    return final

YOLOv5 推理脚本片段

from yolov5 import detect

results = detect.run(source=image_path,
                     weights='weights/best.pt',
                     imgsz=640,
                     conf_thres=0.4,
                     iou_thres=0.5,
                     device='cpu',  # 改成 'cuda' 可启用GPU
                     view_img=False,
                     save_txt=True)

踩坑总结:那些年我们掉进去的坑

这一路走来,我们也踩过不少坑,下面几个教训值得记录下来:

1. Jetson 上部署 ONNX 的“隐式崩溃”

我们一开始尝试将 PyTorch 模型导出成 ONNX,然后用 TensorRT 加速。看起来一切顺利,结果在现场部署时经常出现“程序卡死”现象。

排查才发现,某些 ONNX 层在 TensorRT 编译时出现了隐式转换错误,虽然编译成功了,但运行时内存泄漏导致崩溃。后来我们改用 TorchScript 导出模型,在 Jetson 上运行更稳定。

2. 缺陷类别混淆

某个阶段模型总是把划痕误判为“脏污”。这个问题其实不是模型能力问题,而是数据本身标注不够规范,两种类别定义边界模糊。为此我们重新梳理了缺陷定义文档,组织客户质检部门一起校对数据标签,确保每个缺陷都有清晰的区分标准。

3. 模型输出不确定性

有时候模型会在相同环境下输出不同的结果。后来发现是因为数据增强在验证集被不小心开启了。一定要记得设置:

transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

# 测试时使用:
dataset = DefectDataset(transform=transform, train=False)

效果总结:项目上线后的收获

经过三个月的开发、调优和现场部署,这个系统终于正式上线并取得了不错的成果:

  • 准确率从人工平均的90% 提升到96%
  • 单日质检数量提高3倍以上
  • 漏检率下降至约2%
  • 模型推理延迟稳定在45ms以内
  • 系统支持远程更新模型和配置

客户的厂长还特地请我们吃了一顿饭,说现在不用天天盯着质检报表了,可以专注抓生产。


心得分享:几点建议送给读者

如果你也在做一个 CV 实战项目,尤其是面向工业应用的,我有几点真心建议:

✅ 明确业务边界,别贪多嚼不烂

很多时候业务方提的需求看似合理,但我们要主动引导他们聚焦在最关键的一两个问题上。别想着一开始就建个全能系统,先解决最头疼的问题,再一步步扩展。

✅ 数据质量 > 数据数量

很多新手以为只要有足够多的数据就一定能训练出好模型。其实在 CV 中,数据标注质量和多样性往往更重要。特别是当缺陷样本较少时,高质量标注尤为关键。

✅ 模型不是万能的,工程才是王道

即使模型准确率达到99%,但如果部署不稳定、响应慢、UI不友好,用户一样不会买账。所以你要重视前后端、系统架构、用户体验等方面的投入。

✅ 把“可解释性”融入日常设计中

尤其在工业质检这种涉及产品质量和责任划分的场景,模型的每一个判断都应该有据可依。你可以考虑集成 Grad-CAM 或 SHAP 来展示模型关注区域,让用户更有信任感。


结语:技术是工具,业务才是核心

回顾这段经历,最大的感悟就是:技术永远服务于业务,不能脱离业务谈技术。计算机视觉虽然是当前的热点方向,但它终究只是解决问题的一种手段。

在工业质检这个场景下,我们并不是在打造一个多么炫酷的 AI 模型,而是在帮助客户解决一个真实存在的痛点。正是这些“接地气”的需求和挑战,才推动我们不断成长。

如果你也有类似项目的经验,欢迎留言交流,我们可以一起探讨更多实用技巧!


文末彩蛋:文章提到的代码、数据集结构和训练脚本,我会整理成一个 GitHub 小 demo,放在附录链接里。有兴趣的小伙伴可以去看看。

GitHub 示例仓库地址:https://github.com/example/industrial-defect-detection-demo(伪链接,请替换为你自己的)

如有疑问,欢迎随时找我讨论!

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝