1. 稻田害虫检测项目整体设计与技术选型水稻害虫检测这个方向我从田间拍图、标注、训练到PyQt5界面联调完整跑过一遍踩过的坑比想象中多。这套系统要解决的核心问题很直接把稻田里常见的稻飞虱、稻纵卷叶螟、二化螟等害虫从复杂背景里框出来并给出类别和置信度。它适合农业植保研究者、农技推广人员、想练手目标检测的Python开发者也适合需要做课程设计或毕业项目的同学。整套交付包括Python源码、PyQt5可视化界面、标注好的数据集和训练代码核心关键词就是YOLOv8、深度学习、Python、PyQt5、目标检测。你可以把它理解成一个“能看图的田间助手”输入一张稻田照片或一段巡田视频输出害虫位置、种类和数量统计。1.1 为什么选YOLOv8而不是两阶段检测器水稻害虫检测有几个天然难点虫体小、背景杂乱、遮挡严重、光照变化大。如果用Faster R-CNN这类两阶段检测器精度也许能调上去但推理速度在普通显卡甚至边缘设备上很难看。YOLOv8属于单阶段目标检测一次前向传播就输出框和类别速度优势明显。更关键的是Ultralytics这套代码风格统一训练、验证、导出、推理命令都很短对刚接触深度学习实战的人非常友好。你不需要自己写Anchor匹配、损失函数和NMS大部分细节已经被封装好能把精力放在数据质量和业务效果上。另一个选YOLOv8的原因是版本迭代带来的工程便利。YOLOv8支持分类、检测、分割、姿态多种任务检测部分有n/s/m/l/x不同规模。稻田害虫检测初期完全可以从yolov8n或yolov8s起步用GTX1660Ti 6GB这种级别的显卡就能跑起来。后面如果精度不够再换yolov8m或加入P2小目标检测层。这个渐进路径比一上来就上大模型更稳显存不容易爆训练周期也能接受。我实际测试下来yolov8n在640输入下batch16占用显存约4GB左右开AMP后还能再省一些适合大多数个人开发者。1.2 系统模块拆分与交付清单整套项目我习惯拆成四块数据模块、训练模块、推理模块、界面模块。数据模块负责图片采集、清洗、标注和YOLO格式转换训练模块负责读取data.yaml、加载预训练权重、跑训练和验证推理模块把best.pt封装成可调用的检测函数界面模块用PyQt5做可视化让非程序员也能点按钮检测。这样拆的好处是每一块都能单独测试出了问题容易定位。比如界面显示不对不一定是模型问题可能只是画框颜色或中文类别映射写错了。交付清单大概包括datasets/目录下train、val、test的images和labelsdata.yaml类别配置文件train.py训练脚本detect.py命令行推理脚本ui_main.py和main.py界面代码weights/best.pt训练好的权重requirements.txt依赖列表以及一份简短的README。数据集里每张图对应一个txt标签格式是class_id x_center y_center width height坐标都归一化到0到1。训练代码里我会把关键参数写成argparse方便你改epochs、batch、imgsz和device不用翻源码。注意交付物里数据集和权重不要混在一起权重放weights/数据放datasets/否则打包后路径容易乱。界面读取模型路径最好做成配置文件或下拉选择而不是硬编码。1.3 业务场景与性能指标预期稻田害虫检测不是学术榜单刷分业务上更关心三件事漏检率、误检率和单张耗时。漏检一只稻飞虱可能没事但漏检大量虫害爆发点就影响决策。误检一片叶斑当害虫会让用户失去信任。所以指标上不能只看mAP50还要看Recall和实际抽查结果。我个人经验是害虫检测mAP50能到0.75以上就有可用性Recall最好高于0.8单张640图片在GPU上控制在20到50毫秒CPU上控制在200到500毫秒界面体验就不错。如果要做视频或摄像头实时检测帧率至少要10FPS以上否则画面会卡。这个时候可以用yolov8n、降低输入到416或320、开半精度、跳帧处理。精度和速度永远在打架关键是看场景。巡田拍照可以慢一点、准一点无人机实时巡查就要快一点、粗一点。项目里我会在界面加置信度和IoU滑块让用户自己权衡。2. 数据集构建从田间拍到YOLO标签数据是这套系统的命根子。模型结构再漂亮数据一塌糊涂结果也不会好。水稻害虫数据集最麻烦的地方在于虫体小、类别相似、背景变化大。稻飞虱可能只有几十个像素稻纵卷叶螟的幼虫和叶片颜色接近二化螟危害茎秆拍摄角度不对根本看不到。采集时要有意识覆盖不同生育期、不同光照、不同拍摄距离否则模型很容易记住“某块田的背景”而不是虫子本身。2.1 害虫类别定义与样本采集策略类别定义不要贪多。初期建议先做5到8类比如褐飞虱、白背飞虱、稻纵卷叶螟、二化螟、三化螟、稻苞虫、稻蝗。福寿螺虽然也危害水稻但它属于软体动物检测特征和昆虫差异大混在一起会增加标注歧义可以单独建一类。类别名建议用英文小写加下划线比如brown_planthopper、rice_leaf_roller、rice_stem_borer避免中文路径和编码问题。每个类别至少准备300到500个实例稀有类别最好超过800个否则训练时容易偏向多数类。采集策略上我建议手机加微距镜头拍近景同时用相机拍中景和远景。近景用于确认虫体特征中远景用于模拟实际巡田。晴天、阴天、清晨、傍晚都要拍顺光、逆光、侧光都来一点。稻叶上的水滴、泥点、叶斑、蜘蛛、蚂蚁、瓢虫也要拍进去做负样本让模型学会区分。不要只拍有虫的图片负样本能显著降低误检。采集时随手记录地点、时间、水稻生育期后面分析bad case很有用。2.2 LabelImg标注与YOLO格式转换标注工具用LabelImg、Labelme或CVAT都行目标检测建议LabelImg直接输出YOLO格式最省事。安装可以用pip install labelimg启动后选择YOLO模式打开图片目录和标签保存目录快捷键W画框、A上一张、D下一张。画框时要贴紧虫体边缘不要留太多背景也不要切掉虫体。遇到模糊、遮挡超过一半、无法确定类别的目标直接跳过不要硬标。标注质量比数量重要一千张精标图往往比五千张脏标图有效。YOLO标签格式是每行一个目标class_id x_center y_center width height。其中坐标是相对图片宽高的归一化值范围0到1。如果你用LabelImg的YOLO模式它会自动转换。注意类别索引要和data.yaml里的names顺序完全一致否则训练出来的模型会把稻飞虱认成稻纵卷叶螟。转换后可以写个脚本检查有没有越界坐标、有没有宽高为0、有没有空标签。空标签图片在YOLO里是合法的负样本但不要全是空标签否则模型会倾向于什么都不检测。import os from pathlib import Path def check_yolo_labels(label_dir, img_dir): bad [] for lbl in Path(label_dir).glob(*.txt): img_path Path(img_dir) / (lbl.stem .jpg) if not img_path.exists(): bad.append((lbl.name, missing image)) continue with open(lbl, r, encodingutf-8) as f: lines [x.strip() for x in f if x.strip()] for i, line in enumerate(lines): parts line.split() if len(parts) ! 5: bad.append((lbl.name, fline {i}字段数不对)) continue cls, x, y, w, h parts vals list(map(float, parts[1:])) if any(v 0 or v 1 for v in vals) or float(w) 0 or float(h) 0: bad.append((lbl.name, fline {i}坐标异常)) return bad if __name__ __main__: problems check_yolo_labels(datasets/labels/train, datasets/images/train) for p in problems[:20]: print(p) print(问题总数:, len(problems))2.3 数据增强、划分与防泄漏YOLOv8训练时自带数据增强包括Mosaic、MixUp、HSV调整、随机翻转、缩放和平移。我的建议是先用默认增强跑一版不要一上来就关掉或乱改。Mosaic对小目标检测帮助很大它把四张图拼成一张增加背景多样性。但Mosaic也会让部分目标变得很小如果虫体本身已经很小可以把mosaic概率从1.0降到0.5到0.8最后10个epoch用close_mosaic10关闭让模型在真实分布上收尾。数据划分要按采集批次划分不能随机打乱。比如同一天、同一块田、同一个拍摄角度的图片如果一部分进训练集、一部分进验证集验证指标会虚高。正确做法是按田块、日期或拍摄会话划分训练集和验证集来自不同批次。比例上7:2:1或8:1:1都行验证集至少占10%。如果数据量少可以用交叉验证但界面项目通常固定一个验证集就够。记得把测试集单独留出来训练过程中不要看最后再评估。注意数据增强不要自己用OpenCV离线做一堆重复图容易导致训练集和验证集泄漏。YOLOv8在线增强更安全也省磁盘。2.4 小目标数据集的坑与补丁水稻害虫检测最大的坑就是小目标。640输入下一只稻飞虱可能只占10到20像素经过多次下采样后特征几乎消失。解决办法有几个第一提高输入尺寸到960或1280但显存和速度会涨第二在模型结构里加P2小目标检测层YOLOv8的yaml可以改把P2层接出来第三用SAHI切片推理把大图切成小图分别检测再合并第四采集时尽量靠近拍但别太离谱否则和实际场景脱节。我个人最推荐先试提高输入尺寸和切片推理改动小、见效快。如果要做P2层可以复制yolov8.yaml在head部分增加P2输出注意anchor和stride要匹配。训练时小目标数据集不要用太大的batch因为小目标标注框多显存占用高。imgsz1280、batch4或8配合ampTrue在6GB显卡上能跑。如果OOM先降batch再考虑换n模型。3. YOLOv8训练全流程与调参训练部分我习惯分成环境、配置、命令、指标四步。环境不对后面全是玄学报错配置写错训练直接跑偏命令参数不理解调参就是瞎猜指标不会看模型好坏全靠感觉。下面按我实际跑通的顺序说你可以直接抄作业。3.1 环境配置与目录结构先装Python 3.8到3.10推荐3.9或3.10太新太旧都可能遇到包兼容问题。创建虚拟环境不要全局装。命令如下conda create -n ricepest python3.9 -y conda activate ricepest pip install ultralytics8.0.196 pip install pyqt5 opencv-python numpy pandas matplotlib seaborn pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118如果你的CUDA是11.8就用上面的torch源CUDA 12.1也有对应源。装完用python -c import torch; print(torch.cuda.is_available())检查返回True才算GPU可用。目录结构建议这样rice_pest_yolov8/ ├── datasets/ │ ├── images/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ └── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── weights/ │ └── yolov8n.pt ├── runs/ ├── data.yaml ├── train.py ├── detect.py ├── ui_main.py ├── main.py └── requirements.txt路径不要带中文和空格尤其是datasets和runs。Windows下如果用户名是中文建议把项目放到D盘根目录比如D:/rice_pest_yolov8。很多“找不到图片”“标签读取失败”都是中文路径或反斜杠转义引起的。3.2 data.yaml与模型配置data.yaml是数据入口写错一个字母都不行。示例path: D:/rice_pest_yolov8/datasets train: images/train val: images/val test: images/test names: 0: brown_planthopper 1: white_backed_planthopper 2: rice_leaf_roller 3: rice_stem_borer 4: rice_gall_midge 5: rice_armyworm注意names的索引必须从0开始连续和标签里的class_id对应。path可以是绝对路径train和val写相对路径。如果你用Windows路径写成D:/rice_pest_yolov8/datasets或D:\\rice_pest_yolov8\\datasets不要只写一个反斜杠。模型配置可以从yolov8n.yaml开始也可以直接用预训练权重yolov8n.pt。预训练权重能加快收敛尤其是数据量少于2000张时强烈建议用。from ultralytics import YOLO model YOLO(yolov8n.pt) model.train( datadata.yaml, epochs300, imgsz640, batch16, workers8, device0, projectruns/train, namerice_pest_v8n, pretrainedTrue, optimizerauto, lr00.01, lrf0.01, momentum0.937, weight_decay0.0005, warmup_epochs3.0, cos_lrTrue, close_mosaic10, patience50, ampTrue, seed42 )3.3 训练命令与关键参数解释epochs300不是越多越好配合patience5050轮没提升就早停。imgsz640是速度和精度的平衡点小目标多就升到960或1280但batch要降。batch16在6GB显存上跑yolov8n 640通常没问题如果OOM改成8或4。workers8是数据加载线程Windows下有时报错就改成0或2。device0表示第一块GPUCPU训练写devicecpu但会很慢。lr00.01是初始学习率lrf0.01是最终学习率比例配合余弦退火cos_lrTrue比较稳。close_mosaic10表示最后10轮关闭Mosaic让模型适应真实图片。freeze可以冻结主干前几层小数据集防止过拟合比如freeze10冻结前10层。但冻结太多会欠拟合建议先不冻过拟合再试。ampTrue开启混合精度省显存、提速现代显卡基本都支持。如果你想画损失函数曲线YOLOv8训练结束后runs/train/rice_pest_v8n/下有results.csv可以用pandas和matplotlib画。import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/train/rice_pest_v8n/results.csv) df.columns [c.strip() for c in df.columns] plt.figure(figsize(10, 5)) plt.plot(df[epoch], df[train/box_loss], labelbox_loss) plt.plot(df[epoch], df[train/cls_loss], labelcls_loss) plt.plot(df[epoch], df[val/box_loss], labelval_box_loss) plt.plot(df[epoch], df[val/cls_loss], labelval_cls_loss) plt.xlabel(epoch) plt.ylabel(loss) plt.legend() plt.grid(True) plt.savefig(loss_curve.png, dpi200)3.4 指标解读与模型导出训练时重点看mAP50、mAP50-95、precision、recall。mAP50高但mAP50-95低说明框的位置不够准precision高但recall低说明漏检多反过来则是误检多。稻田害虫检测我更看重recall宁可多框几个可疑目标也别漏掉虫害爆发点。如果recall低可以降低置信度阈值、增加小目标层、提高输入尺寸、补充难例。如果precision低可以增加负样本、提高置信度阈值、清洗错标。训练完成后在runs/train/rice_pest_v8n/weights/里找best.pt和last.pt。best.pt是验证集最好的权重界面推理用它。导出ONNXyolo export modelruns/train/rice_pest_v8n/weights/best.pt formatonnx opset12 simplifyTrue导出TensorRT引擎yolo export modelruns/train/rice_pest_v8n/weights/best.pt formatengine halfTrue device0 workspace4TensorRT速度提升明显但版本匹配很挑TensorRT 8.6对应CUDA 11.8/12.x要查清楚。导出后先用yolo predict验证一遍不要直接扔进界面否则报错很难查。4. PyQt5检测界面开发与推理联调界面是这套系统的门面。用户不关心你用了什么损失函数只关心点按钮能不能出结果、框准不准、卡不卡。PyQt5做桌面界面足够用控件多、资料全配合OpenCV显示视频也方便。但PyQt5和深度学习推理放同一个线程会卡死必须用QThread把推理放到后台。下面按界面布局、线程、绘制、三种输入模式、打包顺序讲。4.1 界面布局与交互流程我设计的界面分三块左侧控制区、中间显示区、底部状态区。左侧放“选择图片”“选择视频”“打开摄像头”“开始检测”“停止”“保存结果”按钮再加置信度滑块、IoU滑块、模型选择下拉框。中间用QLabel显示图片或视频帧保持宽高比。底部显示当前文件、检测数量、耗时和FPS。控件用QVBoxLayout和QHBoxLayout嵌套不要用绝对坐标否则换分辨率就乱。信号槽连接要清晰按钮clicked连接到对应槽函数滑块valueChanged连接到阈值更新。模型加载放在程序启动时或点击“加载模型”时不要在每次检测时重新加载否则会慢到无法忍受。类别映射从data.yaml或names.txt读取显示中文时用字典转换比如brown_planthopper: 褐飞虱。界面字体用微软雅黑或思源黑体避免中文乱码。4.2 QThread推理线程避免卡死所有耗时操作包括模型推理、视频解码、保存大图都不要放在主线程。定义一个Worker类继承QThread在里面跑检测循环通过pyqtSignal把结果帧、统计信息发回主线程。from PyQt5.QtCore import QThread, pyqtSignal import cv2 import numpy as np from ultralytics import YOLO class DetectWorker(QThread): frame_signal pyqtSignal(np.ndarray) stats_signal pyqtSignal(dict) error_signal pyqtSignal(str) def __init__(self, model_path, source, conf0.25, iou0.45): super().__init__() self.model_path model_path self.source source self.conf conf self.iou iou self.running True def run(self): try: model YOLO(self.model_path) cap cv2.VideoCapture(self.source) while self.running and cap.isOpened(): ret, frame cap.read() if not ret: break results model.predict(frame, confself.conf, iouself.iou, imgsz640, verboseFalse) annotated results[0].plot() count len(results[0].boxes) if results[0].boxes is not None else 0 self.frame_signal.emit(annotated) self.stats_signal.emit({count: count, fps: 0}) cap.release() except Exception as e: self.error_signal.emit(str(e)) def stop(self): self.running False self.wait()主线程收到frame_signal后转成QImage再显示。注意OpenCV是BGRQt是RGB必须转换否则颜色发蓝。停止时要调用worker.stop()并等待线程结束避免关闭窗口后线程还在跑导致崩溃。4.3 检测结果绘制与中文类别显示results[0].plot()返回的是BGR图画框、类别、置信度都帮你画好了但类别是英文。如果要显示中文可以自己遍历boxes拿坐标和类别再用cv2.putText绘制。OpenCV的putText不支持中文直接写会显示问号。解决办法是用PIL绘制中文再转回OpenCV或者用Qt在QLabel上叠加文字。我通常用PILfrom PIL import Image, ImageDraw, ImageFont import cv2 def draw_chinese_box(img, box, label, color(0, 255, 0)): x1, y1, x2, y2 map(int, box) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) img_pil Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) draw ImageDraw.Draw(img_pil) font ImageFont.truetype(simhei.ttf, 20) draw.text((x1, max(0, y1 - 25)), label, fontfont, fill(255, 0, 0)) return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)字体文件simhei.ttf要随项目打包或者用系统字体路径。label拼接成类别名 0.87方便用户看置信度。框的颜色可以按类别固定比如褐飞虱红色、稻纵卷叶螟绿色、二化螟蓝色视觉上更清晰。4.4 图片、视频、摄像头三种模式图片模式最简单选择文件读取图片推理显示保存。视频模式要循环读帧可以跳帧处理比如每2帧检测一次中间帧复用上一次结果能提高FPS。摄像头模式用cv2.VideoCapture(0)注意摄像头索引和分辨率设置。视频和摄像头检测时界面不要等整段视频处理完要一边推理一边显示。保存结果时视频用cv2.VideoWriter注意帧率和编码器Windows下用mp4v比较稳。图片路径可能包含中文cv2.imread会读失败。用np.fromfile加cv2.imdecodedef cv_imread(file_path): img cv2.imdecode(np.fromfile(file_path, dtypenp.uint8), cv2.IMREAD_COLOR) return img def cv_imwrite(file_path, img): cv2.imencode(.jpg, img)[1].tofile(file_path)保存结果同理用cv2.imencode。这个坑我踩过很多次界面显示空白但控制台不报错大概率就是中文路径。4.5 打包与常见环境变量开发完可以用PyInstaller打包成exe。命令类似pyinstaller -F -w main.py --add-data weights;weights --add-data simhei.ttf;. --hidden-import PyQt5.sip-F是单文件-w不显示控制台。但YOLOv8依赖多打包后可能缺ultralytics的配置文件、torch的dll、OpenCV的ffmpeg。建议先用--onedir模式确认能跑再考虑单文件。模型权重和字体文件要一起打包并在代码里用sys._MEIPASS处理资源路径。PyQt5界面无显示或报OpenGL错误常见原因是显卡驱动、远程桌面或虚拟机环境。可以设置环境变量import os os.environ[QT_OPENGL] software os.environ[QT_QPA_PLATFORM] windowsQT_OPENGLsoftware会走软件渲染界面能显示但视频可能变慢。如果只是开发调试可以接受正式部署还是修复显卡驱动更好。另外PyQt5安装时长和源有关国内可以用清华源加速但不要混用多个源。5. 常见问题排查速查深度学习项目出问题很正常关键是有排查顺序。先看数据再看训练再看推理最后看界面。很多“模型不准”其实是标签错了“界面卡死”其实是线程没开“摄像头打不开”其实是索引或权限问题。下面整理我实际遇到的高频问题和处理办法。5.1 训练不收敛、漏检、误检训练不收敛的表现是loss震荡或一直很高。先检查data.yaml路径和类别数再检查标签坐标是否归一化。如果用了预训练权重还跑不动把学习率降到0.001试试。如果loss下降但mAP不涨可能是验证集和训练集分布差异太大重新划分数据。漏检多优先看recall和验证集可视化补充小目标、遮挡、逆光样本。误检多增加负样本尤其是叶斑、泥点、水滴、其他昆虫。类别混淆严重检查标注是否把相似虫标错或者类别定义本身太细考虑合并。现象可能原因处理loss不降学习率过大、标签错、路径错降lr、查标签、查data.yamlmAP低但loss降验证集分布不同、过拟合重新划分、加数据增强、早停漏检小虫输入尺寸小、小目标层缺失升imgsz、加P2、SAHI切片误检多负样本少、置信度低加负样本、提高conf类别混淆标注歧义、类别太细清洗标签、合并相似类5.2 PyQt5界面无显示、OpenGL报错界面无显示分几种程序启动后窗口闪退、窗口空白、控件不显示、视频区域黑屏。先看控制台报错如果是OpenGL相关设置QT_OPENGLsoftware。如果是PyQt5插件找不到检查QT_QPA_PLATFORM_PLUGIN_PATH或者重装PyQt5。如果是打包后无显示检查资源路径和dll是否缺失。视频黑屏但音频正常检查OpenCV读取的帧是否为空以及BGR转RGB是否做了。QLabel显示图片时QImage要持有数据引用否则可能显示空白。PyQt5适配高分辨率屏幕时控件可能太小或模糊。可以在主函数开头加from PyQt5.QtCore import Qt QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)但要在创建QApplication之前设置。如果界面布局乱了检查是否用了绝对坐标尽量改成布局管理器。5.3 摄像头卡顿、显存溢出、速度慢摄像头卡顿通常是推理速度跟不上帧率。先测单张耗时如果单张超过100毫秒实时就难。处理办法换yolov8n、降imgsz到416、开半精度、跳帧检测、缩小显示分辨率。显存溢出表现为CUDA out of memory。训练时降batch、降imgsz、开amp、关cache。推理时如果同时开视频和多个模型也会爆显存。可以设置torch.cuda.empty_cache()但不要频繁调用会拖慢速度。速度慢还可能是CPU推理。检查torch.cuda.is_available()如果False装对CUDA版本torch。也可能是数据加载线程太多导致CPU瓶颈把workers降到4。视频保存时编码器也会拖慢可以先检测不保存最后再写视频。5.4 数据集路径与中文路径问题路径问题占报错的一半。YOLO训练报“No labels found”通常是train路径写错或者图片和标签文件名不匹配。图片是abc.jpg标签必须是abc.txt大小写敏感。Windows下路径分隔符用/或双反斜杠。中文路径除了OpenCV读取问题还可能影响YOLO内部缓存。最省事的办法是项目路径全英文图片文件名也用英文或数字。如果必须用中文读取用np.fromfile保存用cv2.imencode并在data.yaml里用绝对路径。6. 实操心得与可扩展方向这套系统从代码角度看并不复杂难的是把数据、训练、界面、部署串成一条稳定的链路。我实际跑下来最耗时的不是写PyQt5界面而是清洗数据和调小目标。界面代码两三天能写完数据集可能要积累几周。下面分享几个我觉得最有用的经验以及后面可以继续扩展的方向。6.1 从实验室到田间的采集经验在实验室拍虫和田间拍虫完全是两回事。实验室背景干净、光照稳定模型容易学田间有风、有露水、有杂草、有阴影还有大量类似虫体的杂物。我的建议是采集时至少留出30%的图片来自真实田间环境不要全用实验室摆拍。拍的时候手要稳但不要只拍特写要模拟农户用手机巡田的距离。另外不同水稻品种叶片颜色不同模型可能把叶色当特征所以品种也要多样。采集记录最好带GPS和时间后面发现某类虫效果差可以回溯补充。如果数据量实在不够可以用公开数据集做预训练再用自己的数据微调。注意公开数据集的类别定义可能不同需要做类别映射。不要直接把不同来源的数据混在一起训练而不检查标注风格差异会让模型困惑。6.2 模型轻量化与边缘部署如果要在无人机、边缘盒子或手机上跑YOLOv8n还不够轻可以考虑剪枝、量化、蒸馏或者导出NCNN、ONNX Runtime、TensorRT。TensorRT在NVIDIA设备上加速明显但部署环境要求高。RK3588这类边缘芯片可以走RKNN需要把ONNX转RKNN注意算子和量化校准。轻量化后精度会掉要用验证集重新评估尤其是小目标。我的经验是先保证精度达标再压缩模型不要一上来就追轻量最后精度不够还得返工。界面端也可以优化图片检测用GPU视频检测用GPU加跳帧摄像头用低分辨率。如果用户电脑没有GPU可以准备一个CPU版权重虽然慢但能用。模型文件不要放C盘避免权限问题。6.3 后续可扩展功能这套系统后面可以加很多实用功能。比如虫害计数和密度估计按图片面积换算每平方米虫量比如历史记录和地图标注把检测结果按田块保存比如多模型切换白天用可见光模型晚上用红外模型比如自动生成报告导出Excel和PDF。还可以接入气象数据分析虫害爆发趋势。界面方面可以加批量处理文件夹、导出带框图片、视频进度条、检测结果筛选。如果要做成Web版可以把推理封装成FastAPI接口前端用Vue或React但那就不是PyQt5项目了。对于课程设计或个人工具PyQt5桌面版足够。最后再分享一个小技巧界面里的置信度阈值不要写死留一个滑块让用户调很多“模型不准”的问题用户自己调一下阈值就解决了。模型不是万能把控制权交给用户体验会好很多。