ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于CNN的煤矸石自动分选:从图像采集到工控机部署的落地实践

基于CNN的煤矸石自动分选:从图像采集到工控机部署的落地实践 简介这份PDF文献面向从事煤炭分选、工业视觉检测与深度学习应用的研究人员和工程技术人员针对传统煤矸石分选依赖灰度信息、易受色差与照明条件干扰的局限提出并验证了一套基于CNN卷积神经网络的自动分选方案。资源包内仅含1个PDF文件大小约1.98MB完整收录了该研究论文的摘要、CNN网络架构说明、煤块与矸石图像纹理特征的多层次提取方法及测试数据读者可据此了解卷积层、池化层与全连接层在图像分类任务中的协同机制并掌握从灰度均值对比到深层特征分类的研究思路演进。文中测试结果表明该方法不受样本色差影响识别准确率达到92%对深度学习在计算机视觉与工业分选场景中的落地具有参考价值。目前已有338人学习关注适合希望将机器学习、数据建模与图像处理技术结合到实际分选问题中的读者研读。1. 煤矸石自动分选从人工选矸到 CNN 推理的落地路径在煤矿地面生产系统里手选皮带旁常年站着拣矸工靠肉眼分辨黑亮的煤和灰暗的矸石一个班下来腰酸背痛分选效率还受情绪和疲劳影响。基于 CNN 卷积神经网络的煤矸石自动分选要解决的就是把这道工序交给摄像头加推理服务皮带上的物料进入视野模型逐帧判断是煤还是矸石再把结果发给执行机构气阀、机械臂或翻板实现不停机分拣。它适合两类人一类是煤矿机电、选煤厂自动化岗位的工程师想用现成视觉方案替换人工另一类是做深度学习落地的人想找一个工业分选场景练手。核心链路并不复杂——图像采集、CNN 分类、坐标映射、执行控制但每一环都有现场约束下面按能复现的顺序拆开讲。2. 煤矸石分选为什么选 CNN从纹理差异到网络结构2.1 煤与矸石的视觉差异到底在哪煤和矸石在可见光下的区分依据主要是颜色、光泽和表面纹理。煤通常呈黑色或黑褐色表面有油脂光泽纹理相对均匀矸石多为灰黑色或灰白色表面粗糙常见层理、裂纹和矿物颗粒。传统图像处理靠阈值分割加形态学特征遇到煤质变化、皮带反光、水雾粉尘就容易失效。CNN 的价值在于它不依赖人工设计的单一特征而是通过卷积核在多个尺度上自动提取边缘、纹理和局部对比度把“看起来像煤”这种模糊判断变成可训练的分类问题。现场光照是最大的变量。井下或地面皮带走廊常见不均匀照明一侧亮一侧暗煤块表面还会反光形成高光斑。如果直接拿原始 RGB 图训练模型很容易学到“亮的就是矸石”这种伪特征。常见做法是先把图像转到 HSV 或 Lab 空间对 V/L 通道做限制对比度自适应直方图均衡CLAHE再送进网络。这一步不是可选项是让模型在换班次、换季节后还能稳住的关键。2.2 选二维 CNN 还是一维 CNN输入形态决定结构热搜里常出现“一维卷积神经网络介绍的文献”但煤矸石分选的主流输入是图像所以基础方案是二维 CNN。一维 CNN 更适合处理光谱曲线或振动信号比如近红外光谱分选、振动筛状态监测。如果你手里只有灰度线阵相机逐行扫描的数据可以把每一行像素当作一维序列用 1D-CNN 做快速判别但会丢失块状物料的二维形状信息误判率通常高于 2D 方案。一个务实的选型顺序是先确认相机类型。面阵相机拍静态或准静态物料用 2D-CNN线阵相机配传送带连续扫描可以把多行拼成二维图再送 2D-CNN也可以先用 1D-CNN 做粗筛再用 2D-CNN 复核。对于大多数中小型选煤厂200 万像素工业面阵相机加补光灯配合轻量 2D-CNN是性价比最高的起点。2.3 轻量网络结构把 ResNet 砍到能跑在工控机上现场推理设备往往是工控机加一张入门级显卡甚至只有 CPU。直接上 ResNet-50 推理延迟可能超过 100 ms皮带速度 2 m/s 时物料已经移动 20 cm执行机构来不及响应。我一般会从 MobileNetV3-Small 或自定义的 4 层卷积网络起步输入尺寸压到 224×224 或 192×192通道数控制在 16/32/64/128。下面是一个可直接训练的最小 CNN 结构用 PyTorch 写输入是 3×224×224 的煤矸石图像块import torch import torch.nn as nn class CoalGangueCNN(nn.Module): def __init__(self, num_classes2): super().__init__() # 第1个卷积块提取边缘和颜色斑块输出 32×112×112 self.block1 nn.Sequential( nn.Conv2d(3, 32, kernel_size3, padding1), nn.BatchNorm2d(32), nn.ReLU(inplaceTrue), nn.MaxPool2d(2) ) # 第2个卷积块提取纹理和局部形状输出 64×56×56 self.block2 nn.Sequential( nn.Conv2d(32, 64, kernel_size3, padding1), nn.BatchNorm2d(64), nn.ReLU(inplaceTrue), nn.MaxPool2d(2) ) # 第3个卷积块提取更大范围的结构输出 128×28×28 self.block3 nn.Sequential( nn.Conv2d(64, 128, kernel_size3, padding1), nn.BatchNorm2d(128), nn.ReLU(inplaceTrue), nn.MaxPool2d(2) ) # 全局平均池化避免全连接层参数过多 self.gap nn.AdaptiveAvgPool2d(1) self.fc nn.Linear(128, num_classes) def forward(self, x): x self.block1(x) x self.block2(x) x self.block3(x) x self.gap(x) x torch.flatten(x, 1) return self.fc(x) if __name__ __main__: model CoalGangueCNN() dummy torch.randn(8, 3, 224, 224) # 模拟一个 batch 的输入 out model(dummy) print(out.shape) # 期望输出 torch.Size([8, 2])这段代码的逻辑说明三个卷积块逐步把空间尺寸从 224 降到 28通道数从 3 升到 128让网络先看局部边缘再看整体纹理。每个卷积后接 BatchNorm 和 ReLUBatchNorm 对现场光照波动有稳定作用。全局平均池化替代大全连接层参数量少工控机上推理更快。参数方面kernel_size3是纹理任务常用值padding1保持尺寸如果显存紧张可以把第一层通道降到 16输入尺寸改成 192。训练时类别不平衡很常见——煤块远多于矸石损失函数用带权重的 CrossEntropyLoss权重按训练集频次倒数设置。3. 从现场图像到训练集采集、标注与增强的实操细节3.1 相机安装与触发别让运动模糊毁掉数据集相机一般装在皮带上方 60100 cm镜头垂直向下配条形 LED 补光灯避免频闪。皮带速度超过 1.5 m/s 时必须用硬触发光电传感器检测到物料进入视野触发相机曝光曝光时间压到 200 μs 以内否则图像拖影会让煤矸石边缘糊成一片。我见过一个现场用卷帘快门相机加软触发结果每张图都有 35 像素的横向模糊模型在验证集上准确率 92%上线后掉到 70%血泪经验就是先解决运动模糊再谈模型。采集时按班次分文件夹早中晚各采一批覆盖晴天、阴天、开灯、关灯等光照条件。每个类别至少 2000 张有效图像块煤和矸石比例尽量接近 1:1不够就用数据增强补。图像块从整幅图中裁剪裁剪框以物料质心为中心边长取物料外接矩形长边的 1.2 倍保证不切掉边缘。3.2 标注规范二分类也要定边界煤矸石分选通常是二分类但边界样本必须定义清楚。煤矸混合块、表面被煤粉覆盖的矸石、反光严重的煤块这三类最容易让标注员犹豫。我的做法是煤矸混合块单独标为“混合”训练时要么剔除要么归入矸石类并在部署时由执行机构二次确认表面覆煤的矸石按实际密度判断如果整块密度接近矸石就标矸石反光煤块保留但要在增强时加入随机亮度扰动让模型学会忽略高光。标注文件用 CSV 或 JSON 都行字段至少包含图像路径、类别、采集班次、光照标签。光照标签在排查模型偏置时很有用——如果模型在“关灯”子集上准确率骤降说明补光或增强不够。3.3 数据增强模拟现场粉尘与光照变化增强策略要贴着现场来不能只用随机翻转。下面这段用 Albumentations 做增强重点模拟粉尘、光照不均和轻微运动模糊import albumentations as A from albumentations.pytorch import ToTensorV2 train_transform A.Compose([ A.RandomResizedCrop(224, 224, scale(0.8, 1.0)), # 模拟物料远近变化 A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(brightness_limit0.3, contrast_limit0.3, p0.7), A.HueSaturationValue(hue_shift_limit10, sat_shift_limit20, val_shift_limit20, p0.5), A.GaussNoise(var_limit(10.0, 50.0), p0.3), # 模拟粉尘噪声 A.MotionBlur(blur_limit3, p0.2), # 模拟轻微拖影 A.CLAHE(clip_limit2.0, p0.5), # 抑制光照不均 A.Normalize(mean(0.485, 0.456, 0.406), std(0.229, 0.224, 0.225)), ToTensorV2() ])逻辑说明RandomResizedCrop让模型适应不同距离的物料亮度和对比度扰动覆盖早晚光照变化GaussNoise和MotionBlur模拟粉尘与轻微运动模糊CLAHE在增强阶段就做局部对比度均衡和推理前处理保持一致。参数上brightness_limit0.3是经过现场对比的再大可能把煤块提亮成矸石外观MotionBlur的blur_limit3只做轻微模拟真实拖影严重时应该改硬件而不是靠增强硬扛。验证集和测试集不要做随机增强只做 resize、CLAHE 和归一化保证评估结果可复现。训练集、验证集、测试集按 7:2:1 划分且按采集班次分层抽样避免某一班次全部进训练集导致评估虚高。4. 训练、量化与部署让模型在工控机上跑到 30 FPS4.1 训练参数学习率、批大小与早停训练用 AdamW初始学习率 1e-3批大小 32权重衰减 1e-4。如果显存不够批大小降到 16学习率按线性缩放降到 5e-4。训练轮数先设 50配合早停验证集损失连续 8 轮不下降就停保留验证集准确率最高的权重。类别不平衡时在损失函数里加权重import torch from torch.utils.data import DataLoader, WeightedRandomSampler # 假设训练集里煤 5000 张矸石 2000 张 class_counts [5000, 2000] class_weights [1.0 / c for c in class_counts] sample_weights [class_weights[label] for _, label in train_dataset] sampler WeightedRandomSampler(sample_weights, num_sampleslen(sample_weights), replacementTrue) train_loader DataLoader(train_dataset, batch_size32, samplersampler, num_workers4)逻辑说明WeightedRandomSampler让每个 batch 里煤和矸石比例接近 1:1避免模型偏向多数类。class_weights也可以直接传给CrossEntropyLoss的weight参数两种方式选一种即可。num_workers4在工控机上够用太多会抢 CPU 影响其他进程。训练过程中每轮记录训练损失、验证损失、验证准确率和矸石类的召回率。矸石召回率比整体准确率更重要——漏掉矸石意味着煤质不达标误把煤判成矸石只是浪费一点产量。我一般要求矸石召回率不低于 95%整体准确率不低于 93%达不到就回去查数据质量和增强策略。4.2 量化与推理加速从 PyTorch 到 ONNX Runtime训练完的模型直接部署在入门级显卡上可能只有 15 FPS。用 ONNX Runtime 加动态量化CPU 上也能跑到 2530 FPS。导出步骤如下import torch import torch.onnx model CoalGangueCNN() model.load_state_dict(torch.load(best_model.pth, map_locationcpu)) model.eval() dummy_input torch.randn(1, 3, 224, 224) torch.onnx.export( model, dummy_input, coal_gangue.onnx, input_names[input], output_names[output], dynamic_axes{input: {0: batch}, output: {0: batch}}, opset_version11 )导出后可以用 ONNX Runtime 的量化工具做动态量化from onnxruntime.quantization import quantize_dynamic, QuantType quantize_dynamic( coal_gangue.onnx, coal_gangue_quant.onnx, weight_typeQuantType.QUInt8 )逻辑说明dynamic_axes让 batch 维度可变方便一次推理多帧。QuantType.QUInt8把权重从 FP32 压到 8 位整数模型体积缩小约 4 倍CPU 推理速度提升明显。量化后必须用测试集重新评估如果矸石召回率掉超过 2 个百分点就回退到 FP32 或改用静态量化。参数上opset_version11兼容性较好工控机上的 ONNX Runtime 版本不要太旧。4.3 与执行机构联调坐标映射和延迟补偿模型输出的是图像块类别执行机构需要的是物料在皮带上的物理位置。如果相机固定、皮带匀速可以用标定板建立像素坐标到物理坐标的映射在皮带旁放已知间距的标记拍一张图算出每像素对应的毫米数。物料质心像素坐标乘以比例系数加上相机到气阀的固定距离就是气阀触发延时。延时补偿公式触发延时 相机到气阀距离 / 皮带速度 - 推理耗时 - 通信耗时。假设距离 1.5 m皮带速度 2 m/s推理耗时 30 ms通信耗时 10 ms则触发延时 0.75 - 0.03 - 0.01 0.71 s。这个值要在现场用高速相机或示波器实测校准不能只靠计算。我见过因为延时设错 50 ms气阀把矸石吹到了煤流里整批煤质超标。联调时先用彩色标记物代替真实物料确认触发位置准确再换真实煤矸石跑空载和负载测试。记录每次触发的图像、推理结果和实际动作形成日志方便回溯误判。5. 避坑与排查煤矸石分选上线后最容易翻车的 5 个点5.1 现象验证集准确率 95%上线后掉到 70%原因训练集和现场分布不一致。常见情况是训练集在白天采集上线后夜班光照色温变化大或者训练集用某一种煤换煤层后煤的反射率变了。解决上线前用现场相机在目标班次采集至少 500 张图做测试不达标就补数据重新训练。部署后每周抽检 200 张在线图像监控准确率漂移。5.2 现象模型把反光煤块判成矸石原因高光区域在训练集里被标注为矸石特征或者增强时亮度扰动不够。解决在增强里加入随机高光模拟或者用偏振镜减少镜面反射。如果已经上线可以在推理前加一步高光检测对高光面积超过阈值 30% 的图像块降低置信度转人工复核。5.3 现象推理延迟忽高忽低气阀触发不稳定原因工控机上同时跑着组态软件、数据库和推理服务CPU 抢占导致延迟抖动。解决给推理进程设 CPU 亲和性绑定到独立核心用 ONNX Runtime 的intra_op_num_threads限制线程数把推理服务做成独立进程通过共享内存或本地 socket 通信避免 Python GIL 影响。5.4 现象粉尘积累在镜头上图像越来越模糊原因现场粉尘大镜头没有定期清洁。解决加装气幕吹扫装置用压缩空气在镜头前形成风帘设置图像清晰度监控用拉普拉斯方差判断模糊程度低于阈值就报警。清洁周期根据粉尘浓度定一般每班吹扫一次每周擦拭一次。5.5 现象矸石召回率够高但煤里还是混矸石原因执行机构响应慢或气阀压力不足模型判对了但没吹掉。解决检查气阀从收到信号到动作的延迟用示波器测确认气压稳定在 0.60.8 MPa如果物料粒度差异大小矸石需要更高压力或更近的吹嘴。模型侧可以调低矸石判定阈值让更多可疑块进入吹除流程代价是可能多吹掉一些煤。6. 进阶技巧用置信度分级和在线学习把误判压下去模型上线后最值钱的不是准确率数字而是误判样本。我习惯在推理服务里加一个置信度分级逻辑输出概率大于 0.9 的直接执行0.70.9 的标记为可疑低于 0.7 的转人工复核或二次拍摄。可疑样本和人工复核结果自动存盘每周导出一次挑出模型判错的图补进训练集做增量训练。增量训练时学习率降到 1e-4只训练最后两个卷积块和分类层避免把之前学到的特征冲掉。另一个技巧是时间一致性过滤。皮带上的物料在连续多帧里会被拍到多次如果单帧判断有波动可以用滑动窗口投票最近 5 帧里至少 3 帧判为矸石才触发气阀。这能压掉大部分随机误判代价是增加约 23 帧的延迟皮带速度不高时完全可接受。验证方法上不要只看测试集准确率。我会在测试集上画混淆矩阵单独看矸石类召回率和煤类精确率再用 Grad-CAM 可视化模型关注区域如果热力图集中在皮带背景而不是物料本身说明模型学到了伪特征需要重新裁剪图像块或加背景随机化增强。最后说个习惯每次现场调试我都会把相机参数、模型版本、阈值、延时值写在一张标签上贴在控制柜门内侧。换人维护时不用翻聊天记录看一眼就知道当前配置。这个方案值不值得做取决于你的现场光照能不能稳住、执行机构延迟能不能压到 100 ms 以内。这两条满足CNN 分选就能把拣矸工从皮带旁解放出来满足不了先改硬件再谈模型。希望帮到你。本文还有配套的精品资源点击获取
返回列表