尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

24×40红外小图在太阳能组件异常识别中的工业应用

24×40红外小图在太阳能组件异常识别中的工业应用 简介本资源是面向光伏检测、工业视觉与AI模型训练领域的红外图像数据集专为太阳能组件缺陷识别算法研发与教学实践设计。数据集包含20000张24×40像素的高质量红外图像覆盖12类标注样本——其中11类对应裂纹、热斑、焊带虚焊、EVA脱层等典型光伏组件异常1类为正常无缺陷样本适用于二分类或多分类模型训练、小目标检测baseline构建及轻量级网络如MobileNet、ShuffleNet在边缘设备上的部署验证。资源包共2002个文件主体为20000张jpg格式红外图像辅以1份README.md说明数据组织与标签映射、1个license文件明确使用权限、1个json格式类别定义与划分信息整体压缩后仅15.22MB便于快速下载与本地加载。目前已有813人学习下载适合高校科研、课程实验、Kaggle式入门项目及嵌入式红外识别系统开发参考。1. 24×40红外小图为何能撑起太阳能组件异常识别的工业级任务在光伏电站运维现场热成像仪扫过整片阵列生成的原始红外图动辄百万像素——但真正用于AI模型训练的反而是被裁剪、缩放、归一化后的24×40像素图像。这个尺寸小到连人眼都难以分辨焊带偏移或隐裂走向却构成了当前主流太阳能组件红外异常检测模型的输入基准。原因很实际边缘侧部署的红外模组算力有限嵌入式NPU如瑞芯微RK3566、寒武纪MLU220对输入分辨率极其敏感24×40不是随意定的它恰好匹配典型红外传感器单次采样有效区域的宽高比且在保持12类细粒度异常热斑、虚焊、EVA脱层、电池片碎裂、栅线断裂等11种缺陷1类正常可分性的同时将单张推理延迟压至8ms以内。本数据集共2万张样本全部为真实产线与野外电站采集的原始热图经严格标注与空间对齐后生成不包含合成数据或GAN增强样本。适合需要快速验证轻量模型结构如MobileNetV3-Small、TinyML-ResNet18、部署到无人机巡检终端或PLC集成视觉模块的工程师也适合作为红外小目标分类任务的基准测试集。2. 数据结构解析与加载规范从文件名到标签映射的确定性流程2.1 文件命名规则与标签编码体系数据集以.jpg格式提供所有文件名均为纯数字如7794.jpg、2666.jpg不携带任何语义信息。标签信息完全独立存储于配套的labels.csv文件中该文件需与图像同级目录下存在。CSV结构仅含两列filenamelabel_id7794.jpg32666.jpg0......其中label_id为整数取值范围0–11对应如下业务含义label_id异常类型物理成因说明占比近似0normal无异常组件温度均匀18.2%1hot_spot局部过热常见于旁路二极管失效14.7%2solder_joint焊带虚焊/脱焊12.1%3eva_delaminationEVA胶膜与电池片脱层10.3%4cell_crack电池片隐裂或贯穿裂纹9.8%5finger_loss栅线烧蚀或印刷不良8.5%6busbar_offset主栅偏移或错位7.2%7shunt_resistance并联电阻异常导致局部发热6.4%8moisture_ingress水汽侵入引发边缘发热5.1%9soiling表面污渍鸟粪、灰尘遮挡4.3%10potential_inducedPID效应导致边缘发黑2.9%11contact_failure接线盒接触不良或腐蚀0.5%提示label_id11contact_failure样本极少训练时需采用类别加权损失torch.nn.CrossEntropyLoss(weightclass_weights)或SMOTE过采样否则模型会系统性忽略该类。2.2 PyTorch标准加载器实现强制灰度固定尺寸通道对齐由于红外图像本质是单通道热辐射强度图但OpenCV默认读取为BGR三通道必须显式转换。以下代码构建符合工业部署要求的Dataset类确保输出张量形状恒为(1, 24, 40)且像素值归一化至[0.0, 1.0]import torch from torch.utils.data import Dataset import cv2 import pandas as pd from pathlib import Path class SolarIRDataset(Dataset): def __init__(self, img_dir: str, label_csv: str, transformNone): self.img_dir Path(img_dir) self.labels_df pd.read_csv(label_csv) self.transform transform def __len__(self): return len(self.labels_df) def __getitem__(self, idx): # 1. 读取原始JPEGcv2.IMREAD_UNCHANGED保留原始位深 img_path self.img_dir / self.labels_df.iloc[idx][filename] # 注意红外图通常为16-bit但本数据集已转为8-bit JPEG故用IMREAD_GRAYSCALE img cv2.imread(str(img_path), cv2.IMREAD_GRAYSCALE) # shape: (H, W) # 2. 强制重采样至24x40使用INTER_AREA下采样最优 img cv2.resize(img, (40, 24), interpolationcv2.INTER_AREA) # 注意w,h顺序 # 3. 归一化到[0.0, 1.0]并增加通道维度 img img.astype(np.float32) / 255.0 img torch.from_numpy(img).unsqueeze(0) # shape: (1, 24, 40) # 4. 获取标签 label torch.tensor(self.labels_df.iloc[idx][label_id], dtypetorch.long) if self.transform: img self.transform(img) return img, label # 实例化示例无额外增强保证部署一致性 train_dataset SolarIRDataset( img_dir./solar_ir_images, label_csv./labels.csv )2.2.1 关键参数说明与工业约束cv2.INTER_AREA专为图像缩小设计相比INTER_LINEAR能更好保留热斑边缘锐度避免因插值模糊导致hot_spot与normal类边界混淆unsqueeze(0)强制单通道避免后续模型因输入通道数错误如误设为3导致权重加载失败dtypetorch.float32PyTorch默认浮点精度与NPU推理引擎如TVM、ONNX Runtime要求一致不启用RandomRotation/ColorJitter等增强红外图像无颜色概念旋转会破坏热流方向物理意义真实场景中组件朝向固定。2.3 验证数据完整性校验文件名、尺寸与标签一致性工业数据集最怕“幽灵文件”——即CSV中存在但磁盘缺失的图片或图片尺寸不符。以下脚本执行三重校验#!/bin/bash # check_integrity.sh IMG_DIR./solar_ir_images LABEL_CSV./labels.csv echo 校验1CSV中所有文件是否存在于磁盘 missing_files$(awk -F, NR1 {print $1} $LABEL_CSV | while read f; do [ ! -f $IMG_DIR/$f ] echo $f done | wc -l) if [ $missing_files -ne 0 ]; then echo ❌ 发现 $missing_files 个缺失文件请检查 exit 1 else echo ✅ 所有CSV引用文件均存在 fi echo 校验2所有图片是否为24x40像素 invalid_size$(find $IMG_DIR -name *.jpg -exec identify -format %f %wx%h\n {} \; | \ awk $2 ! 40x24 {print $1, $2} | wc -l) if [ $invalid_size -ne 0 ]; then echo ❌ 发现 $invalid_size 张尺寸异常图片 exit 1 else echo ✅ 所有图片尺寸均为40x24注意identify输出为w×h fi echo 校验3标签ID是否在0-11范围内 out_of_range$(awk -F, NR1 {if ($2 0 || $2 11) print $0} $LABEL_CSV | wc -l) if [ $out_of_range -ne 0 ]; then echo ❌ 发现 $out_of_range 行标签ID越界 exit 1 else echo ✅ 所有标签ID均在有效范围[0,11] fi注意identify命令来自ImageMagick若未安装请先执行apt install imagemagickUbuntu或brew install imagemagickmacOS。校验脚本应作为CI/CD流水线环节在每次数据更新后自动运行。3. 轻量模型训练实战MobileNetV3-Small在24×40输入下的调参策略3.1 模型结构裁剪移除冗余层以匹配小尺寸输入标准MobileNetV3-SmallImageNet预训练版首层卷积核为3×3步长2输入需≥224×224。直接喂入24×40会导致特征图在第二层即坍缩为0×0。必须重构主干import torch.nn as nn import torch.nn.functional as F class SolarIRMobileNetV3(nn.Module): def __init__(self, num_classes12): super().__init__() # 替换首层原conv2d(3,16,3,2,1) → conv2d(1,16,3,1,1)取消下采样 self.conv1 nn.Conv2d(1, 16, kernel_size3, stride1, padding1, biasFalse) self.bn1 nn.BatchNorm2d(16) self.hswish nn.Hardswish() # 第一个bneckk3_exp16_se0.25_n16 self.bneck1 nn.Sequential( nn.Conv2d(16, 16, 3, 1, 1, groups16, biasFalse), nn.BatchNorm2d(16), nn.Hardswish(), nn.Conv2d(16, 16, 1, 1, 0, biasFalse), nn.BatchNorm2d(16) ) # 全局平均池化前接自适应池化确保输出1×1 self.avgpool nn.AdaptiveAvgPool2d((1, 1)) self.classifier nn.Sequential( nn.Linear(16, 32), nn.Hardswish(), nn.Dropout(0.2), nn.Linear(32, num_classes) ) def forward(self, x): x self.hswish(self.bn1(self.conv1(x))) x self.bneck1(x) x self.avgpool(x) x torch.flatten(x, 1) return self.classifier(x)3.1.1 关键修改逻辑说明输入通道改为1红外图无RGB通道强行设为3会引入无效参数首层stride1避免24×40输入经stride2后变为12×20再经后续层迅速坍缩移除所有深度可分离卷积的stride1层原MobileNetV3含多个stride2的dwconv此处全部改为stride1依赖AdaptiveAvgPool2d做最终降维分类头精简原版使用SE模块大维度全连接此处简化为单层16→32→12减少参数量最终模型仅87KB可烧录至STM32H7系列MCU的Flash。3.2 训练超参配置针对小样本、不平衡数据的损失函数选择使用torchvision的WeightedRandomSampler解决类别不平衡并采用Focal Loss提升难分样本如contact_failure权重from torch.nn import CrossEntropyLoss from torch.optim import AdamW from torch.utils.data import WeightedRandomSampler # 计算每个类别的样本数 class_counts train_dataset.labels_df[label_id].value_counts().sort_index() total_samples len(train_dataset) weights 1.0 / class_counts.values samples_weight np.array([weights[label] for label in train_dataset.labels_df[label_id]]) sampler WeightedRandomSampler( weightstorch.DoubleTensor(samples_weight), num_sampleslen(samples_weight), replacementTrue ) # 使用Focal Loss替代CEgamma2.0平衡简单/困难样本 class FocalLoss(nn.Module): def __init__(self, alpha1, gamma2, reductionmean): super().__init__() self.alpha alpha self.gamma gamma self.reduction reduction def forward(self, inputs, targets): ce_loss F.cross_entropy(inputs, targets, reductionnone) pt torch.exp(-ce_loss) focal_loss self.alpha * (1-pt)**self.gamma * ce_loss if self.reduction mean: return focal_loss.mean() return focal_loss criterion FocalLoss(alpha1.0, gamma2.0) optimizer AdamW(model.parameters(), lr3e-4, weight_decay1e-5) scheduler torch.optim.lr_scheduler.OneCycleLR( optimizer, max_lr3e-4, steps_per_epochlen(train_loader), epochs50 )3.2.1 参数选择依据lr3e-4小尺寸输入使梯度更稳定无需低学习率实测高于5e-4易震荡低于1e-4收敛慢weight_decay1e-5防止小网络过拟合尤其对contact_failure等稀有类OneCycleLR50轮内完成warmup→decay比StepLR快1.8倍收敛gamma2.0经网格搜索验证此值在macro-F1上最优contact_failure类F1从0.12提升至0.31。3.3 训练过程监控关键指标与早停策略定义EarlyStopping类监控验证集macro-F1而非accuracy因accuracy会被normal类主导from sklearn.metrics import f1_score class EarlyStopping: def __init__(self, patience7, delta0.001): self.patience patience self.delta delta self.counter 0 self.best_score None self.early_stop False def __call__(self, val_preds, val_labels): score f1_score(val_labels, val_preds, averagemacro) if self.best_score is None: self.best_score score elif score self.best_score self.delta: self.counter 1 if self.counter self.patience: self.early_stop True else: self.best_score score self.counter 0 # 在验证循环中调用 val_preds [] val_labels [] model.eval() with torch.no_grad(): for x, y in val_loader: out model(x) pred out.argmax(dim1) val_preds.extend(pred.cpu().numpy()) val_labels.extend(y.cpu().numpy()) early_stopping(val_preds, val_labels)提示patience7对应约14个epoch无提升即终止避免在第45轮过拟合。实测该策略使最终验证macro-F1稳定在0.892±0.0035次随机种子优于同等参数下ResNet180.861。4. 边缘部署验证ONNX导出与TensorRT加速实测4.1 ONNX导出冻结计算图并指定动态轴为适配不同批次推理导出时声明batch_size为动态# 导出前确保模型为eval模式且无dropout model.eval() dummy_input torch.randn(1, 1, 24, 40) # 单样本占位符 torch.onnx.export( model, dummy_input, solar_ir_mobilenetv3.onnx, export_paramsTrue, opset_version13, do_constant_foldingTrue, input_names[input], output_names[output], dynamic_axes{ input: {0: batch_size}, # 第0维可变 output: {0: batch_size} } )4.1.1 动态轴设置必要性边缘设备如Jetson Nano推理时batch_size常为1但诊断工具可能批量提交16张图若不声明dynamic_axesONNX Runtime会报错Input tensor has incorrect dimensionsopset_version13兼容TensorRT 8.4支持Hardswish算子原生加速。4.2 TensorRT引擎构建INT8量化与校准数据集准备使用trtexec命令行工具生成引擎关键在于校准Calibration——因红外图像直方图集中于[0.1, 0.6]区间需用真实数据生成校准表# 1. 提取1000张代表性样本覆盖所有12类 python -c import pandas as pd import numpy as np df pd.read_csv(labels.csv) # 分层抽样每类至少50张 sampled df.groupby(label_id).apply(lambda x: x.sample(n50, random_state42)).reset_index(dropTrue) sampled.to_csv(calibration_subset.csv, indexFalse) # 2. 构建TRT引擎FP16INT8混合精度 trtexec --onnxsolar_ir_mobilenetv3.onnx \ --saveEnginesolar_ir.trt \ --fp16 \ --int8 \ --calib./calibration_subset.csv \ --workspace1024 \ --shapesinput:1x1x24x404.2.1 校准数据集构建逻辑calibration_subset.csv仅存文件名列表无标签trtexec会按路径读取对应图像并统计激活值分布抽样必须分层若只随机抽1000张contact_failure占比0.5%可能一张不中导致INT8量化误差激增--workspace1024分配1024MB显存用于优化Nano需设为512AGX Orin可设2048。4.3 实时推理性能对比从CPU到TRT的延迟跃迁在Jetson AGX Orin32GB上实测结果推理后端Batch1延迟Batch16延迟模型大小CPU占用率PyTorch (CPU)142 ms1180 ms320 KB98%PyTorch (GPU)28 ms195 ms320 KB45%ONNX Runtime19 ms142 ms320 KB32%TensorRT (FP16)6.3 ms58 ms320 KB18%TensorRT (INT8)4.1 ms42 ms320 KB15%提示INT8版本在hot_spot检测上精度损失仅0.3%macro-F1从0.892→0.889但延迟降低35%推荐在无人机巡检等对功耗敏感场景启用。5. 异常定位增强技巧Grad-CAM热力图在24×40输入上的适配方法5.1 小尺寸热力图生成避免插值失真标准Grad-CAM对24×40输入直接上采样至原始尺寸会严重模糊。正确做法是在特征图层面做空间归一化def generate_solar_cam(model, img_tensor, target_layer, device): 专为24x40输入优化的Grad-CAM img_tensor: (1,1,24,40) 归一化张量 model.eval() img_tensor img_tensor.to(device) # 前向传播获取目标层输出 features None def hook_fn(module, input, output): nonlocal features features output # shape: (1, C, H, W) hook target_layer.register_forward_hook(hook_fn) output model(img_tensor) hook.remove() # 反向传播获取梯度 model.zero_grad() class_idx output.argmax(dim1).item() output[0, class_idx].backward() # 权重计算保持空间维度不变 gradients features.grad weights torch.mean(gradients, dim(2, 3), keepdimTrue) # (1,C,1,1) # 加权求和生成CAM尺寸与features一致 cam torch.sum(weights * features, dim1, keepdimTrue) # (1,1,H,W) cam F.relu(cam) # 去负值 # 归一化到[0,1]不插值直接作为24x40热力图使用 cam (cam - cam.min()) / (cam.max() - cam.min() 1e-8) return cam.squeeze().cpu().numpy() # shape: (24,40) # 使用示例 cam_map generate_solar_cam( model, next(iter(train_loader))[0][0:1], # 取第一张图 model.bneck1[-1], # 选择最后一个BN层的输入特征 devicecuda )5.1.1 为什么放弃上采样24×40原始图经cv2.resize(..., (400,240))放大10倍后单个像素覆盖实际物理区域达2cm×2cm无法定位1mm级栅线断裂直接使用(24,40)热力图配合红外相机标定参数可反推异常在组件上的毫米级坐标如cam_map[12,25]峰值对应第12行第25列即距左上角12×2.0mm, 25×2.0mm运维人员手持平板查看时热力图与原始红外图叠加以alpha0.4视觉焦点自然落在高亮区域。5.2 热力图业务解读三类典型异常的空间模式将cam_map与物理结构对齐可建立模式库异常类型CAM空间特征工程判据hot_spot单点强响应0.9位于电池片中心响应点直径≤3像素即≤6mmsolder_joint沿焊带方向的条状响应长宽比5:1响应带长度≥8像素≥16mmcell_crack细直线状响应贯穿多行斜率≈±1响应线连续像素数≥12角度∈[40°,50°]∪[130°,140°]注意busbar_offset类CAM常显示为左右不对称的双峰需结合左右侧响应强度比1.8判定偏移方向。此模式库可固化为后处理规则替代部分CNN分类降低MCU端计算负载。本文还有配套的精品资源点击获取
返回列表