尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

MPViT+Detectron2农田害虫检测实战:小目标、遮挡与低对比度场景优化方案

发布时间:2026/9/24 18:38:47

资讯中心
01
ARTICLE

MPViT+Detectron2农田害虫检测实战:小目标、遮挡与低对比度场景优化方案

MPViT+Detectron2农田害虫检测实战:小目标、遮挡与低对比度场景优化方案
简介本资源是2022年泰迪杯数据挖掘竞赛A题《农田害虫检测识别》的完整实现方案面向计算机、人工智能、自动化等专业学生及初学者解决农业场景下小目标、类间差异小的害虫视觉检测难题。项目基于Detectron2框架创新融合Mask R-CNN与MPViT视觉Transformer在有限算力下提升检测精度与泛化能力适用于课程设计、毕设开发、算法入门与进阶实践。压缩包共31个文件含14个配置型yaml文件定义模型结构与训练参数、9个核心py脚本训练/预测/评估全流程、2个ipynb交互式示例含predict1/predict2双路径推理演示、2个sh部署脚本及README.md使用指南整体仅42KB轻量易部署。已有140人学习下载提供经实测可运行的完整代码、配套文档说明、预训练模型与精简数据集附带清晰目录结构与关键注释支持远程答疑与基础教学切实降低视觉检测项目落地门槛。1. 农田害虫检测不是“调个YOLO就完事”为什么用MPViTDetectron2组合在小目标、遮挡、低对比度场景下真能跑通去年带学生复现这个泰迪杯A题时我特意拿它和三个主流方案做了横向对比YOLOv5sCOCO预训练、Faster R-CNN ResNet50-FPN、以及直接套用MMDetection里最新版YOLOX-L。结果在真实农田图像上——尤其是水稻叶背面的褐飞虱若虫体长不足1mm、被露水打湿后反光的菜青虫、或藏在卷曲叶片阴影里的斜纹夜蛾幼虫——YOLO系列漏检率高达37.2%Faster R-CNN掉到28.6%而这个MPViTMask R-CNN的组合稳定在14.3%。关键不是参数调得多玄而是MPViT的多尺度局部-全局注意力机制天然适配农田图像里“小目标密集背景纹理强光照不均”的黑匣子特性。它不靠堆anchor框硬刷召回而是让模型自己学会在0.5×0.5像素级区域里抓特征响应。项目源码里configs/mpvit_mask_rcnn.yaml里那行BACKBONE: mpvit_tiny不是随便写的tiny版在RTX3090上单图推理只要186ms比ResNet50快1.7倍mAP还高2.4个点。如果你正卡在毕设/课设里“检测精度上不去但又不敢换框架”或者想搞懂Transformer怎么落地到农业视觉这种非标准场景这份经过实测的完整工程包——含训练脚本、预处理流水线、验证可视化工具、甚至带标注错误自动清洗逻辑——就是你能立刻抄作业的底座。别被标题里“2022年”劝退它的数据组织方式、配置解耦设计、还有predict2.ipynb里那个带热力图叠加的交互式推理模块至今仍是农业AI项目里最干净的参考范式。2. 从数据集到模型输出四步走通MPViTDetectron2农田害虫检测全流程2.1 数据集结构解析与农田场景特化预处理逻辑泰迪杯原始数据集datasets/tdcup2022/采用Pascal VOC风格组织但暗藏三个农业图像专属坑JPEGImages/里存在大量同一株作物不同角度拍摄的重复样本如连续5帧拍同一片稻叶直接按默认train/val划分会导致数据泄露Annotations/中XML文件的bndbox坐标常因人工标注疲劳出现微小偏移±3像素对小目标尤其致命部分图像filename含中文路径如水稻_褐飞虱_001.jpgWindows系统下OpenCV读取会报UnicodeDecodeError。项目用scripts/preprocess_dataset.py做了三重加固去重校验计算每张图的感知哈希phash相似度0.95的只保留第一帧坐标校准对每个bbox执行亚像素级边缘对齐——先用Canny提取物体轮廓再将bbox中心强制吸附到轮廓质心路径标准化所有文件名转为pest_{id}_{seq}.jpg格式ID映射表存于datasets/tdcup2022/id_map.json。# scripts/preprocess_dataset.py 关键片段 def align_bbox_to_contour(img_path, xml_path): img cv2.imread(img_path) tree ET.parse(xml_path) root tree.getroot() for obj in root.findall(object): bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) ymin int(bbox.find(ymin).text) xmax int(bbox.find(xmax).text) ymax int(bbox.find(ymax).text) # 提取bbox区域内灰度图并计算轮廓质心 roi cv2.cvtColor(img[ymin:ymax, xmin:xmax], cv2.COLOR_BGR2GRAY) edges cv2.Canny(roi, 50, 150) contours, _ cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if contours: moments cv2.moments(contours[0]) if moments[m00] ! 0: cx int(moments[m10] / moments[m00]) xmin cy int(moments[m01] / moments[m00]) ymin # 重新计算对齐后的bbox保持宽高比 w, h xmax - xmin, ymax - ymin new_xmin max(0, cx - w//2) new_ymin max(0, cy - h//2) obj.find(bndbox).find(xmin).text str(new_xmin) obj.find(bndbox).find(ymin).text str(new_ymin) obj.find(bndbox).find(xmax).text str(new_xmin w) obj.find(bndbox).find(ymax).text str(new_ymin h)这段代码解决的是农业数据里最隐蔽的精度杀手标注漂移。我试过不用它直接训val mAP卡在0.52加上后首轮验证就跳到0.58。注意cv2.moments()返回的质心是相对于ROI左上角的所以要加回xmin/ymin才是全局坐标——这是新手最容易漏掉的偏移量。2.2 MPViT backbone集成到Detectron2的三处核心修改点Detectron2原生不支持MPViT项目在tdcup2022-main/detectron2/modeling/backbone/mpvit.py里实现了轻量级适配重点突破三个接口输入通道兼容性MPViT默认输入3通道RGB但农田图像常有近红外波段如无人机多光谱图。代码里MPViT类构造函数新增in_chans3参数并在forward_features()中预留x self.patch_embed(x)前的通道映射层特征金字塔对齐Detectron2的FPN要求backbone输出{p2,p3,p4,p5}四层特征图而MPViT原生输出只有{stage1,stage2,stage3,stage4}。项目用MPViTFeaturePyramid类在stage3/stage4后插入1×1卷积双线性插值生成符合FPN输入规范的p3-p5p2则由stage2经3×3卷积降采样得到梯度截断保护MPViT的局部窗口注意力Local Window Attention在小batch_size下易梯度爆炸。train_net.py第87行显式添加torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm1.0)实测batch_size2时loss震荡幅度降低63%。# configs/mpvit_mask_rcnn.yaml 关键配置项 MODEL: MASK_ON: True PIXEL_MEAN: [123.675, 116.28, 103.53] # 注意此处必须与MPViT预训练权重一致 PIXEL_STD: [58.395, 57.12, 57.375] RESNETS: DEPTH: 50 # 此参数实际被MPViT忽略但Detectron2校验必需 BACKBONE: NAME: MPViT MPVIT: MODEL_NAME: mpvit_tiny # 可选 tiny/base/large PRETRAINED: True PRETRAINED_PATH: models/mpvit_tiny.pth # 权重需自行下载这里PIXEL_MEAN/STD必须严格匹配MPViT官方发布的预训练权重归一化参数不是ImageNet的[0.485,0.456,0.406]否则特征提取层输出全乱。我在第一次训时没改这个val loss一直卡在0.85不动查了3小时才发现是归一化错位。2.3 训练脚本train_net.py的农业场景定制化参数train_net.py不是简单封装detectron2.tools.train_net它针对农田检测做了五处硬编码优化动态学习率衰减SOLVER.BASE_LR: 0.02起始但每10个epoch检查val AP75若连续2轮不涨则lr×0.5代码第124行if ap75_history[-2:] sorted(ap75_history[-2:])小目标增强策略在data_loader.py中启用CopyPasteAug随机将标注框内害虫图像复制粘贴到其他叶片区域提升小目标密度遮挡模拟transforms.py里新增RandomLeafOcclusion用真实叶片mask来自datasets/occlusion_masks/覆盖bbox区域模拟虫体被叶脉遮挡类别不平衡处理dataset_mapper.py中对稀有类如“稻纵卷叶螟成虫”仅127张图设置weight3.0常见类“菜青虫”2156张设weight1.0早停机制当val mAP连续5轮无提升且loss波动0.001时自动保存最佳权重并终止训练。# 启动训练的正确命令务必指定config和output目录 python train_net.py \ --config-file configs/mpvit_mask_rcnn.yaml \ --num-gpus 2 \ --eval-period 10 \ OUTPUT_DIR ./output/mpvit_tiny_finetune注意--eval-period 10不能设太小——农田图像验证集有1247张图每次eval耗时约4分钟设成1会拖慢训练3倍。我建议初学者先用--eval-period 20跑通流程再调优。3. predict1.ipynb 与 predict2.ipynb 的分工本质为什么你该用predict2做最终交付3.1 predict1.ipynb快速验证模型是否加载成功的最小闭环这个notebook只做三件事加载权重→读一张图→画bbox→打印置信度。它存在的唯一价值是帮你确认MODEL.WEIGHTS路径没错、GPU显存够、OpenCV版本兼容。里面所有操作都写死——图路径写在代码里、阈值固定0.5、连颜色都是[(0,255,0)]单色。它甚至不保存结果图只用plt.show()弹窗。适合刚解压完代码时跑一次“心跳检测”5分钟内告诉你模型能不能动。但千万别用它做效果评估因为没做图像预处理如自适应直方图均衡化CLAHE对露水反光图至关重要没做NMS后处理cv2.dnn.NMSBoxes未调用重叠框全保留输出坐标未还原到原始分辨率resize到800×1333后直接画框实际尺寸错乱。3.2 predict2.ipynb面向农业场景的生产级推理引擎这才是真正能交差的模块。它把农田检测的“最后一公里”全包了光照自适应预处理对输入图执行cv2.createCLAHE(clipLimit2.0, tileGridSize(8,8))专治晨雾/露水导致的低对比度多尺度推理融合对同一张图做[640,800,1024]三尺度resize分别推理后用加权平均合并bbox权重按尺度倒数分配害虫生物学后处理根据《中国农作物病虫害图谱》规则过滤结果——例如“稻飞虱”和“叶蝉”形态相似但稻飞虱必出现在水稻叶片上若检测框中心点落在cv2.inRange(hsv_img, lower_rice, upper_rice)之外则置信度×0.3可解释性输出生成result_with_heatmap.jpg用Grad-CAM可视化MPViT最后层注意力热力图叠加在原图上代码第156行cam_visualizer.draw_on_image()。# predict2.ipynb 核心逻辑节选 def run_inference_multi_scale(model, image_path, scales[640,800,1024]): original_img cv2.imread(image_path) all_boxes, all_scores, all_classes [], [], [] for scale in scales: resized cv2.resize(original_img, (scale, int(scale * 0.6))) # CLAHE增强 clahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8,8)) lab cv2.cvtColor(resized, cv2.COLOR_BGR2LAB) lab[...,0] clahe.apply(lab[...,0]) enhanced cv2.cvtColor(lab, cv2.COLOR_LAB2BGR) # Detectron2标准推理 outputs model([{image: torch.as_tensor(enhanced.astype(float32).transpose(2,0,1))}]) pred outputs[0][instances].to(cpu) boxes pred.pred_boxes.tensor.numpy() scores pred.scores.numpy() classes pred.pred_classes.numpy() # 坐标还原到原始尺寸 ratio original_img.shape[1] / resized.shape[1] boxes boxes * ratio all_boxes.append(boxes) all_scores.append(scores) all_classes.append(classes) # 加权NMS融合权重1/scale weights [1/s for s in scales] final_boxes, final_scores, final_classes weighted_nms( all_boxes, all_scores, all_classes, weights, iou_threshold0.5 ) return final_boxes, final_scores, final_classes这段代码里weighted_nms是自研函数不是detectron2原生的。它把不同尺度的检测结果按权重加权再统一做NMS——这比单纯取最高分尺度结果mAP高1.8个点。注意ratio计算用的是宽度缩放比因为农田图多为横构图高度缩放比可能因裁剪失真。4. 避坑指南MPViTDetectron2农田检测的五个血泪经验4.1 现象训练loss在0.4~0.5之间震荡val mAP始终卡在0.48不动原因MPViT预训练权重的归一化参数PIXEL_MEAN/STD与Detectron2默认值不匹配导致backbone特征提取失效。官方MPViT权重使用[123.675, 116.28, 103.53]和[58.395, 57.12, 57.375]而Detectron2默认是ImageNet的[103.53, 116.28, 123.675]BGR顺序且std不同。解决严格按configs/mpvit_mask_rcnn.yaml中配置PIXEL_MEAN/STD并在train_net.py第42行确认cfg.MODEL.PIXEL_MEAN已生效。可用print(cfg.MODEL.PIXEL_MEAN)验证。4.2 现象predict2.ipynb运行时报错AttributeError: NoneType object has no attribute pred_boxes原因输入图像路径含中文字符如D:\我的项目\害虫图.jpgOpenCVcv2.imread()返回None后续所有tensor操作崩溃。解决改用cv2.imdecode(np.fromfile(image_path, dtypenp.uint8), -1)读图此方法支持UTF-8路径。已在predict2.ipynb第33行修复。4.3 现象训练时GPU显存占用飙升至98%但batch_size1仍OOM原因MPViT的局部窗口注意力LWA模块在window_size7时显存消耗与图像长宽呈平方关系。当输入图resize到1333×800时LWA的QKV矩阵占显存超4.2GB。解决在mpvit.py第217行将window_size从7改为5显存降至2.8GBmAP仅下降0.3点。实测window_size5对农田小目标检测足够。4.4 现象验证集上“稻纵卷叶螟”类别AP为0但训练集上正常原因该类别标注存在系统性偏差——训练集标注框多覆盖整只成虫而验证集标注框常只框头部因幼虫期难识别。模型学到的是“头部纹理”而非“整虫形态”。解决在dataset_mapper.py中启用ExpandBBox增强对所有bbox外扩15像素代码第89行box[0]-15, box[1]-15, box[2]15, box[3]15强制模型关注更大区域。4.5 现象predict2.ipynb生成的热力图全是噪声无法定位害虫位置原因Grad-CAM实现时误用了MPViT的中间层输出stage2输出但该层感受野仅32×32像素不足以覆盖1mm级害虫。解决改用model.backbone.stages[3].blocks[-1].normstage4最后一层LN作为target_layer其感受野达256×256热力图聚焦准确率提升至89%。提示所有避坑方案均已集成进源码无需手动修改。但请务必核对git log --oneline确认你拉取的是fix-all-bugs-v2.1之后的commit。5. 用predict2.ipynb做农业现场快速诊断一个能落地的三步技巧5.1 第一步构建害虫置信度可信度校准曲线农田检测最怕“假阳性”——把叶脉当害虫。predict2.ipynb默认阈值0.5但实测发现对“稻飞虱若虫”类小目标0.3阈值下召回率82%、精确率61%而“斜纹夜蛾成虫”在0.6阈值下召回79%、精确率88%。项目在scripts/calibrate_confidence.py里提供了校准脚本# scripts/calibrate_confidence.py from sklearn.calibration import CalibratedClassifierCV from sklearn.ensemble import RandomForestClassifier # 提取所有预测的logits非softmax和真实标签 logits_list, labels_list extract_logits_and_labels(model, val_dataset) # 用随机森林校准比Platt scaling更适配多类别 calibrator CalibratedClassifierCV(RandomForestClassifier(n_estimators100), cv3) calibrator.fit(logits_list, labels_list) # 保存校准器 joblib.dump(calibrator, models/confidence_calibrator.pkl)运行后生成confidence_calibrator.pkl在predict2.ipynb第201行加载它就能把原始logits转为校准后置信度。这样“稻飞虱若虫”输出0.45时校准后可能是0.72——真正反映检测可靠性。5.2 第二步用热力图验证模型是否学到生物学特征别只看bbox框得准不准要看模型“为什么”框这里。predict2.ipynb第168行cam_visualizer.draw_on_image()生成的热力图要对照《中国农作物病虫害图谱》验证害虫类型应聚焦区域实际热力图偏差处理动作褐飞虱若虫腹部末端蜡粉区集中在头部启用ExpandBBox增强菜青虫体表黑色斑点覆盖整条虫体正常无需干预稻纵卷叶螟幼虫口器及前胸背板散布在叶片上检查标注质量重标50张我带学生做这步时发现热力图总在叶脉上亮——说明模型在用纹理作弊。立刻停训回溯preprocess_dataset.py把align_bbox_to_contour的cv2.Canny参数从(50,150)调到(20,80)让轮廓提取更精细热力图才回归虫体。5.3 第三步生成带GPS坐标的检测报告PDF农业场景需要可追溯的检测记录。predict2.ipynb第225行generate_field_report()函数会自动读取图像EXIF中的GPS信息若存在生成含以下要素的PDF原图缩略图 检测框叠加图每个害虫的经纬度、海拔、拍摄时间当前模型版本号git rev-parse HEAD置信度校准状态calibrated: True/False# generate_field_report() 关键逻辑 def generate_field_report(image_path, detections, output_pdf): # 读取EXIF exif {} try: img Image.open(image_path) info img._getexif() if info and 34853 in info: # GPSInfo tag gps info[34853] lat convert_to_degrees(gps[2]) * (1 if gps[1] N else -1) lon convert_to_degrees(gps[4]) * (1 if gps[3] E else -1) exif[gps] f{lat:.6f}, {lon:.6f} except: exif[gps] GPS not available # 生成PDF用reportlab doc SimpleDocTemplate(output_pdf, pagesizeA4) elements [] # ... 添加标题、图片、表格等 doc.build(elements)这个PDF能直接交给农技站他们用手机扫二维码就能看到检测详情。从那以后我每次部署农田AI项目都强制走一遍generate_field_report()生成首份报告——不是为了好看是让农民相信“这机器真认得虫不是瞎框”。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。