
简介面向辣条包装袋质检场景的工业视觉缺陷检测实战项目包适合机器视觉初学者与中级算法工程师快速上手。项目完整覆盖图像预处理灰度化、二值化、滤波、边缘检测、特征提取、缺陷识别与结果输出等关键环节并基于开源视觉库与深度学习框架实现了训练、预测、导出推理模型的工程化脚本。压缩包共包含八十八个文件其中有三十余个算法脚本、四十余张包装袋图像样本、预训练权重文件、通用推理模型以及说明文档整体约四十兆字节目录结构清晰便于复现与二次开发。目前已有一百四十余人学习使用可帮助读者快速跑通缺陷检测流程理解传统图像处理与深度模型在包装质检中的协作方式。通过自带权重和推理脚本可快速验证算法效果在此基础上还可移植到生产线联动剔除不合格包装为食品包装自动化升级提供直接参考。1. 辣条包装袋缺陷检测这是一个能直接照着做的工业视觉项目在辣条产线上每分钟有两三百包成品从枕式包装机里吐出来品检工要盯着封口是否漏气、袋身有没有破孔、油渍是否渗漏、印刷图案有没有缺块。人眼在这种强度下撑不过半小时漏检率一高投诉和退货就找上门。这个标题里的“辣条包装袋缺陷检测算法实现”本质就是用工业相机加一整套图像处理算法替代人眼完成这道质检工序。它属于工业视觉里典型的“表面缺陷检测”场景和钢板表面划痕、螺栓缺扣、轴承滚珠瑕疵是同一类问题只是被检测对象换成了半透明、高油光、褶皱多的塑料包装袋。这个项目的价值在于辣条包装的材质和内容物决定了它不能简单套用通用检测算法油渍反光会被误判成破孔透明薄膜的褶皱会被误判成划痕这些坑不踩一遍很难理解。文章会在方案选型、图像预处理、检测算法实现和产线部署四个层面给你一套能本地跑通的最小实现。适合三类人刚入门机器视觉想做实战项目的学生、在食品包装厂做设备改造的工程师、想用传统视觉方案快速验证需求而不是一上来就上深度学习的算法工程师。接下来先回答一个问题这个检测任务到底该拆成几路来做为什么不能指望一个模型通吃。2. 检测任务拆解与方案选型先分缺陷类型再决定用规则还是深度学习拿到“辣条包装袋缺陷检测”这个需求第一反应往往是训练一个目标检测模型把所有缺陷框出来。这个思路方向对但落地成本偏高标注几千张缺陷样本需要时间辣条油渍的形态千变万化模型很容易过拟合到某一条产线的光照和包装批次上。更稳的做法是把缺陷按物理成因分三类每一类用不同的检测策略最后在结果层合并。2.1 缺陷分型封口类、袋身类、印刷类三类缺陷的检测逻辑完全不同封口类缺陷包括封口不严、封口偏移、封口褶皱。这类缺陷只出现在包装袋两端的热封区域可以用“区域限定纹理分析”解决不需要看全图。袋身类缺陷包括破孔、油渍渗出、异物附着这类缺陷出现在薄膜主体上特征是灰度或颜色的局部异常适合用阈值分割加连通域分析。印刷类缺陷包括图案缺失、色差、套印偏移这类缺陷需要与标准模板做比对对打光均匀性要求最高。把检测任务按这三类拆开好处在于每一路的算法复杂度都能降下来不需要一个万能模型处理所有情况。以封口检测为例你只需要裁出袋子两端各一块固定区域检查这块区域内的灰度和纹理特征。假如封口正常这块区域应该是一条灰度均匀的压痕带如果封口不严压痕带中间会出现灰度突变或者出现与正常压痕纹理明显不同的松散的暗色区域。2.2 选型理由传统视觉做预筛查轻量模型做细分类这是食品包装线最常见的配置在真实产线上我一般会把方案定成“传统视觉初筛 轻量CNN细分类”的两级架构。第一级用OpenCV做快速的规则检测把明显合格的袋子放行把疑似异常的区域裁出来第二级只对疑似区域做分类判断是缺陷还是正常纹理。这样做有两个直接好处第一传统视觉部分跑在CPU上50毫秒内能处理完一张图不会成为产线瓶颈第二深度学习模型只需要看局部小图不需要在大分辨率的全图上跑推理算力需求和标注成本同时降下来。有人会问为什么不直接用DINOv2这类基础模型做2D缺陷对比它们在有大量通用视觉知识的前提下做异常检测的效果确实好但部署依赖GPU和较大的显存在单条产线预算有限、只配一台工控机的场景下很难落地。先用规则检测把问题范围缩小再让轻量分类器只回答“有缺陷/没缺陷”是性价比最高的路径。2.3 标定思路先定相机、镜头和光源再谈算法硬件决定了算法的上限检测方案里最容易忽略的是硬件选型。辣条包装袋是半透明材质内部有辣条和油脂如果用背光照明袋身内部的油渍会投影成暗斑误判率很高。常见做法是用低角度环形光源加漫射板让光线均匀打在袋面封口区域用条形光源从侧面打光利用热封压痕对光线的散射差异来增强纹理对比度。相机方面500万像素的面阵相机配上16毫米定焦镜头在400毫米工作距离下能覆盖一包辣条的全部袋身区域单像素精度约0.1毫米足够看清直径0.5毫米以上的破孔。如果现场没有条件重新搭光学环境也可以用现有的普通工业相机加一个偏振片来削弱辣条油的反光。偏振方向与光源偏振方向垂直时镜面反射光被过滤漫反射光保留油渍区域会从高光变成暗区这比任何后处理算法都管用。硬件定了之后再做软件算法才有意义否则所有参数都是对着光晕调出来的玄学。3. 图像采集与预处理光源、ROI和增强手段怎么定才能让缺陷特征真正现形算法实现之前先把图像质量做到位能省掉后面一半的调参时间。预处理的目的是扩大缺陷与正常区域的差异同时抑制辣条油反光、薄膜褶皱和包装批次差异这些干扰项。下面按采集端参数、ROI定位、预处理管线三个层次展开。3.1 采集端的三组关键参数曝光、增益、触发方式相机参数不是随便给的要根据产线速度和目标精度算出来。辣条包装袋在传送带上的运动速度一般在每秒200到400毫米如果曝光时间超过1毫秒图像上会出现运动模糊破孔边缘被拉成一条线。所以我通常把曝光时间压在200到500微秒靠补光来保证亮度而不是靠增益。增益一旦超过6分贝噪点会明显增加原本需要检测的微小破孔会淹没在噪声里算出来的连通域面积忽大忽小。触发方式用硬件触发不要用软件连续采集。光电传感器检测到包装袋到达相机视野中心时发出脉冲信号相机在脉冲触发下采集一帧。这样做的原因是产线上袋子之间的间距不固定软件定时采集容易拍到袋子边缘或者两张袋子的接缝后续ROI定位还得做复杂的图像匹配得不偿失。触发信号接好之后配合一个简单的串口通信程序每次触发就存一张图离线阶段可以快速积累缺陷样本。3.2 ROI动态定位用包袋边缘做基准不靠固定坐标裁剪固定坐标裁剪在产线静止时没问题但传送带一跑起来袋子的位置会有几个毫米的随机偏移直接裁固定区域会把背景漏进来或者把封口切掉一半。常见做法是先做一次全局阈值分割把袋身主体从背景里分出来然后取袋身轮廓的最小外接矩形以矩形的四边为基准重新计算封口区域和袋身区域的坐标。这样每次检测前ROI都会跟随包袋位置自动调整。ROI定位的代码逻辑大概是灰度图转二值图找最大轮廓计算最小外接矩形然后定义封口区域为矩形两端各10%宽度的条带袋身区域为中间80%的主体部分。需要提一下的是背景颜色要跟袋子有足够的灰度差否则轮廓提取不稳定。如果现场背景无法修改可以在相机视野下方垫一块黑色哑光垫板这是成本最低的解决方案。3.3 预处理管线降噪、增强、去反光三个步骤的顺序不能乱预处理顺序有讲究我做过几次调整最后稳定为先高斯滤波去噪再做局部直方图均衡最后用形态学操作去掉细小的纹理干扰。高斯滤波的卷积核大小一般取3×3或5×5。辣条包装袋表面的印刷图案有明显的边缘核太大容易把图案边缘磨掉核太小去不掉油渍引起的椒盐噪声。局部直方图均衡用CLAHE算法限制对比度参数clipLimit设为2.0网格大小设为8×8。这一步很关键因为产线上环境光会变化全局直方图均衡会把整体亮度拉平让背景和袋身分不清而局部均衡可以保留袋身内部的明暗层次让破孔边缘更加锐利。最后做一次开运算先腐蚀再膨胀结构元素用3×3矩形目的是去掉薄膜表面细小的褶皱纹理因为这些纹理在后面的连通域分析里会连成一片形成面积很大的假缺陷。下面是一段可直接运行的OpenCV预处理代码基于Python环境import cv2 def preprocess_image(image_path, clip_limit2.0, kernel_size3): 辣条包装袋图像预处理 image_path: 输入图像路径 clip_limit: CLAHE对比度限制 kernel_size: 形态学结构元素大小 # 读取图像转为灰度图 img cv2.imread(image_path) if img is None: raise ValueError(f图像读取失败: {image_path}) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 第一步高斯滤波去噪sigma取0由核大小自动计算 blur cv2.GaussianBlur(gray, (kernel_size, kernel_size), 0) # 第二步CLAHE局部直方图均衡增强局部对比度 clahe cv2.createCLAHE(clipLimitclip_limit, tileGridSize(8, 8)) enhanced clahe.apply(blur) # 第三步开运算去除细小褶皱纹理 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_size, kernel_size)) cleaned cv2.morphologyEx(enhanced, cv2.MORPH_OPEN, kernel) return img, gray, cleaned逻辑说明高斯滤波的核大小取3时能保留印刷图案的锐利边缘取5时对油渍噪声的抑制更好。CLAHE是这步的核心它把图像分成8×8的小块做直方图均衡限制对比度避免放大噪声。开运算里的结构元素大小直接影响后续连通域面积统计取3×3时能去掉单像素宽度的褶皱纹理取5×5时会把一些真正的细小破孔也抹掉所以这个参数要根据实际分辨率测试后再定。4. 检测算法核心实现面积筛选、颜色阈值与轻量分类器的组合拳预处理完成后进入检测主流程。这里的三路检测分别对应前面拆解的封口类、袋身类和印刷类缺陷。每一路先跑规则检测把确定异常的区域保留再把疑似区域交给分类器复核。4.1 封口缺陷检测灰度投影加边缘密度统计找出封口不严和褶皱封口区域的正常特征是灰度均匀、纹理平滑。封口不严时热封压痕中间会有一段灰度明显偏亮或偏暗的区域。褶皱封口则表现为边缘密度异常增大。检测方法是先把ROI区域裁出来做一次灰度投影统计每一行和每一列的平均灰度值再计算梯度变化。封口区域的宽度通常是150到250像素投影后会形成一条规律的灰度曲线。正常封口的曲线平滑中间没有大的跳变封口不严的区域曲线上会出现一个宽度5到15像素的凹陷或凸起。同时用Canny边缘检测统计封口区域内的边缘像素密度正常封口边缘像素占比在2%以内褶皱封口会超过5%。两条规则取或任何一个指标超过阈值就判为缺陷。import numpy as np def check_seal_area(roi_image, gray_threshold18, edge_ratio0.05): 检测封口区域的灰度均匀性和边缘密度 roi_image: 裁剪后的封口区域图像单通道灰度 gray_threshold: 灰度投影最大允许波动 edge_ratio: 边缘像素占比阈值 height, width roi_image.shape # 行投影计算每一行的平均灰度 row_mean np.mean(roi_image, axis1) # 计算投影曲线的最大波动范围 row_deviation np.max(row_mean) - np.min(row_mean) # Canny边缘检测统计边缘像素占比 edges cv2.Canny(roi_image, 50, 150) edge_count np.sum(edges 0) edge_ratio_actual edge_count / (height * width) is_defective False if row_deviation gray_threshold: is_defective True if edge_ratio_actual edge_ratio: is_defective True return is_defective, row_deviation, edge_ratio_actual逻辑说明灰度投影的波动值直接反映封口压痕是否均匀。如果热封温度不够封口区域会有一段没有被压紧灰度值明显偏高。Canny边缘检测的阈值50和150是经验值针对500万像素的封口图像效果稳定如果摄像头分辨率不同这两个阈值要做线性缩放否则边缘密度统计会失真。edge_ratio设为0.05意味着5%的边缘像素占比就触发判定这个值在褶皱封口上非常敏感但也会把表面印刷比较脏的袋子误判所以要和后续的CNN复核配合使用。4.2 袋身缺陷检测形态学重建加连通域筛选定位破孔和油渍渗出袋身区域是检测的难点因为辣条油会渗出到透明薄膜表面形成一片面积不定的油渍区。破孔和油渍都是灰度异常区域但形态不同破孔是边缘锐利的暗色小区域油渍是灰度过渡平缓的暗色大区域。处理时先用形态学重建做背景估计得到袋身的明暗场分布然后从原始图像中减去背景估计值得到前景异常区域。具体做法是对袋身区域做一个大核的闭运算结构元素约15×15得到模糊的背景图然后用原图减去背景图。这样可以消除光照不均匀的影响让破孔和油渍以目标的绝对灰度差显现出来。之后用大津阈值二值化再按面积筛选面积小于5个像素的判定为噪声面积在5到50像素的判定为破孔候选面积大于50像素的判定为油渍渗出候选。4.3 印刷缺陷检测模板差分与配准先对齐再比较印刷缺陷的三路检测里最容易翻车的一路因为薄膜是软的每一袋的印刷位置都有几毫米的偏移直接差分会出现大量边缘假阳性。正确做法是先做模板匹配配准在图像中找印刷图案的基准色块计算偏移量把当前图像平移回来再做差分。配准的基准我一般选包装袋上的一个固定尺寸logo或生产日期喷码区域。用归一化互相关匹配最大响应点的位置就是配准偏移量。差分之后计算差分图像的绝对值和均值超过阈值的像素数占总像素数的比例就是印刷异常指数。需要注意喷码区域每一袋的数字都不一样配准和差分时都要把喷码区域排除在外。4.4 引入轻量分类器做复核只对“模棱两可”的区域做判断这是落地时最实用的技巧规则检测的输出有三类确定正常、确定缺陷、特征模糊。确定正常和确定缺陷直接放行或拦截特征模糊的区域个数通常占总量不到5%但它们恰恰是误检和漏检的高发区。我在这里用了一个结构简单的CNN分类器输入是嫌疑区域的裁剪图尺寸缩放到64×64网络只有两层卷积加一层全连接参数总量不到10万CPU推理单张耗时不到3毫秒。训练这个分类器需要的标注量不多。收集1000张特征模糊的区域图标注为“正常纹理”和“真实缺陷”两类再加上图像增强做扩充就能把准确率做到95%以上。训练时要注意类别平衡正常纹理和缺陷样本的比例控制在1比1否则模型会偏向把模糊区域判为正常。数据增强用随机旋转、平移和亮度抖动不要用强模糊强模糊会把缺陷的边缘特征抹掉。import torch import torch.nn as nn import cv2 import numpy as np class DefectClassifier(nn.Module): 轻量缺陷复核分类器输入64x64灰度图 def __init__(self): super(DefectClassifier, self).__init__() self.features nn.Sequential( nn.Conv2d(1, 8, kernel_size3, padding1), nn.ReLU(inplaceTrue), nn.MaxPool2d(2), nn.Conv2d(8, 16, kernel_size3, padding1), nn.ReLU(inplaceTrue), nn.MaxPool2d(2), ) self.classifier nn.Sequential( nn.Linear(16 * 16 * 16, 32), nn.ReLU(inplaceTrue), nn.Linear(32, 2), ) def forward(self, x): x self.features(x) x x.view(x.size(0), -1) x self.classifier(x) return x def classify_candidate(model, candidate_image): 对嫌疑区域做缺陷复核 candidate_image: 嫌疑区域灰度图任意尺寸 # 缩放到64x64并归一化 resized cv2.resize(candidate_image, (64, 64)) resized resized.astype(np.float32) / 255.0 tensor torch.from_numpy(resized).unsqueeze(0).unsqueeze(0) with torch.no_grad(): logits model(tensor) pred torch.argmax(logits, dim1).item() return pred # 0表示正常纹理1表示真实缺陷逻辑说明第一层卷积输出8个特征图第二层输出16个通道数刻意压得很低目的是不让模型学出对特定光照的过拟合。全连接层的输入维度由卷积输出特征图尺寸决定64×64输入经过两次池化后是16×16乘以16通道所以是4096维。candidate_image传入前要确保包含完整的嫌疑区域轮廓不要只传一个被裁剪了一半的区域否则模型看不到缺陷的边界信息判决结果会偏随机。5. 常见问题与踩坑记录油渍反光、ROI漂移和模型过拟合逐个拆解这一章是血泪经验的部分全部来自实际跑线中遇到过的翻车案例。每一条都是“现象-原因-解决”三段式可以对照自己的项目排查。5.1 油渍反光被误判成破孔现象规则检测把大量的油渍高光区域判定为破孔一包正常的辣条因为表面油渍反光被拦截误检率达到30%以上。原因辣条油在环形光源照射下形成镜面反射反射区域的灰度值比周围高出两三个等级阈值分割时被当作灰度异常提取出来。加了偏振片可以减少镜面反射但很多项目现场没有条件加装只能靠算法补救。解决在光源和相机之间加装偏振片是根治方案若无法加装则在预处理阶段增加一步“饱和度通道检查”油渍区域的整体色调偏红或偏黄而破孔区域是透明的没有明显的颜色偏移。具体做法是在HSV空间的S通道上再做一次阈值分割如果某个连通域在S通道上没有对应的红色响应就把它判为破孔如果S通道上同时存在大面积高饱和区域就判为油渍渗出不触发破孔报警。5.2 ROI定位在高速产线上漂移现象预处理阶段用最小外接矩形定位袋身区域低速运行时准确加速到每分钟200包以上时ROI频繁出现偏移封口区域被裁到袋身中间。原因高速产线上袋子有轻微跳动最小外接矩形在袋子边缘不平整时计算出的角度会突变导致裁剪区域产生几个毫米的偏差而这些偏差在封口区域以内的特征上被放大。解决换用“最小外接矩形角度平滑”方案维护一个长度为10的旋转角度滑动窗口每次用窗口中位数作为本次检测的旋转角而不是用单次计算出来的瞬时角度。这样即使某一帧袋子跳动ROI也不会跟着跳而是平滑过渡到新位置。5.3 CLAHE参数不当导致微弱破孔被增强成正常纹理现象预处理后用连通域统计检出的破孔面积比实际偏小部分直径0.3毫米的微孔直接漏掉。原因CLAHE的clipLimit设得太高6.0以上时局部小块内的噪声被大幅增强破孔边缘的对比度虽然提升了但破孔内部的灰度变化也被拉平导致阈值分割时破孔区域的像素被分割成两个不连续的小区域面积小于最小统计阈值。解决把clipLimit降回2.0并在阈值分割之前加一步“局部区域最小灰度搜索”以规则检测提取出的连通域为中心向外扩张5个像素搜索该局部区域内的灰度最低点若最低点比背景均值低30个灰度级以上就保留该区域为破孔候选。5.4 模板配准受印刷批次差异影响现象印刷缺陷检测的误检率在有新批次包材上线时暴增甚至整袋被误判为印刷异常。原因包材供应商切换批次后印刷油墨的色相有轻微偏移模板匹配的归一化互相关响应从0.95掉到0.85触发误报阈值。这不是算法问题是工业现场常见的物料批次差异。解决在模板匹配阶段不直接用标准模板而是每生产批次开始前自动采集前20袋正常品做平均生成“批次参考模板”。这个方案需要产线有联动启停信号批次切换时由操作工触发一次模板更新成本低、效果明显比在算法里做颜色恒常性处理要省事得多。5.5 深度学习复核模型在产线环境下缓慢退化现象复核模型上线时准确率97%运行两个月后掉到88%而且误判集中在固定的几个时间段。原因光源亮度在衰减相机镜头上积累油雾导致输入图像的对比度分布发生偏移模型训练时的数据分布和实际推理时的数据分布不再一致。这是机器视觉项目在食品产线上最常见的慢故障。解决在部署代码里加一条输入分布自检逻辑每1000张图中随机抽10张统计灰度均值、方差和CLAHE增强后的梯度密度与上线时的基准值对比。任一指标偏差超过15%就触发维护告警提示清洁镜头或更换光源。同时每月用最近的缺陷样本增量微调一次复核模型只需要训练少量step避免模型被新批次包材的图像分布带偏。6. 从离线验证到产线部署结点服务、接PLC信号、做A/B对比代码在本地跑通只是第一步产线部署涉及通信协议、异常处理和效果闭环。这一章给出一个最小可落地的部署路径以及验证算法效果的实操方法。6.1 算法封装成检测服务用FastAPI或TCP Socket提供接口常见做法是把检测算法封装成一个独立的服务进程通过HTTP或TCP接口与上位机通信。我倾向于用FastAPI起一个轻量服务每次收到图像数据就返回检测结果。接口定义只需要两个一个是单图检测接口供离线调试用一个是批量推理接口供产线连续调用。Python的GIL会限制多线程推理效率所以使用Flask或FastAPI时建议通过进程池来执行检测函数避免耗时操作阻塞请求线程。下面是部署服务的核心框架import cv2 import numpy as np from fastapi import FastAPI, File, UploadFile import uvicorn from concurrent.futures import ThreadPoolExecutor # 用线程池隔离检测任务避免请求阻塞 executor ThreadPoolExecutor(max_workers2) app FastAPI() def run_inspection(image_array): 核心检测逻辑接收BGR图像数组返回检测结果元组 # 这里调用第3章、第4章的预处理和检测函数 # 返回格式: (is_ok, defect_type, defect_location) pass app.post(/inspect) async def inspect_image(file: UploadFile File(...)): 单图检测接口返回JSON格式的检测结果 image_bytes await file.read() image_array cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR) if image_array is None: return {status: failed, message: image decode error} future executor.submit(run_inspection, image_array) is_ok, defect_type, defect_location future.result(timeout5) return { status: ok, is_ok: is_ok, defect_type: defect_type, defect_location: defect_location, } if __name__ __main__: uvicorn.run(app, host0.0.0.0, port8000)6.2 与PLC对接检测结果通过IO信号或Modbus TCP输出产线拦截机需要实时拿到检测结果HTTP响应的时间不可控所以结果输出要走硬实时通道。通常的做法是检测服务在判定缺陷后通过USB转IO模块或Modbus TCP向PLC写一个线圈信号PLC收到信号后驱动气吹机构把缺陷袋子踢出产线。检测服务的判结果到发出IO信号的全链路耗时应该低于100毫秒这是由PLC的扫描周期和气吹机构的机械延迟决定的。如果Python端到IO模块的链路不稳定可以把IO控制独立成一个C语言小进程检测服务通过本地UDP把结果发给它由它来驱动IO这样丢包率可以降到万分之一以下。6.3 用A/B对比验证效果人工质检与算法并行记录误检漏检持续调优算法上线时不要直接替代人工而是让算法和人工质检并行运行两周。每一次人工复核的结果都记录下来与算法判定做对比生成混淆矩阵。重点看两类数据算法判为缺陷但人工放行的即误检算法放行但人工拦截的即漏检。误检样本要分析特征是否过于敏感把规则阈值往回收漏检样本要回放图像确认是预处理阶段被滤掉了还是分类器打错了标签。两周后统计误检率和漏检率如果两项都低于人工质检的水平就可以进入单机试运行阶段。最终验收时用连续一周的日产量做统计缺陷检出率不低于95%误检率不高于2%这是食品包装行业里一个相对合理的验收标准。6.4 阈值参数速查表检测项参数经验值调节依据预处理CLAHE clipLimit2.0增大则增强对比度过大会放大噪声预处理形态学核大小3×3比单个破孔直径小一半以上封口检测灰度投影波动阈值18按封口区域宽度均值调整封口检测边缘密度阈值5%过高会漏掉褶皱封口袋身检测破孔面积下限5像素小于此值的多为噪点袋身检测油渍面积下限50像素小于此值的为油渍微渗可忽略分类器输入尺寸64×64过大增加推理时间过小丢失缺陷细节这套阈值只适用于本文使用的500万像素相机和约0.1毫米像素精度换用不同分辨率的相机时面积类参数要按像素精度做等比缩放这个容易忘。6.5 一个值得养成的习惯上线第一天就建立“缺陷图像台账”和“误判复盘日”机制部署不是终点算法会在产线环境里持续漂移。我的习惯是上线第一天就写一个图像保存开关把所有判为缺陷和所有被人工纠正判定结果的图像原图自动留存。每周做一次误判复盘从台账里挑出新增的误判样本看是否存在新批次的包材、新的油渍形态或光源变化。两个月下来台账里的误判样本就成了调整阈值的依据而不是凭感觉改参数。这个习惯帮我在很多项目上避免了“上线时效果好、三个月后问题频出”的翻车回退。希望这篇实战记录能帮你在辣条包装袋检测这个方向上少走弯路也欢迎你在自己的产线上先跑通这三路检测再考虑加深度学习做更细的分类。本文还有配套的精品资源点击获取