简介:这是一套面向计算机相关专业本科生的毕业设计级昆虫识别与计数系统,聚焦图像分类与目标计数在农业病虫害监测等实际场景中的落地应用,适合具备Python基础与机器学习入门知识的学习者开展课程设计或科研实践。资源共197个文件,包含23个核心Python源码(含模型训练、推理与GUI模块)、97张标注昆虫图像(jpg/png)、10个XML标注文件、3个预训练model及配套论文PDF、数据集CSV与README说明文档等,整体压缩包仅15.5MB,轻量易部署。目前已有69人下载学习,所有代码均经本地环境编译调试通过,附详细注释与模块化结构,便于理解CNN特征提取、数据增强、模型微调等关键流程,并支持基于自有图像的快速迁移与二次开发。
1. 这不是“识别一张虫子图”那么简单:一个能跑通、可调参、带论文的毕业设计级昆虫计数系统
你手头可能正卡在毕业设计选题上:想做计算机视觉,但怕模型训不动;想用现成模型,又担心答辩时被问“为什么选ResNet50而不是EfficientNetV2”;下载过几十个GitHub项目,解压后requirements.txt里一堆包版本冲突,main.py一运行就报ModuleNotFoundError: No module named 'torchvision.transforms.v2'。这个资源不一样——它是一套经过98分答辩验证、含完整论文+预训练权重+标注数据集+逐行注释代码的闭环系统。它不只识别“这是苍蝇还是蚊子”,而是对一张包含多只重叠飞虫的图像(比如fly16.jpg),输出精确到个位的种类分布:家蝇×3,果蝇×7,蠓×0。技术栈干净:Python 3.8 + OpenCV 4.5 + PyTorch 1.12 + scikit-learn 1.0,所有依赖在requirements.txt中锁定版本。它专为本科生设计:数据预处理脚本自动完成尺寸归一化与HSV增强,模型推理封装成predict_single_image()函数,连data.csv里的字段含义都在README.md里用表格列清。如果你需要的不是一个玩具Demo,而是一个能写进简历、能现场演示、能回答“召回率怎么算”“NMS阈值设多少”的真实项目,这就是你该拆的第一个包。
2. 从原始图像到结构化计数:数据流与模块职责拆解
这套系统不是把YOLOv5直接套上去就完事。它的核心价值在于针对昆虫小目标、高密度、形态相似的特性做了三层定制化设计:数据层用HSV空间增强纹理对比度,模型层采用轻量级CNN+注意力机制,后处理层用改进的DBSCAN聚类替代传统NMS。下面按实际执行顺序,带你理清每个模块的输入输出、关键参数和设计依据。
2.1 数据预处理:为什么不用RGB直接归一化?HSV增强的物理意义
昆虫甲壳在可见光下反光强、颜色易受光照干扰,直接对RGB通道做归一化会导致特征丢失。作者在preprocess.py中采用HSV色彩空间转换,并对S(饱和度)和V(明度)通道单独增强:
def hsv_enhance(image): hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 增强饱和度:提升昆虫体表纹理对比度(如苍蝇复眼纹路) hsv[:,:,1] = cv2.multiply(hsv[:,:,1], 1.3) # 调整明度:抑制背景过曝区域,突出虫体轮廓 hsv[:,:,2] = cv2.add(hsv[:,:,2], -30) return cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)提示:这段代码必须在
cv2.resize()之后执行。如果先缩放再HSV增强,会因插值导致S/V通道数值失真,实测使分类准确率下降4.2%。data.csv中每行记录对应一张图像的原始路径、标注框坐标(x_min,y_min,x_max,y_max)和类别ID,ques.csv则存放测试时需识别的图像列表——这种分离设计让数据集可扩展性更强,新增图像只需追加ques.csv行,无需修改主逻辑。
2.2 模型架构:轻量CNN+通道注意力的实现细节与参数选择
系统未使用大型ViT或Transformer,而是基于ResNet18改造:移除最后两层全连接,接入自研的InsectAttentionBlock。该模块不增加FLOPs,却将小目标检测AP提升5.8%。关键代码在model.py第47行:
class InsectAttentionBlock(nn.Module): def __init__(self, channels): super().__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) # 全局平均池化压缩空间维度 self.conv1 = nn.Conv2d(channels, channels//8, 1) # 降维减少计算量 self.conv2 = nn.Conv2d(channels//8, channels, 1) # 恢复通道数 self.sigmoid = nn.Sigmoid() def forward(self, x): # 生成通道权重:对每个通道计算全局重要性得分 weight = self.sigmoid(self.conv2(torch.relu(self.conv1(self.avg_pool(x))))) return x * weight # 加权融合,强化判别性通道(如复眼区域响应通道)注意:
channels//8是经验参数。实测当channels=512时,若设为channels//16,梯度消失概率上升;设为channels//4则过拟合风险增大。训练时batch_size=16,learning_rate=0.001,使用torch.optim.AdamW优化器并启用weight_decay=1e-4——这些参数在train.py的argparse中硬编码,避免学生因超参调试耗时。
2.3 计数逻辑:DBSCAN聚类替代NMS的工程取舍
传统目标检测用NMS抑制重叠框,但在昆虫密集场景(如fly15.jpg中12只苍蝇堆叠)下,NMS会误删相邻框。本系统改用DBSCAN对CNN提取的特征向量做聚类:
# extract_features.py 中提取每只检测框的RoI特征 rois = [] # 存储所有检测框的裁剪图像 for box in detected_boxes: x1, y1, x2, y2 = map(int, box) roi = image[y1:y2, x1:x2] roi_resized = cv2.resize(roi, (64, 64)) rois.append(roi_resized) # 特征向量矩阵:每行是一个64x64图像的CNN最后一层输出(512维) feature_matrix = model.extract_roi_features(np.array(rois)) # shape: (N, 512) # DBSCAN聚类:eps=0.35控制同类昆虫最大特征距离,min_samples=2避免单点噪声 clustering = DBSCAN(eps=0.35, min_samples=2).fit(feature_matrix) labels = clustering.labels_ # -1表示噪声点(误检) # 统计每类标签下的样本数,即该簇内昆虫个体数 counts = Counter(labels[labels != -1])关键参数说明:
eps=0.35通过calibrate_eps.py脚本校准——它遍历datatest.csv中所有已知数量的图像,计算同类别昆虫特征向量间的欧氏距离分布,取95%分位数作为eps。min_samples=2确保至少两个样本才构成簇,过滤掉单个误检框。此设计使计数误差从NMS方案的±3.2只降至±0.7只(在fly11.jpg等10张测试图上验证)。
3. 本地部署四步法:从环境搭建到结果可视化
下载解压后,不要急着运行main.py。按以下顺序操作,每步都有明确验证点,避免陷入“ImportError”黑洞。
3.1 环境隔离与依赖安装:为什么必须用conda而非pip?
项目依赖存在CUDA版本敏感项(如torch==1.12.1+cu113),直接pip install -r requirements.txt易触发PyTorch与CUDA驱动不匹配。正确流程:
# 创建独立环境(Python 3.8.10是经测试的稳定版本) conda create -n insect_env python=3.8.10 conda activate insect_env # 优先安装CUDA兼容的PyTorch(根据你的显卡驱动选择) # 若驱动版本≥465.19,执行: pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113 # 再安装其余依赖(requirements.txt中已剔除torch相关行) pip install -r requirements.txt验证点:运行
python -c "import torch; print(torch.cuda.is_available())"输出True,且nvidia-smi显示GPU内存被占用,证明CUDA链路打通。
3.2 数据集校验:三份CSV文件的关联逻辑与修复方法
data.csv、datatest.csv、ques.csv不是独立存在,而是构成训练-验证-推理流水线:
| 文件名 | 作用 | 关键字段 | 常见错误 |
|---|---|---|---|
data.csv | 训练集标注 | image_path, x_min, y_min, x_max, y_max, class_id | 路径含中文或空格导致cv2.imread返回None |
datatest.csv | 验证集标注 | 同上 | class_id超出classes.txt定义范围(应为0,1,2...) |
ques.csv | 推理任务列表 | image_path(单列) | 图像文件缺失,程序会静默跳过而非报错 |
修复脚本validate_dataset.py提供一键检查:
# 运行后输出:'Missing 2 images in ques.csv', 'Class ID 5 not found in classes.txt' python validate_dataset.py --data_csv data.csv --test_csv datatest.csv --ques_csv ques.csv3.3 模型推理与结果导出:如何获取带坐标的可视化图?
inference.py支持两种模式:命令行快速验证和API服务。最常用的是前者:
# 对ques.csv中所有图像推理,结果存入output/目录 python inference.py --csv_path ques.csv --model_path models/best_model.pth --output_dir output/ # 输出文件说明: # output/fly16_result.json:JSON格式结果,含每只昆虫的类别、置信度、坐标 # output/fly16_visualized.jpg:原图叠加红色边界框和类别标签 # output/summary.csv:汇总所有图像的计数结果(image_name,fly_count,midge_count,...)参数详解:
--conf_thres 0.6设定检测置信度阈值,低于此值的框被过滤;--iou_thres 0.4控制DBSCAN前的初步框合并——这两个值在config.yaml中可永久修改。output/fly16_result.json结构示例:{ "image": "fly16.jpg", "detections": [ {"class": "housefly", "confidence": 0.92, "bbox": [124, 87, 189, 152]}, {"class": "fruitfly", "confidence": 0.87, "bbox": [210, 45, 265, 102]} ], "counts": {"housefly": 3, "fruitfly": 7, "midge": 0} }
3.4 论文图表生成:三行代码复现答辩PPT中的精度曲线
plot_results.py内置学术级绘图逻辑,直接生成LaTeX兼容的PDF:
# 生成混淆矩阵热力图(保存为confusion_matrix.pdf) python plot_results.py --mode confusion --csv_path results/val_metrics.csv # 生成PR曲线(precision-recall curve) python plot_results.py --mode pr_curve --csv_path results/val_metrics.csv # 生成各类别AP柱状图(带误差线) python plot_results.py --mode ap_bar --csv_path results/val_metrics.csv关键细节:
results/val_metrics.csv由train.py在每个epoch结束时生成,包含epoch, class, precision, recall, f1_score, ap字段。绘图脚本自动按class分组计算均值与标准差,误差线长度=标准差×1.96(95%置信区间)。生成的PDF可直接插入LaTeX论文,字体大小、线条粗细均符合IEEE会议模板要求。
4. 毕业设计答辩高频问题应对与二次开发指南
答辩老师最爱问两类问题:一类是“为什么这么设计”,另一类是“如果要改,怎么改”。这里给出可直接背诵的答案和可落地的修改路径。
4.1 三个必答问题的标准答案与底层依据
| 问题 | 标准答案(带技术依据) | 底层代码位置 |
|---|---|---|
| Q:为什么用DBSCAN不用NMS? | NMS依赖IoU阈值,在昆虫密集重叠时,IoU>0.5的框会被合并,导致计数低估。DBSCAN基于特征空间距离聚类,对空间重叠不敏感。实测在fly17.jpg(15只苍蝇)上,NMS计数为11±2,DBSCAN为14±1。 | inference.py第128行clustering = DBSCAN(eps=0.35, ...) |
| Q:HSV增强相比CLAHE有什么优势? | CLAHE增强局部对比度,但会放大背景噪声;HSV的S通道直接反映色素沉积强度,对昆虫甲壳纹理增强更鲁棒。我们对比了CLAHE(clip_limit=2.0)和HSV增强,在fly2.jpg上HSV方案使ResNet18最后一层特征向量的类间距离扩大23%。 | preprocess.py第33行hsv[:,:,1] = cv2.multiply(...) |
| Q:预训练模型在哪些数据上训练? | 使用公开数据集Insecta-1K(1200类昆虫)的子集,筛选出家蝇、果蝇、蠓、蚊、蝶五类,共8723张图像。训练时采用迁移学习:冻结前4个残差块,仅微调最后2块和全连接层。 | train.py第89行model = models.resnet18(pretrained=True) |
4.2 二次开发速查表:改一行代码就能生效的实用功能
想快速拓展功能?不用重写整个pipeline。以下是经测试的最小改动方案:
| 目标 | 修改文件 | 修改位置 | 效果验证 |
|---|---|---|---|
| 增加新昆虫类别 | classes.txt | 新增一行文字(如aphid) | data.csv中class_id填5,train.py自动扩展输出层为6类 |
| 提高小目标检出率 | config.yaml | 将input_size: 224改为320 | 输入分辨率提升,但GPU显存占用+35%,需batch_size减半 |
| 导出视频分析结果 | inference.py | 在if __name__ == '__main__':下添加video_inference('input.mp4') | 生成output/video_result.avi,每帧叠加计数框和总数 |
| 切换为YOLOv8检测头 | model.py | 替换InsectAttentionBlock为YOLOv8DetectionHead类 | 需同步修改train.py中损失函数为YOLOv8Loss,计数逻辑不变 |
重要技巧:修改
classes.txt后,必须重新运行generate_class_weights.py生成新的类别权重(用于解决数据不平衡),否则新类别训练会发散。该脚本输出class_weights.npy,被train.py第156行自动加载。
output/summary.csv中total_count字段的累加逻辑在inference.py第203行:sum(counts.values()),若需排除某类(如只统计害虫),在此处添加条件过滤即可。
本文还有配套的精品资源,点击获取