ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

机器视觉实战:苹果品质分级系统的设计与工程化实现

机器视觉实战:苹果品质分级系统的设计与工程化实现

1. 从一个分拣难题说起:为什么苹果品质分级需要机器视觉

过去几年我自己一直在折腾机器视觉相关的项目,最常见的需求不是人脸识别,也不是自动驾驶,而是各种“看着简单、做起来一堆坑”的传统工业分拣问题。苹果品质分级就是其中很有代表性的一个:普通人觉得“不就是按大小颜色分个类吗”,但真正站在分拣线旁边看一个小时就会发现,人工分拣的疲劳速度远超想象。一个熟练工每分钟能分拣几十个苹果,但连续工作两个小时之后,误判率明显上升,尤其是大小相近、颜色有细微差异的果子,标准很容易漂移。果企真正想要的不是“分得比人快”,而是“全天候保持同一套标准”。

我之前帮某果企做了一套基于机器视觉的苹果品质分级系统,整个过程走下来,发现真正的技术难点其实不在算法模型的复杂度,而在于怎么把“品质”这个模糊概念翻译成可计算的视觉特征,以及怎么在真实产线的光照、震动、速度条件下保持稳定。这个项目我从硬件选型、图像采集到特征提取和分级决策全部独立完成,走了不少弯路,也沉淀了一套可以复用的方法。这篇文章就把整个设计与实现过程拆开来讲,包括为什么选这套方案而不是那套方案、每一步操作背后的逻辑、以及实际跑产线时踩过的坑。

这套系统能做什么,先给一个明确的范围界定:它面向的是静态或慢速移动状态下的单个苹果表观品质分级,核心指标涵盖大小(直径或投影面积)、形状(圆整度)、底色颜色(青红比例)、表面缺陷(碰压伤、花斑、虫眼等)。不涉及内部品质如糖度、酸度的无损检测,那些需要近红外光谱设备,是另一个技术分支。

无论你是刚开始接触机器视觉的学生、想给家里果园做小型分拣机的爱好者,还是产线技术负责人想评估视觉分级方案的可行性,这篇文章都可以作为一份偏向实战的参考,我会把每个环节的取舍逻辑都讲清楚。

2. 分级指标拆解:哪些特征能真正区分苹果品质

在做任何视觉项目之前,第一件事不是打开相机,而是和需求方把分级标准谈清楚。苹果分级其实是有行业惯用维度的,但不同渠道差异很大:收购商可能更看重大小和底色,超市渠道对表面缺陷和果形要求更严格,电商小份装又会额外关注颜色均匀度。系统设计必须把这些维度映射成视觉上可提取的特征。

我把分级指标拆成了四组:大小、形状、颜色、表面缺陷。

大小是最容易量化的。正面拍摄苹果时,可以用轮廓的外接圆直径或者等效直径来表征。但要注意,苹果不是一个完美的球体,不同品种的果形差异很大。如果用单个直径值来分级,容易把果形偏扁的果子误判为小果。实际操作中我采用投影面积换算等效直径的办法,公式是 D = 2 * sqrt(A / π),A 为二值掩膜的像素面积,再通过标定系数换算成物理尺寸。这样对果形不那么敏感的品种更友好。

形状特征我用了两个指标:圆度(Roundness)和轮廓凹凸度。圆度计算方式是 4πA / P²,其中 P 是轮廓周长。标准富士苹果的圆度一般在 0.85 到 0.95 之间,畸形的果子常常低于 0.8。单看圆度还不够,有些果实在侧面视角下轮廓接近圆形,但实际上某个区域有塌陷,这时我会额外计算轮廓凸包面积与实际轮廓面积的比值,称为“丰满度”。两项结合能筛掉绝大多数畸形果。

颜色特征包含两个层面:底色判定和着色面积比例。底色受品种影响很大,红富士的底色偏黄绿,花牛苹果底色偏红黄。因此系统先做品种注册,每种品种保存一组HSV颜色分布模板。着色面积比例则是计算红色像素占整个果实像素的比例,这是超市渠道很看重的指标。颜色特征必须在受控光源下提取,否则色温一飘,结果就全变了。

表面缺陷是最难搞的部分。碰压伤在可见光图像上往往只是局部颜色变暗甚至没有明显色差,虫眼和花斑又容易被误判为正常果点。我采用的策略是“多通道联合判定”:使用颜色异常检测、边缘梯度分析和形态学筛选三层过滤。先找到可疑区域,再用边缘强度确认缺陷边界是否清晰,最后按面积和圆形度排除果点、果锈等干扰。

这个拆解过程帮我把无标准的问题转化成了有标准的问题。每一组特征都有明确的输出区间,后面做分级决策表时就不需要拍脑袋了。

3. 图像采集与预处理:消除环境噪声是精度的起点

很多人一上来就调算法,结果效果不稳定,最后发现是图像采集环节出了问题。苹果表面的反光、环境光的闪烁、传送带背景干扰,这些都会直接影响特征提取的稳定性。这个项目我在采集环节花的精力不比其他任何环节少。

3.1 硬件选型思路:工业相机还是普通摄像头

这里先说明,我用的相机是某品牌的千兆网工业相机,500万像素,全局快门。为什么不选 USB 摄像头?两个原因:一是普通摄像头的自动白平衡和自动曝光没法关闭,光照一变它会自己调整参数,导致同一箱苹果在不同时刻拍出来的颜色表现不一样,这对颜色分级是致命的。二是全局快门对运动模糊的控制更好,虽然我的实验台用的是静态拍摄,但后期要接传送带,提前把硬件冗余做出来能少走弯路。

如果预算有限,也可以选 USB 接口的工业相机,只要确认支持手动关闭自动增益、自动白平衡这些功能即可。像素选 300 万到 500 万就够用了,苹果的直径按 80mm 计算,视场拍 200mm x 200mm 范围,500 万像素下每个苹果能分到足够多的像素用于缺陷检测。

镜头方面我用的是 8mm 定焦镜头,光圈调到 F8 左右。小光圈带来更大的景深,减少苹果高度差异导致的边缘虚化。

光源是整个采集环节的灵魂。苹果表面是曲面,直接打光会产生大面积镜面反射,亮斑区域的颜色信息完全丢失。我最后选择了低角度环形光源加漫射板的方案,相当于用散射光把苹果包围起来,高光区域被显著压制。灯色温固定在 6500K,让色彩还原一致性有保障,白色 LED 板比较好买,成本也低。

3.2 背景与遮光:一个经常被忽略的稳定性因素

采集箱内部涂成哑光黑,背景也是黑色绒布。为什么用黑色?因为苹果轮廓与背景的灰度差异最大,后续背景分割的阈值处理最简单、最稳定。如果用白色背景,苹果的高光和白色背景混在一起,分割难度直线上升。

相机、光源、苹果的相对位置固定之后,整套系统对外界环境光的抗性就很强了。我在采集箱外侧加了遮光帘,实测下来,室内灯光开关状态对最终特征数值的影响控制在很小范围内。这一点很重要,因为很多实验室环境下跑得好好的代码,一搬到车间就失效,多数原因是没有做环境隔离。

3.3 预处理流水线:从原图到干净的果实掩膜

预处理的作用是把苹果从背景中干净地分离出来,同时去除噪声干扰。我的流程如下。

第一步是色彩空间转换,将原图从 BGR 转到 HSV。HSV 对光照变化的鲁棒性比 RGB 好,而且后续做颜色判定时直接在 HSV 空间操作更直观。

第二步是背景分割。我试过基于阈值的简单分割也试过基于深度学习的语义分割。结论是,在固定黑色背景下,传统图像处理的阈值方法就足够了,而且速度更快、无需标注数据。具体做法是用 HSV 的 Saturation 通道做背景分离——黑色背景的饱和度极低,而苹果表面的饱和度较高,设一个饱和度阈值可以将两者分开。再配合亮度通道排除阴影区域,最终得到一个二值掩膜。

第三步是形态学操作。先用开运算去除掩膜上的零星小白点,再用闭运算填补苹果表面反光导致的内部孔洞。这一步看似简单,但对后续轮廓提取的效果影响很大,如果掩膜边缘毛刺太多,轮廓周长 P 会被高估,圆度值就失真了。

第四步是提取最大连通域,排除误检区域。如果画面里意外出现其他物体,最大连通域筛选能保证我们操作的对象始终是苹果。然后根据掩膜与原始图像做按位与,得到干净的果实区域图像,后续所有特征提取都在这个区域内完成。

这段代码很多人写过,但我建议不要直接抄,而是要理解每一步是为什么。比如形态学核的大小,我用的开运算核是 3x3,闭运算是 15x15。核太大会把真实缺陷也抹掉,核太小又填补不了反光孔洞。这个参数需要根据实际拍摄效果调整,没有万能值。

4. 颜色特征提取:基于 HSV 空间实现底色与着色面积判定

苹果的颜色分级有两个维度需要分开处理:底色和着色。底色是果皮本身的基色,着色是表面红色素的覆盖情况。这两个概念常被混为一谈,但在分级标准里是完全不同的指标。

4.1 主色判定:给红富士建立颜色指纹

我给每种品种建立了一张“颜色指纹表”,本质是一个二维直方图,横轴是 H 色调,纵轴是 S 饱和度,每个单元统计对应的像素数量。新品种上市前,我会采集 30 到 50 个该品种的正常果样本,用这批样本生成统计模板,然后提取主色调范围和分布峰形。

在实际代码实现中用到的不是复杂的机器学习模型,而是 OpenCV 的直方图统计加阈值过滤。先把苹果区域的像素提取出来,丢弃饱和度极低的像素(那些是反光点),然后在 H 通道上做直方图统计,找到主要峰值位置和半高宽。峰值位置对应主色调,半高宽反映底色分布范围。

这种做法的好处是可解释性极强。如果发现某个苹果的主色调峰值偏移,说明它可能是未成熟果或者光照异常,调试时能直接定位问题。我见过有人一上来就上卷积神经网络做颜色分类,效果可能不错,但出了问题很难排查,而且标注成本高很多。对颜色这种低阶特征,传统方法往往是最优解。

4.2 着色面积比例:一个简单却关键的商业指标

着色面积的计算要更精细一些。不同品种的“红色”定义区间不同,比如红富士的红色在 HSV 空间里大致是 H 小于 10 或大于 170(红色在 OpenCV 的 HSV 中围绕 0 度分布,形成两个区间),S 大于某个阈值。但花牛苹果的红色更深,饱和度和亮度特征又不一样。

我处理两段红区间的办法是把 H 通道做一次映射:把 H 大于 180 的数值减 180,让红色区间连续化,方便统一阈值。然后计算符合条件的像素占总果实像素的比例。

这里有一个常见的坑:苹果表面的高光区域饱和度很低,会被排除在红色判定之外,但这些区域实际上可能是红色果皮。如果不做处理,着色比例会被低估,红色越深的苹果反光越强,误差就越大。我的处理办法是先用闭运算把高光区域“修复”:在高光掩膜的基础上做膨胀,然后从邻近像素的颜色做插值填充。简单说,就是用周围区域的色调信息替代高光区域的丢失信息,保证着色面积统计的完整性。这个方法对普通红色苹果精度足够,能达到产线需求。

4.3 颜色均匀度与色差分布

除了着色面积,部分高端渠道还看颜色均匀度。我计算的是苹果表面像素与主色调的平均色差,用 CIELAB 空间中的 ΔE 来表示。具体做法是先把图像从 BGR 转到 LAB,计算所有像素点与主色参考的色差,再做标准差统计。标准差小说明颜色均匀,标准差大说明表面有杂色斑块。

这个指标不参与基础分级,而是作为附加评分,用于优质果的“挑尖货”。某渠道曾要求底部着色的苹果优先,因为底部着色的果子通常日照充分、糖度更高,这个要求通过分析着色区域在掩膜中的位置分布就能实现,并不需要额外增加硬件。

5. 大小与形状分级:轮廓测量而不是像素长宽

大小测量听起来最简单,但实际做的时候需要处理不少细节。第一个问题是像素尺寸到物理尺寸的标定。方法非常简单:在一张白纸上画一个已知直径的黑色圆片,放在与苹果相同高度的平面上拍照,检测其轮廓直径的像素长度,然后用物理直径除以像素直径得到标定系数。这个步骤不能只做一次就完事,相机或镜头稍微松动,标定系数就失效了,建议每次产线调试前做一次验证。

我用的标定架是一个 3D 打印的小平台,固定高度和位置,放上标准圆片就能快速完成标定,整个过程不到一分钟。

等效直径的计算公式前面提过,使用的是投影面积反推。这里要注意一点:苹果在传送带上可能是侧放或立放,投影形状不同。侧放得到的投影面积与果实的最大横径相关,最接近商用的“直径”概念。所以如果要在传送带上做动态检测,尽量让苹果以固定姿态通过相机视野。我在实验台上设计了 V 型托槽,保证苹果的主轴方向一致朝上,这样做出来的测量结果重复性很高。

形状判定中,圆度和丰满度是两个组合指标。计算公式前面说过了,但实际判定时建议不要用单一阈值做硬切分,而是采用区间评分。比如圆度 0.9 以上为果形优,0.85 到 0.9 为良,0.8 到 0.85 为合格,低于 0.8 为畸形。连续评分比一刀切更符合实际需求,也方便与颜色、大小等其他维度的分数做加权汇总。

具体代码实现是这样的:找到最大轮廓后,用 contourArea 计算面积,用 arcLength 计算周长,然后按公式计算圆度。丰满度则通过计算轮廓的凸包面积与轮廓面积的比值得到。苹果表面如果有凹陷,轮廓的凸包面积会明显大于实际轮廓面积,比值越接近 1 说明表面越饱满。

还有一个小细节:图像边缘的苹果轮廓会被截断。如果要准确测量,必须保证苹果完整在视野内,或者对边缘截断情况进行标记并排除。我的系统会在拍摄后自动判断苹果掩膜是否触及图像边界,如果触及就发出提示,建议调整输送位置。这个问题在动态产线上尤其常见,因为苹果落在传送带上的位置不一定在正中央。

6. 表面缺陷检测:边缘比对与色差合并的实用思路

表面缺陷检测是我整个项目里调试时间最长、走弯路最多的部分。苹果缺陷种类多,形态差异大,单一算法很难通吃。我最终的方案是三层筛选加一道人工校验的流程。

6.1 颜色异常检测:找到与底色偏离的区域

第一层是颜色异常检测。在 LAB 色彩空间中,正常果皮的颜色分布相对集中,缺陷区域(碰压伤、腐烂、花斑)通常与周围正常果皮存在色差。我计算每个像素与局部背景均值的色差,超出阈值则标记为候选缺陷区域。为了避免把苹果自身的颜色渐变误判为缺陷,这里使用自适应阈值:以像素周围一定半径内的邻域均值为基准做比较,而不是与全局均值比较。这样能容忍自然渐变,同时捕捉局部突变。

这一步能检出大部分明显的花斑、腐烂区域,但对颜色差异极小的碰压伤无能为力。碰压伤区域的色差可能只有几个 Lab 单位的差异,肉眼都很难看出来,更别提阈值分割了。

6.2 边缘梯度分析:碰压伤的边界线索

第二层从边缘入手。碰压伤区域虽然颜色变化小,但果皮表面会有微小的凹陷,在特定角度光照下会产生边缘阴影或高光变化。我在灰度图上计算梯度幅值,寻找局部区域中梯度分布异常的块。具体操作是:把灰度图分成网格,统计每个网格的梯度均值与整体均值的偏离程度。碰压伤位置因为表面曲率突变,梯度分布会出现局部簇状异常。

这个方法在侧向光源条件下效果最好。正打光下凹陷区域的反差太小,几乎看不到;改用人射角度较大的侧光之后,缺陷区域在图像上会呈现局部暗带或亮带,梯度特征明显增强。所以我的采集方案在环形主光源之外,额外加了一路可切换角度的侧向辅助光,专门用于缺陷检测模式。这个设计思路是在调试了各种光源方案之后总结出来的。

6.3 形态学筛选:排除果点与果锈等干扰

第三层是形态学筛选。颜色异常和边缘分析都会产生大量小面积的误检区域,主要是果点(果皮上的小斑点)和果锈。果点的特点是面积小、形状近似圆形且分布分散;真正的缺陷往往面积更大、形状更不规则。

我按照候选区域的面积、圆形度、长宽比设定过滤条件:面积过小的直接丢弃,圆形度接近 1 的也倾向于判为果点。但有一个例外:如果某个区域面积不大,但颜色偏离程度非常严重,比如深褐色或黑色,仍然要判为缺陷,因为这很可能是虫眼。

三层筛选的输出是一份“缺陷候选地图”。实际测试中,这套方案对腐烂斑、花斑、严重碰压伤的检出率很高,对轻微碰压伤的检出率略低,但实用性已经可以接受。毕竟人工分级对轻微碰压伤同样容易漏检,系统的稳定性反而更好。

最后加一道校验逻辑:多个缺陷区域位置相邻时,合并为一个缺陷并计算总面积。分级决策中,缺陷面积占果实投影面积的比例是一个连续值,按比例赋予不同档位。

7. 综合分级决策:让分级标准可配置,而不是写死在代码里

特征都提取完了,最后要回答的问题是:一个苹果,大小第几等、颜色第几等、缺陷是否超标,最终应该归入哪个总等级?这里需要一套清晰的分级决策表。

7.1 分级决策表与可配置权重

我设计的决策逻辑不是简单的加权求和,而是先按缺陷做硬性否决,再按大小和颜色做组合定级。原因很现实:有腐烂斑的苹果无论如何不能进一级果,哪怕它又大又红。

硬性否决项有三个:缺陷面积占比超过阈值(比如一级果不超过 2%)、存在虫眼类深色斑点、果形严重畸形。任何一项触发就直接降级或淘汰。

通过硬性否决后,剩余指标按得分累加。大小得分、颜色得分、形状得分分别映射到 0 到 100 分区间,然后加权汇总。权重是可配置的,存放在一个 JSON 文件里,果企可以根据不同渠道的要求调整。比如某大型商超渠道更看重颜色,权重设为 0.5,大小 0.3,形状 0.2;电商小规格装渠道更看重大小均匀性,就把大小的权重提高。

这种做法在工程上非常实用。因为需求方常常会提“能不能把颜色要求再严格一点”这种新需求,如果权重写在代码里,每次都要改程序重新部署。做成配置文件后,现场调整只需要改几个数字,大大减少了沟通成本。

7.2 分级输出的可视化与追溯

除了给出最终等级,系统还会输出一张标注图像,把检测到的轮廓、缺陷区域、尺寸信息、颜色信息直接画在图上。这张图有两个用途:一是给现场操作人员做人工复检参考,二是给果企留档追溯。万一后续果品出现客诉,可以回头查这套系统当时拍下的图像记录,判断是不是分级环节出了问题。

我建议所有图像数据按批次存储,文件名包含时间戳和传送带序号。存储目录按日期组织,定期清理超过保留期的数据。虽然增加了一些硬盘开销,但换来的可追溯性在商业项目中非常值得。

7.3 系统集成与通信方式

系统软硬件之间的通信,我用的是简单的 TCP 协议。检测程序在收到某个硬件触发信号(光电传感器)后开始采集和分析,分析完成后把结果通过 TCP 发送给下位机,由下位机驱动执行机构把苹果分配到对应等级的通道。这部分在实验阶段可以用串口助手模拟验证,逻辑非常简单。

但这里有一个容易被忽略的时序问题:分析耗时必须小于苹果在输送带上通过工位的时间。苹果在传送带上移动距离为 D,速度为 V,可用分析时间就是 D/V。我的单帧处理时间大概在 150 到 200 毫秒(包括采集和所有特征提取),所以对应的产线速度其实有限。提高产线速度就要考虑更高效的实现方式,比如并行流水线、使用多线程或者把部分计算放到 GPU 上。如果明确要求每秒处理十个以上苹果,纯图像处理方案的硬件成本会明显上升,需要用更高性能的相机和算子优化。这个现实约束在项目初期就要和客户确认清楚。

8. 参数调试与现场工程化的几个教训

系统跑通和跑稳之间隔着一大段距离。我在这个项目里收获最多的不是哪段代码写得多巧妙,而是那些只有在现场才会暴露出来的问题。

8.1 光照衰减与光源老化的隐患

LED 光源用久了会有亮度衰减,尤其在车间粉尘环境下衰减更快。我的系统在连续运行两周后,发现同一箱苹果的着色比例出现了系统性偏差,排查了很久才锁定是光源亮度下降导致的。

解决办法是在系统中加入一个标准色卡的定期校验流程:每天开机后拍一张标准色卡,对比关键通道的均值。如果偏离基线超过一定百分比,就提示需要进行光源校准或更换。这个小工具非常简单,但能避免系统在不知不觉中偏离精度。

8.2 苹果表面水分与灰尘干扰

从冷库出来的苹果表面常常有冷凝水珠。水珠会形成局部高光,干扰颜色和缺陷判断。如果是露天存储的苹果,表面还可能附着泥点,泥点会被误判为缺陷区域。

针对这个问题,我在预处理阶段增加了一层高光和水珠掩膜检测。根据高光区域的形状和亮度特征,将其从缺陷候选中排除。泥点的问题处理起来更棘手,因为它确实会遮挡果皮信息。我目前的策略是:如果泥点面积超过一定比例,将样本标记为“待人工复核”,而不是直接判级。人工复检的成本虽然存在,但比误判带来的客诉成本低得多。

8.3 不同批次苹果的标准漂移

不同批次的苹果即使同一个品种,颜色分布也会有差异。早期系统用固定的 HSV 阈值做颜色判定,发现某年新上市的苹果着色普遍偏浅,被误判为未成熟。

后来我把颜色特征判定改成了动态基准模式:每批次开始前,先用抽检的 10 个样本建立该批次的基准颜色分布,然后用偏离基准的程度做分级,而不是用绝对阈值。这个方法在实际生产中大幅降低了批间误判率。当然,前提是同一批次内苹果本身的品质差异不能太大,否则基准本身就不可靠。

8.4 建议每一个做实机项目的朋友

尽量不要在仿真环境里调参数。有些问题只有把设备摆在真实场地里才会出现,比如车间振动、传送带晃动、隔壁设备产生的电磁干扰。我的习惯是:先跑通功能,再花 30% 的时间做鲁棒性测试,然后至少用一周时间做长期稳定性观察。宁可自己在现场多盯几天,也不要等客户打电话来说设备出问题。

这套系统做下来,我自己的感受是,机器视觉分级系统的核心竞争力和算法先进程度关系没那么大,更多是在工程细节里抠出来的稳定性。把采集环境控制好、把特征定义清楚、把决策逻辑做可配置、再把现场可能出现的干扰逐一消化掉,这套框架可以复用到很多农产品分选场景。苹果只是第一站。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进