YOLOv5小麦麦穗检测全流程:从标注训练到Flask网页部署

发布时间:2026/10/2 2:48:06

YOLOv5小麦麦穗检测全流程:从标注训练到Flask网页部署 简介本资源是一套面向计算机视觉初学者与农业AI应用开发者的毕业设计级项目聚焦小麦麦穗的自动化检测需求解决农业生产中作物生长状态评估、产量预估与智能监测等实际问题。压缩包共37个文件含14个Python源码覆盖YOLOv5模型加载、Flask后端服务、图像预处理与结果可视化、12张测试/示例图像、7个配置类YAML文件含模型结构、训练参数与数据路径、以及HTML前端页面、CSS样式、README说明文档和requirements依赖清单整体仅2.23MB轻量易部署。已有96人学习下载适合课程设计、毕设开发或农业AI入门实践。用户可直接运行Flask服务上传图片获取检测结果源码采用模块化设计结构清晰配套详细使用说明涵盖环境配置、参数调优、异常处理及性能优化要点同时提供完整训练—推理—Web集成全流程代码具备良好的二次开发与场景迁移基础。1. 这不是又一个“YOLOv5 Flask”套壳项目它真能跑通小麦麦穗检测全流程从标注、训练、推理到网页端可视化所有环节都留了可调试的断点你搜“YOLOv5 Flask 小麦检测”十页结果里八页是空壳 demo模型权重缺失、Flask 路由写死、前端页面连图片上传按钮都点不动。而这份毕业设计资源我拆开 zip 后第一眼就看到datasets/wheat_spike/下整齐放着 327 张带.xml标注的田间实拍图非公开数据集裁剪models/yolov5s_wheat_best.pt是真实训练收敛后的权重val/box_loss0.042app.py里predict_image()函数明确调用torch.no_grad()conf0.35iou0.45三重控制——这不是教学模板是有人在华北平原麦田边蹲了两周拍图、标框、调参后交出的完整工程包。它解决的是农业场景下最痛的三个落地卡点小目标密集麦穗漏检、田间光照变化导致的误报、以及基层农技员不会装 CUDA 的部署难题。适合两类人一是需要快速交付毕设答辩的本科生含 Word 版《使用说明》和答辩 PPT 框架二是想验证轻量级农作物检测 pipeline 的一线算法工程师所有超参数、数据增强策略、Flask 响应头配置全开放。2. 从原始图像到检测模型YOLOv5 训练小麦麦穗的四步闭环每步都配可复现命令与参数依据2.1 数据准备为什么必须用 VOC 格式而非 COCO327 张图的标注逻辑与边界处理这份资源采用 PASCAL VOC 格式.xml而非更常见的 COCO JSON原因很实际小麦麦穗在田间呈簇状分布单穗尺寸常小于 32×32 像素VOC 的bndbox直接记录像素坐标避免 COCO 中 segmentation 多边形在小目标上产生的浮点误差累积。所有标注均通过labelImg工具完成关键约束有三点最小尺寸过滤剔除宽度 15px 或高度 12px 的 bbox对应田间拍摄距离下不可信的噪点重叠抑制同一张图中 IOU 0.8 的相邻麦穗框只保留置信度更高的一个防止模型学习虚假密集伪标签类别统一全部标注为wheat_spike单类不区分品种或成熟度符合基层农技识别需求。数据集结构严格遵循 YOLOv5 官方要求datasets/ └── wheat_spike/ ├── Annotations/ # 327 个 .xml 文件含 xminyminxmaxymax ├── JPEGImages/ # 327 张 .jpg命名与 xml 一一对应 ├── ImageSets/ │ └── Main/ │ ├── train.txt # 262 行每行一个文件名无后缀 │ ├── val.txt # 65 行 │ └── test.txt # 空文件毕业设计未做测试集评估但留了接口 └── labels/ # 转换后生成的 .txt每行格式class_id center_x center_y width height归一化提示convert_voc_to_yolo.py脚本中--img-size 1280参数必须与训练时--img 1280一致否则归一化坐标错位。该脚本会自动检查 XML 中size与实际图像尺寸是否匹配不匹配则报错退出——这是防止后期训练 loss 爆炸的关键守门员。2.2 模型训练为什么选 yolov5s 而非 yolov5m超参数组合背后的田间推理权衡资源包中models/yolov5s_wheat_best.pt是基于yolov5s.yaml修改后训练所得核心修改点有三处见models/yolov5s_wheat.yaml输入尺寸nc: 1单类、depth_multiple: 0.33、width_multiple: 0.50轻量化Anchor 重聚类用utils/autoanchor.py对小麦麦穗 bbox 长宽比重新聚类生成 3 组 anchor[12,18, 24,36, 48,72]比默认 anchor 在小目标召回率上提升 11.3%见results/train/exp/labels_correlogram.jpg损失函数加权hyp.yaml中box: 0.05,cls: 0.5,obj: 1.0—— 因麦穗外观差异小分类损失权重压低目标存在性obj权重拉高防止背景误判。训练命令直贴可用Windows / Linux 通用# 进入 yolov5 目录需提前 git clone https://github.com/ultralytics/yolov5 python train.py \ --img 1280 \ --batch 8 \ --epochs 300 \ --data ../datasets/wheat_spike/wheat_spike.yaml \ --cfg models/yolov5s_wheat.yaml \ --weights \ --name wheat_spike_train \ --cache--cache强制启用内存缓存避免 SSD 频繁读取导致训练卡顿327 张图虽少但 1280×1280 分辨率下 I/O 是瓶颈--epochs 300早停阈值设为patience50见train.py第 421 行实际在 epoch 217 收敛--batch 8显存占用峰值约 5.2GBRTX 3060 可跑若用 2060 需降为 4 并开启--rect。2.3 模型验证不只是 mAP0.5重点看小目标召回率AP_s与田间误报率FP per image验证阶段不能只看results/train/exp/val_batch0_labels.jpg里的框画得漂不漂亮。资源包中val_results_analysis.ipynb提供了三维度分析小目标专项 AP按 bbox 面积分桶统计32², 32²–96², 96²AP_s达 0.682高于 baseline yolov5s 的 0.521误报溯源对val/集中所有 FP 框提取 HOG 特征聚类发现 67% 误报集中在秸秆阴影区域提示后续可加阴影抑制模块速度-精度平衡在 Jetson Nano 上实测1280×1280→640×640resize 后推理耗时 142msmAP0.5 下降 0.019但帧率从 3.2fps 提升至 5.8fps——这对无人机巡检足够。关键验证命令生成详细 PR 曲线python val.py \ --data ../datasets/wheat_spike/wheat_spike.yaml \ --weights ../models/yolov5s_wheat_best.pt \ --img 1280 \ --task val \ --name wheat_spike_val \ --plots # 自动生成 PR_curve.png、F1_curve.png 等输出目录runs/val/wheat_spike_val/中metrics.txt记录了每类 AP、AR、F1-score单类任务下F1-score0.82是比 mAP 更贴近业务的指标农技员更关心“找全了多少穗”而非“框得多准”。2.4 模型导出ONNX 与 TorchScript 双路径为什么 Flask 选 ONNX 而非原生 PyTorchFlask 后端采用 ONNX Runtime 推理而非直接加载.pt原因有二跨平台兼容性ONNX 模型可在无 CUDA 环境如树莓派 5用 CPU 推理且onnxruntime-gpu与onnxruntimeAPI 一致内存可控性PyTorch 加载.pt会预分配显存而 ONNX Runtime 可通过sess_options.intra_op_thread_count 2限制线程数避免 Flask 多请求并发时显存 OOM。导出命令需先安装 onnx1.12.0python export.py \ --weights ../models/yolov5s_wheat_best.pt \ --include onnx \ --imgsz 1280 \ --dynamic # 启用动态轴适配不同尺寸输入生成yolov5s_wheat_best.onnx后用onnx.checker.check_model()验证有效性并用onnx.shape_inference.infer_shapes()补全 shape 信息——这步漏掉会导致 Flask 加载时报InvalidArgumentError: Input size mismatch。3. 从模型到网页Flask 服务的三层架构设计如何让农技员在 Chrome 里直接拖图检测3.1 后端路由设计为什么/detect不用 POST 传图而坚持用 multipart/form-data资源包中app.py的/detect路由明确要求enctypemultipart/form-data而非 base64 字符串或 JSON 传图原因在于大图容忍度田间拍摄图常达 4000×3000 像素base64 编码后体积膨胀 33%Chrome 对 URL 长度有限制约 2MB而 form-data 无此限制流式处理Flask 的request.files[image]返回FileStorage对象可直接save()到临时目录避免内存中解码整图12MB 图片解码后占 140MB RAM错误反馈精准若用户上传非图片文件file.filename.rsplit(., 1)[1].lower() not in {png, jpg, jpeg}可立即返回400 Bad Request而非等到模型加载时报PIL.UnidentifiedImageError。核心检测逻辑精简版app.route(/detect, methods[POST]) def detect(): if image not in request.files: return jsonify({error: No image uploaded}), 400 file request.files[image] if file.filename : return jsonify({error: Empty filename}), 400 # 保存临时文件避免内存爆炸 temp_path os.path.join(temp, secure_filename(file.filename)) file.save(temp_path) try: # ONNX 推理含预处理、NMS、后处理 results run_onnx_inference(temp_path, model_pathmodels/yolov5s_wheat_best.onnx) # 生成带框图并返回 base64 output_img_b64 draw_boxes_on_image(temp_path, results) return jsonify({ success: True, detection_count: len(results), image_with_boxes: output_img_b64 }) except Exception as e: return jsonify({error: str(e)}), 500 finally: if os.path.exists(temp_path): os.remove(temp_path) # 必须清理否则磁盘爆满3.2 前端交互HTML 中的input typefile如何绑定到 Flask 的 multipart 解析templates/index.html中关键 HTML 结构form iduploadForm enctypemultipart/form-data input typefile idimageInput nameimage acceptimage/* required button typesubmit上传检测/button /form div idresult/div配套 JavaScriptstatic/js/main.js用FormData构造请求document.getElementById(uploadForm).addEventListener(submit, async function(e) { e.preventDefault(); const fileInput document.getElementById(imageInput); const formData new FormData(); formData.append(image, fileInput.files[0]); // 关键字段名必须与 Flask 中 request.files[image] 一致 try { const res await fetch(/detect, { method: POST, body: formData // 不设 Content-Type浏览器自动设为 multipart/form-data boundary }); const data await res.json(); if (data.success) { document.getElementById(result).innerHTML img srcdata:image/png;base64,${data.image_with_boxes} alt检测结果; } else { alert(检测失败 data.error); } } catch (err) { alert(网络错误 err.message); } });注意fetch发送FormData时绝不能手动设置Content-Type否则 boundary 丢失Flask 解析失败报400 Bad Request。3.3 响应优化为什么返回 base64 图片而非 URL如何控制响应大小不超 2MB返回 base64 而非http://localhost:5000/static/results/xxx.jpg是为了规避 CORS 和静态文件权限问题农技员可能用手机热点访问IP 经常变。但 base64 体积比原图大 33%故必须压缩预处理压缩draw_boxes_on_image()中cv2.imencode(.jpg, img, [cv2.IMWRITE_JPEG_QUALITY, 85])将 JPEG 质量压至 85肉眼无损体积减 40%尺寸限制上传图 1920×1080 时前端 JS 自动canvas.toDataURL(image/jpeg, 0.7)降采样确保 base64 字符串 2MBChrome 对fetch响应体无硬限但过大会卡 UI。验证方法在浏览器开发者工具 Network 标签页查看/detect响应大小正常应为 300–800KB1280×720 输入图。3.4 部署适配Windows 下如何绕过spawn问题启动多进程 Flask资源包run.bat中启动命令为set FLASK_APPapp.py set FLASK_ENVproduction flask run --host0.0.0.0 --port5000 --no-debugger --no-reload禁用--reload是关键——Windows 下 Flask 默认用spawn方式重启子进程而 ONNX Runtime 初始化时会锁住 GPU 显存导致重启时报CUDA initialization error。生产环境必须用--no-reload靠nginx或supervisor管理进程生命周期。若需热更新改用watchdog监控文件变化后os.kill(os.getpid(), signal.SIGTERM)主动退出由外部进程管理器拉起新实例。4. 避坑指南小麦麦穗检测在 Flask 中的五个血泪现场现象、原因、解决方案全列清4.1 现象上传图片后页面卡死 30 秒最终返回 500 错误日志显示OSError: [WinError 1455] 页面文件太小原因Windows 默认页面文件虚拟内存仅 2GB而 YOLOv5s ONNX 模型加载 1280×1280 图像预处理需峰值 3.8GB 内存物理内存不足时触发页面文件耗尽。解决扩展页面文件系统属性 → 高级 → 性能设置 → 高级 → 虚拟内存 → 自定义大小初始大小设 4096MB最大值 8192MB代码层降内存在run_onnx_inference()开头添加torch.set_num_threads(2)限制 PyTorch 线程数预处理降分辨率cv2.resize(img, (640, 640))替代 1280mAP0.5 仅降 0.008但内存峰值降至 1.9GB。4.2 现象检测结果框位置偏移 50 像素且所有框都向右下角偏原因convert_voc_to_yolo.py脚本中未校验图像实际尺寸某张图 XML 标注sizewidth1920/widthheight1080/height/size但实际 JPG 是 1280×720导致归一化坐标计算错误。解决运行python utils/check_dataset_integrity.py --dataset-path datasets/wheat_spike/自动扫描所有 XML 与 JPG 尺寸不匹配项手动修正 XML 中size值或用PIL.Image.open().size读取 JPG 实际尺寸覆盖 XML在run_onnx_inference()中增加assert img.shape[:2] (1280, 1280), 否则resize后坐标错乱。4.3 现象Flask 启动后访问http://127.0.0.1:5000显示空白页Network 查看/static/css/style.css404原因Flask 默认静态文件路径为./static但资源包中static/目录被压缩进 zip 时因路径层级错误变成static\css\style.cssWindows 反斜杠而 Flask 用/解析路径找不到文件。解决解压 zip 后检查static/是否为顶层目录不是【精选毕业设计】/static/若路径嵌套将static/、templates/剪切到项目根目录与app.py同级验证print(app.static_folder)应输出绝对路径末尾为/static。4.4 现象同一张图多次上传第一次检测正确第二次开始框变少且置信度暴跌原因ONNX Runtime Session 复用时未重置状态内部缓存了前次推理的中间 tensor导致后续输入被污染。解决禁止 Session 复用每次run_onnx_inference()都新建 Session牺牲 120ms 启动时间换稳定性或启用 Session 共享但强制清除sess.run(None, {input_name: input_tensor}) # 推理 sess._sess.reset_session() # 清除内部状态ONNX Runtime 1.12 支持4.5 现象Linux 服务器部署后/detect返回500 Internal Server Error日志无报错原因onnxruntime-gpu依赖 CUDA 驱动但服务器仅安装了nvidia-driver-525而onnxruntime-gpu1.15.1要求驱动 ≥ 535版本不匹配导致 silent fail。解决查驱动版本nvidia-smi查 ONNX Runtime 兼容表https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html降级 ONNX Runtimepip install onnxruntime-gpu1.14.1支持驱动 515或改用 CPU 版pip uninstall onnxruntime-gpu pip install onnxruntime性能降 3.2 倍但稳定。5. 进阶技巧如何用这份资源快速迁移到新作物检测三步替换法与两个必改参数5.1 数据迁移从小麦麦穗到水稻稻穗只需改三处文件无需重写代码新作物检测的核心是标注一致性与数据增强适配而非模型重训。以水稻稻穗为例同样小目标、簇状分布替换标注文件将datasets/wheat_spike/Annotations/全部替换为水稻.xml确保objectnamerice_ear/name/object更新数据集配置修改datasets/wheat_spike/wheat_spike.yaml中train: ../wheat_spike/images/train/→train: ../rice_ear/images/train/nc: 1→nc: 1仍单类names: [wheat_spike]→names: [rice_ear]调整数据增强编辑data/hyps/hyp.scratch-low.yaml将hsv_h: 0.015色相扰动改为0.005水稻颜色更稳定mosaic: 1.0保持应对田间密集分布。关键convert_voc_to_yolo.py中--classes [rice_ear]参数必须与 yaml 中names一致否则生成的labels/*.txt里 class_id 为-1训练时报IndexError: index -1 is out of bounds。5.2 模型微调冻结 backbone 微调 head30 分钟内获得新作物检测能力不必从头训练用--weights加载原小麦模型冻结 backbone 后微调 detection headpython train.py \ --img 1280 \ --batch 8 \ --epochs 50 \ --data ../datasets/rice_ear/rice_ear.yaml \ --weights ../models/yolov5s_wheat_best.pt \ --cfg models/yolov5s_wheat.yaml \ --name rice_ear_finetune \ --freeze 10 # 冻结前 10 层backbone只训 neck head--freeze 10查看models/yolov5s_wheat.yaml中backbone:部分共 10 层从Focus到Conv冻结后显存占用降 35%--epochs 50早停patience15通常 22 轮收敛效果水稻稻穗 mAP0.5 从随机初始化的 0.312 提升至 0.741耗时 28 分钟RTX 3060。5.3 Flask 服务增强添加检测统计面板用 Pandas 实时汇总每张图的穗数与密度资源包未提供统计功能但可 5 行代码接入在app.py的/detect路由末尾插入# 新增统计逻辑 import pandas as pd from datetime import datetime stats_df pd.DataFrame([{ timestamp: datetime.now().isoformat(), filename: file.filename, spike_count: len(results), image_width: img.shape[1], image_height: img.shape[0], density_per_m2: len(results) / (img.shape[0] * img.shape[1] * 0.0001) # 假设 1px0.1mm }]) stats_df.to_csv(detection_stats.csv, modea, headerFalse, indexFalse)再新建/stats路由读取 CSV 并返回 JSONapp.route(/stats) def get_stats(): try: df pd.read_csv(detection_stats.csv, names[timestamp,filename,spike_count,image_width,image_height,density_per_m2]) return jsonify(df.tail(10).to_dict(records)) # 返回最近 10 条 except FileNotFoundError: return jsonify([])前端用setInterval(() fetch(/stats).then(r r.json()).then(renderStats), 5000)每 5 秒刷新统计面板——农技员一眼看出“今天巡检 12 块地平均密度 128 穗/m²”。从那以后我每次接手新作物检测项目都先拿这份小麦资源当骨架convert_voc_to_yolo.py校验数据、train.py冻结微调、app.py注入统计逻辑三小时搭出可演示 demo。它不完美但每个.py文件里都埋着可 debug 的 print、每个.yaml里都有注释说明参数意义——这才是毕业设计该有的样子不是炫技的黑匣子而是能掰开揉碎教人复现的后悔药。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/2 2:48:06

RHCSA作业实操指南:从环境准备到重启验证的核心技能

如果你手头恰好有一份RHCSA认证相关的实操作业,或者你正在备考红帽系统管理员认证,却总觉得知识点零零散散、不知道从哪下手,那这篇文章你值得看完再动手。RHCSA全称Red Hat Certified System Administrator,是红帽体系里最基础的…

2026/10/2 2:48:06

研发管理实战:源码图纸库如何统一代码与设计资产

做研发管理这十年,我见过太多团队把宝贵的源代码和设计图纸散落在个人电脑、网盘、U盘和微信文件传输记录里。每次项目迭代,总有人扯着嗓子问"最新的图纸在哪""这个版本是谁改的""PCB源文件怎么和固件对不上"。直到我们把…

2026/10/2 2:43:06

汽车零部件目标检测数据集:VOC转YOLO与训练避坑指南

简介:面向汽车零部件目标检测的VOCYOLO格式数据集,收录约1万张真实零部件图像及对应标注,覆盖50个常用类别,包括空气压缩机、交流发电机、制动卡钳、刹车盘、燃油喷射器、大灯等具体部件,同时涵盖发动机、制动、电气等…

2026/10/2 3:43:08

Windows本地管理员安全加固:从权限边界到LAPS实战

1. 为什么“本地管理员”是系统里最容易被忽视的安全盲区聊到Windows系统的权限管理,很多人第一时间想到的是域管理员(Domain Admin)、企业管理员(Enterprise Admin),本地管理员账户通常被当成“装系统时随…

2026/10/2 3:43:08

ComfyUI电商图一致性方案:Z-Image Turbo+Wan2.2+LoRA实战指南

1. 项目本质与真实价值定位“【Z-ImageWan2.2无审版】ComfyUI 文生图I 万物涩一致性人物一致性解决方案zimage turbolora模型训练万物迁移电商模特”——这个标题里藏着当前AI图像生成领域最棘手、也最刚需的两个硬骨头:跨对象风格一致性和跨场景人物一致性。不是“…

2026/10/2 3:43:08

6G显存跑AI漫剧全流程:轻量化工作流实战指南

1. 项目概述:6G显存也能跑通AI漫剧全流程?这不是画大饼,是实测可行的轻量化路径“6G显存做60秒AI漫剧”——看到这个标题,很多刚入坑的朋友第一反应是怀疑:显存都快被ComfyUI基础节点吃光了,还敢碰视频生成…

2026/10/2 3:43:08

ComfyUI视频工作流搭建指南:从零构建AI漫剧生产环境

1. 为什么2026年学ComfyUI做AI漫剧,必须绕开“一键安装”陷阱?我去年帮三个刚入行的漫画师朋友搭ComfyUI环境,他们清一色下载了所谓“秋叶2026 v10整合包”,结果两周内全部卡在同一个地方:视频生成时显存爆满、提示词不…

2026/10/2 3:43:08

粒子群优化FCM聚类:Matlab实现居民用电行为分析的完整方案

1. 这个项目到底解决了什么问题做电力数据分析的朋友应该深有体会:居民用电行为分析这件事,听起来简单,真正落地的时候全是坑。我们拿到手的往往是海量负荷数据,每户每天的用电曲线动辄几十上百个维度,如果没有一个合理…

2026/10/2 3:38:08

从零构建猫情绪检测数据集:YOLO格式标注与模型训练实战

猫的情绪到底能不能被机器识别出来?这个问题我在两年前第一次接触宠物行为分析项目时就想过。当时团队想做一个智能猫窝,核心功能是根据猫的情绪状态自动调节环境灯光和播放安抚音频,结果卡在了最基础的一步——怎么让模型知道眼前的猫是放松…

2026/10/1 5:21:14

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/10/1 17:09:46

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 10:48:55

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/2 0:02:57

PWN入门:从栈溢出原理到ROP链实战

1. 这不是“学PWN”,是重新理解你每天敲的每一行C代码我第一次在CTF赛场上写出能控制程序流的exp时,手抖得连gdb的c命令都输错三次。那道题只有23行C代码,一个gets()调用,一个printf(),一个return——它甚至没开NX&…

2026/10/2 0:02:57

Windows下cudaMallocHost显存占用之谜:WDDM与TCC模式差异及优化方案

1. 一个反直觉的显存占用现象第一次在 Windows 上看到cudaMallocHost把显存吃掉的时候,我的反应是打开任务管理器反复确认了三遍。明明调用的是主机端锁页内存分配,按 CUDA 文档的说法,这块内存应该落在系统 RAM 里,跟 GPU 的显存…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑