☰
基于Mask R-CNN的木材板材智能计数与识别系统实践
2026/10/21 3:08:39 网站建设 项目流程

做木材板材智能计数与识别这个项目,起因其实很朴素。朋友经营一家板材仓储厂,有一回我去车间找他,正碰见质检员蹲在堆垛边,一张一张翻板材的侧棱,数完一遍又数第二遍,因为第一遍和第二遍差了四张。那一堆板子少说两百八十张,来回折腾了快四十分钟。当时我就说:这个活儿,其实可以交给机器。后来我们真的立项做了,核心方案就是基于Mask R-CNN的木材板材智能计数与识别系统——相机拍照,模型在图像里分割出每一块板材的顶面轮廓,再在后处理里数出准确数量,同时按规格切分不同类别。

这篇文章把这个项目从数据采集、标注、训练、后处理到产线部署的完整过程复盘一遍,重点是几个反复踩过的坑。如果你也在做类似的工业视觉计数方案,比如管材、型材、瓷砖、纸板,这套思路基本可以直接平移。

1. 板材计数为什么需要实例分割:从堆场点板说起

1.1 板材盘点现场的三个真实痛点

板材仓储场景的计数,外面人看着简单,真正到现场做一遍才知道烦。

第一是堆叠导致的信息不可见。板材不像纸箱有规整的外包装,码在一起就是一层层压着,顶面只能看到最上面一层,要看清层数得从侧棱数。很多厂的做法是拿个手电筒,对着侧棱一条一条数分层,再乘每层板数。侧棱上板材之间几乎没有视觉缝隙,数着数着就容易串行,数完自己都拿不准到底是多少。

第二是近距离高重复劳动,眼睛非常容易疲劳。同一摞板子规格高度一致,人工翻看时一旦被外界打断,基本就得从头再来。我们调研的现场小哥说,清点一摞三百张的板材,顺利的话二十分钟,不顺的话四十分钟起步,误差率大概在2%到3%。这个误差对库存台账是个持续放大的问题:每批都差一点,月底盘点对不上账,只能再拉人复核。

第三是数据不能即时电子化。人工点完还要写在纸质单子上,再录进系统,信息流转慢。厂长想看的实时库存,永远滞后半天以上。

这三个痛点指向同一个需求:能不能有一台设备,对着板材堆垛拍一张照片,直接输出“这一堆有多少块、分别是什么规格”。这就是这个项目最原始的出发点。

1.2 为什么普通目标检测不够用

初期我们也考虑过用普通目标检测。目标检测最典型的输出是矩形框,但板材计数恰恰是矩形框最不擅长的事情。

板材从顶面看,绝大多数是规则的矩形,两块板并排摆放时,相邻边界几乎重合;稍微错开一点,一个矩形框就会同时框住两到三块板的一部分。检测框本质上是一个“包含该物体的最小矩形”,当多个物体紧紧挨在一起时,框和框之间的IoU会非常高,非极大值抑制很容易把其中一块的检测框直接合并掉。

我们拿一个早期的检测模型做过实验,在板材平铺但紧贴的图片上,mAP看着还行,但数数完全不可用:两块板被当成一块、三块板被当成一块的情况比比皆是。原因不在模型性能,而是输出表达方式本身就限定死了——矩形框没能力表达“紧贴在一起的两个独立物体”。

1.3 Mask R-CNN能输出什么:模型原理与直观理解

换到实例分割,问题就绕过去了。Mask R-CNN在目标检测两阶段结构的基础上加了一个掩码分支:检测阶段先用区域建议网络(RPN)生成候选框,再用ROI Align把每个候选区域对齐到固定尺寸的特征图,最后并行输出三样东西——物体类别、边界框,以及逐像素的掩码。

用大白话说,目标检测是“拿一个相框把人框住”,实例分割是“拿一把剪刀把人像从照片里完整剪下来,再涂上颜色”。每一块板材对应一个独立的剪影,哪怕两块板紧紧贴在一起,只要掩码边界能把它们区分开,后处理就能数成两块。这就是我们选择Mask R-CNN作为核心模型的原因。

Mask R-CNN里还有一个处理细节值得提:ROI Pooling升级为ROI Align,解决了特征图对齐时的量化误差。这个问题在板材这种直角边界清晰的目标上尤其明显——边界对不齐,掩码轮廓会呈现锯齿状,后处理拿到的面积和周长都不可靠。实际对比下来,ROI Align对掩码精度的提升,在板材场景比在通用物体场景更显著。

2. 数据准备阶段最容易踩的坑

2.1 采集视角与相机布局:决定后面所有标注工作

数据怎么采,直接决定模型能不能用。

我们最初的假设是:在堆垛正上方垂直安装相机,俯拍得到完全俯视的顶面图像。这个想法听上去很标准,实际装到产线试拍才发现问题:板材堆放在厂房里,上方往往有行车、吊臂、传送带,垂直安装很难找到净空;而且垂直拍摄时侧面光源会被板材边缘遮挡,顶面形成大面积阴影。

最终采用的是斜上方俯视安装,相机离地大概3.2米,光轴与地面法线成25度左右的夹角。这样既能覆盖约1.5米乘2米的堆放区域,又避开了行车轨道。代价是板材顶面在图像里会有轻微透视变形,矩形不再是严格矩形。这个变形在标注和推理时都得接受,好在板材计数本身不依赖绝对精确的几何定位。

光照上我们吃过一次亏。起初直接用厂房里的混合照明,白天有自然光,晚上开灯,同一个位置上午和下午拍出来的板材颜色差异极大,导致模型白天效果尚可,傍晚以后误检率明显上升。后来在相机两侧加了两条长条光源,亮度调到室内环境光之上并保持恒定,情况才稳定下来。工业现场做项目,“光照一致性”往往比“光照亮度”更重要,这句话我是深有体会。

2.2 标注规范:遮挡板材怎么标、细节边界怎么抠

标注工具我们用的labelme,手动画多边形,几百张图下来,最大的心得是标注规范要先定死,否则返工返到怀疑人生。

最容易返工的坑是遮挡板材的标注方式。板材堆垛里经常出现上层压下层、斜搭等情况,下层板材只露出一部分。一开始我们要求标注员只画可见部分,结果训练出来的掩码大量缺角,计数倒是没太大问题,但后期按规格分类时形状信息全乱了。后来改成:只要能判断出板材的完整矩形轮廓,就沿着完整轮廓标,把被压住的部分也连着画上去,让掩码之间允许互相重叠。实例分割模型是支持重叠掩码的,每块板对应一个独立实例,训练时都会保留。这个改动让后期分类的准确率明显回升。

还有一个细节是板材端头细节的处理。旧板材边缘会有破损、毛刺,标注时不要为了“美观”去修圆滑,也不要只画到半途。Mask R-CNN的掩码分支是逐像素预测,标注边界形状直接影响它学到的轮廓特征,手绘多边形的点尽量贴着板材外沿走,不要大段拉直线代替。

2.3 数据增强策略:哪些增强真正有效

数据增强是项目里性价比最高、但也最容易被用过头的东西。

对板材这类纹理强、方向固定的目标,我们在训练里使用了随机水平翻转、随机缩放(0.8到1.2倍)、随机亮度扰动和少量高斯噪声。实测下来,随机翻转和随机亮度最有价值,因为它们模拟了板材堆放角度变化和现场光环境波动。

我反而建议慎用随机裁剪和大幅旋转。板材的长宽比是有业务含义的,乱旋转会让模型把“横着的板”和“竖着的板”学混淆,尺寸分类就乱了。随机裁剪切得太狠,板上纹理信息残缺,模型容易学着用纹理碎片猜物体,而不是学整体轮廓。

第一批数据集是1280张图像,标注了约16000个板材实例。其中80%用来训练,15%做验证,5%做测试。对实例分割任务来说,这个数量不算多,但每张图里的板材密度高,有效实例数足够,模型还是能稳定收敛。

3. 模型训练与调参记录

3.1 框架与预训练模型的选择

模型主体直接用开源实例分割框架实现,重点不是复现网络结构,而是把训练和部署的流程走顺。我选的是MMDetection,理由很简单:配置中心化,训练脚本和推理接口统一,切换backbone、调整anchor、改loss都是一行配置的事,迭代效率在工业项目里非常重要。

backbone我们一开始用ResNet-50-FPN,初始化直接加载在COCO上预训练好的权重。预训练的好处是网络已经学会了丰富的低级特征,比如边缘、角点、纹理,换到板材这种新领域只需要迁移高层语义,收敛明显更快。

第一轮训练跑了36个epoch,验证集上mask AP在36%左右。对跨领域的新数据集来说,这个值正常。但计数任务大家只看最终数量准不准,AP只是中间指标,我们很快就发现还要在后处理上花更大力气。

3.2 训练超参数与资源清单

训练超参数这一块,我记录一下当时的实际配置供参考:

参数取值说明
输入尺寸短边随机640~960,长边限制1333模拟不同拍摄距离
batch大小4(2卡×2)受显存限制
初始学习率0.005按线性缩放规则从0.02等比缩小
优化器SGD,momentum 0.9收敛稳定性好
weight decay0.0001常规配置
训练轮数36 epoch验证指标在30轮后基本平稳
warmup500步线性预热防止开局震荡

学习率这里值得多说一句。很多开源配置默认batch 16、lr 0.02,这是经过调优的搭配。我把batch降到4之后,如果保持0.02,训练明显震荡、掩码学不精细。按线性缩放规则,lr应该大致等比缩小,所以设为0.005。这个规则不是严格的,但作为起点很实用。

3.3 验证指标与收敛情况

验证阶段我们同时看两组指标。第一组是通用的mask AP与边界框AP。第二组更贴近业务——把验证集每张图输入模型,统计“预测数量/标注数量”的偏差分布。通用指标好不代表业务指标好,我们见过mask AP高但计数偏差波动大的模型,原因通常是板材密集区有个别掩码被漏掉或重复。

最终模型在验证集上的mask AP约42.5%,预测数量和标注数量的平均绝对偏差在2.1张左右。这个水平已经可以进入后处理优化阶段了,但离产线要求的误差不超过一张还有距离。

4. 计数后处理:从掩码到准确数量

4.1 模型输出直接数数为什么不稳

模型跑完,返回的是实例列表,每个实例包含类别、边界框、掩码和置信度。最直观的数数方式是直接统计实例数量,但直接统计出来的数字基本不能用。

第一,置信度阈值没选好之前,低分误检和高分漏检并存。板材侧棱上的阴影纹理经常生成一些高分“假掩码”,阈值设低,这些假目标全混进来;设高了,被压在下面只露出一角的板材会被丢掉。对每个实例做置信度筛选时,阈值不是拍脑袋定的,而是用验证集的PR曲线来确定,最后定在0.5比较合适。

第二,同一块板可能被预测成两个重叠实例。板材中间如果有分隔线、裂缝,模型会把一块板拆成两半输出两个掩码。这种情况下我们做了掩码合并:两个掩码的IoU大于0.5就合并成一个实例,边界取置信度高的那个。不处理这一步,数量会凭空多出不少。

4.2 连通域分析与粘连板材分离

针对“一块板被拆成两个掩码”和“两块板粘连成一个掩码”这两类问题,后处理做了两层修正。

第一层是连通域检查。每个实例的掩码是二值图,用连通域标记拆成独立区域。如果同一个实例掩码包含两个明显分离的大区域,且面积接近,就作为两块板拆分处理,分别计算各自的外接矩形和面积。

第二层针对掩码只有“一条窄脖子”连着的粘连情况,用形态学开运算先断开细连接,再重新做连通域。断开后两边面积都超过最小板材面积阈值,就记为两块。这一步的效果取决于图像分辨率,板材在图像里像素宽度越小,后处理能做的越有限,所以拍摄距离不能拉太远。

4.3 面积过滤与边界截断策略

还有一个很影响计数准确度的细节:图像边缘。

板材堆垛会有些板子刚好压在图像边界上,模型只能看到半块。这种半块如果直接数,数量是对的——它就是一块板;但直接保留的话,它的面积比完整板小很多,尺寸分类会掉到错误类别,也容易和远处的小块误检混在一起。

我们的处理策略分三步:第一步,用最小面积阈值过滤真噪声,面积小于全图0.1%的掩码直接丢弃;第二步,对接触图像边缘的掩码做标记,接触长度超过掩码边界五分之一就标注为“边缘截断”,不参与规格分类,但保留计数;第三步,后处理结果里同时输出“完整板数量”和“含截断板总数量”,由业务侧决定用哪个口径。

5. 实测中的误检漏检:一次完整的排查链路

5.1 把Badcase可视化:错误分类的三个高发模式

模型和后处理跑通之后,真正的硬仗在实地测试。

我们把现场采集的200张新图喂给系统,逐张查看输出掩码叠在原图上的效果,把所有错误截图存档,再按模式分类。高发错误集中有三种。

第一种是侧棱线误检。板材堆叠时侧棱形成一条条平行线,模型偶尔会把几条平行线组成的区域当成一块很薄的板。这类误检在斜上方视角尤其多,透视变形让板材顶面和侧面的分界变模糊。

第二种是压叠漏检。上层板材完全遮住下层板的一部分时,模型对露出的窄条区域信心不足,经常直接跳过。阈值定在0.5时,这个模式的漏检率最高。

第三种是同色粘连。深色板材和阴影背景混在一起,掩码边界会“溢出”,把两块板的边界连成一片,后处理里的形态学分离也不是每次都能断开。

5.2 逐类修正:数据、anchor与阈值三板斧

针对三类问题,我们分别做了处理,而不是简单粗暴调一个参数。

侧棱误检:在训练数据里补充了大量“侧棱+端面”特写图像,专门让模型见过板材堆的侧面结构。同时把输入分辨率从短边800提到短边1000,侧棱线的细微纹理在更高分辨率下更容易被区分开。

压叠漏检:把置信度阈值从0.5降到0.4,再靠后处理里的面积过滤清除新增的低分误检。这一降一滤,净效果是漏检明显减少、误检没有反弹。

同色粘连:主要靠后处理里的形态学分离,另外在数据增强里提高亮度扰动强度,让模型对阴影更不敏感。

这个过程中最重要的习惯是每次错误都留下截图,攒成小样本集,一边改一边反复跑回归测试。没有回归测试,今天修了漏检,明天很可能多出一堆误检。

5.3 效果验证:准确率、召回率与计数误差的最终表现

三轮修正跑完,用另一批之前没见过的现场图像做最终验证,计数口径按“含截断板总数量”计算,平均绝对偏差降到0.8张左右。分规格识别的准确率约94%。单张图的计数时间受板材数量影响,这个阶段还在GPU上跑裸网络,一张图从输入到输出约500到700毫秒,已经够离线盘点场景使用。

6. 部署到产线的性能优化经验

6.1 推理管线设计:异步与队列

离线盘点和产线实时计数,性能要求完全不同。我们的场景是固定机位、自动触发拍照,产线用光电开关检测板材到位后拍照,推理期间没有人在等待,所以对单张延迟不敏感,但对吞吐率和稳定性要求高。

推理侧做成多级队列:采集线程只负责收图和存图,推理线程从队列里取任务,中间用一个有界队列缓冲。这样相机连续抓拍几张,推理进程忙不过来也不会丢任务。队列长度设成8就够用,太长反而让旧图像积压,盘点实时性变差。

6.2 模型加速与精度权衡

PyTorch模型直接推理偏慢,我们导出成ONNX,再转TensorRT,用FP16精度加速。转换过程主要做两件事:把图像预处理算子放到GPU上执行,把模型的动态batch打开,这样一次能处理多张图。

FP16会不会掉精度?我们对同一批100张图做了FP32和FP16的对比,计数结果完全一致,差异只在掩码像素级的微小偏差,业务口径不受影响。转换后单张图推理时间从原来的500到700毫秒,压到160到220毫秒左右,已经足够支撑实时抓拍触发的在线计数了。

6.3 与业务系统对接的细节

最后是输出环节。系统对外提供一个JSON接口,包含三个字段:总数量、各规格数量、每块板材的掩码轮廓点集。业务端用前两个字段做台账,用第三个字段做可视化复核。

这里有个容易被忽略的点:掩码轮廓输出的坐标单位要和相机标定结果对齐。部署时我们做了一次像素到厘米的标定,轮廓点集可以直接换算成板材实际尺寸,业务侧能自动发现“多出来的板”到底是什么规格,而不是只看一个总数。这层标定工作花了两天,但客户验收时的体验完全不一样。

这个项目做完之后还能往板材表面缺陷检测方向扩展,训练数据里已经包含每块板的高精度掩码,缺角、裂纹、划痕都落在掩码范围内,改一下标注规范就能在同一套摄像系统上复用。我自己做完最大的体会是:工业视觉项目到最后,拼的往往不是模型有多新,而是数据规范、后处理边界条件和部署稳定性这些“脏活累活”做得够不够细。希望这份复盘能帮打算做类似计数系统的朋友少走几个弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询