Python课设CV方向——yolo中草药识别系统系统设计

Python课设CV方向——基于yolo的中草药识别系统系统设计

记录计算机视觉课上完成的两个课设,这是其二,采用yolov8加上PyQt5开发用户系统界面完成,感兴趣的小伙伴请多多来交流(可接python课设)

一、需求分析

(1)照片识别
用户可以通过系统界面上传单张中草药照片,系统对其进行识别并返回结果。此功能便于用户在日常生活中快速识别未知中草药。
(2)视频识别
用户可以上传包含中草药的视频,系统对视频中的每一帧进行识别,实时记录视频中出现的所有中草药种类,并返回识别结果。此功能适用于中草药种植基地的监控、教学演示或制作教程等场景。
(3)摄像头实时识别
用户可以通过设备自带的摄像头实时拍摄中草药,系统实时显示识别结果。此功能便于用户在野外、药店或药材市场等地实时识别中草药。
(4)文件夹批量识别
用户可以上传包含多张中草药照片的文件夹,系统对文件夹内的所有照片进行一次识别,并返回识别结果,识别结果可以对应照片一一对应。此功能提高了用户处理大量照片的效率。
(5)中草药简介
用户在通过以上 4 个功能输入图像进行识别后,系统会自动输出识别出的中草药的简介,帮助用户更熟悉中草药,对中草药的功效、用途、形态等进行更全面了解。

二、模型算法选择

关于CV模型算法的详细对比和介绍我会写一篇新贴。
通过对比了SVM、CNN、ResNet、DenseNet、MobileNet、EfficientNet和YOLO系列后还是选择了我们最出名的YOLO系列。使用的YOLOv8n-cls模型的设计继承了YOLO系列模型的快速推理特点,同时在分类精度上得到了优化。它使用了高效的骨干网络,并通过优化特征提取模块来提高分类任务的表现。这使得它在保持高精度的同时,仍能提供快速的推理速度,满足实时性要求高的应用场景。但是像 ResNet、DenseNet、EfficientNet 等经典的 CNN 模型在图像分类任务中也表现优异,尤其是在大规模数据集上。而这些模型通常较为复杂,在推理速度上可能不如 YOLOv8n-cls 快速,尤其是在资源有限的环境下(CPU)。此外,SVM 在小规模数据集上可能有效,但在处理高维图像数据时,训练时间和推理时间都会显著增加,不适合实时应用,不满足本系统的需求。YOLOv8n-cls 可以在较小的数据集上快速收敛,并且能够通过数据增强技术(如 Mosaic增强)有效提升模型的泛化能力。很适合本实训中相对小规模且多样性高的数据集。而像ResNet、DenseNet 等深度 CNN 模型通常需要更大的数据集来发挥其优势。虽然这些模型在大规模数据集上能达到高精度,但在小规模数据集上可能容易过拟合,或需要更长的训练时间来避免过拟合问题。在模型鲁棒性方面,YOLOv8n-cls 模型支持先进的数据增强技术,使得即使在小数据集上也能获得较好的泛化性能。此外,YOLOv8n-cls 还通过优化训练过程中的正则化技术,提高了模型对不同图像质量和环境的鲁棒性。

三、系统界面设计工具选择

同样,关于界面设计工具的详细对比和介绍我也会写在新贴里。。
由于本实训在 CPU 中完成,经过对比后选择了PyQt5。PyQt5 在使用 CPU 进行处理的环境中同样性能上表现优异。相比 Electron 等基
于网页技术的工具,PyQt5 在资源消耗上更为高效,启动速度更快,运行更加流畅。

四、系统设计与实现

本系统基于 YOLOv8n-cls 模型,结合使用 PyQt5 开发的图形界面和 OpenCV 进行视频与图像处理。系统采用管道处理方式,将输入数据(图像或视频)经过多个阶段处理,最终识别中草药类型并展示结果。系统架构流程图如下:

因此,关键组件可分为:输入模块、预处理模块、识别分类模块、后处理模块和用户界面(UI)模块。

数据准备

本实训选择 50 种中草药,每种中草药原始训练数据集为 60 张的数据集大小,每种中草药原始训练验证集为 8 张的数据集大小;系统准确性和实际方面,每种中草药的数据集尽量多地选取中草药的不同形态。

所识别的中草药种类有:安息香、白扁豆、白鼈、白芥根、白前、白芷、柏子仁、蓖拨、蔽泽苣、整甲、草豆蔻、赤石脂、川棟子、川牛膝、大腹皮、淡豆豉、稻芽、地龙、冬虫夏草、番泻叶、蜂房、枸杞子、谷精草、海龙、海螵蛸、合欢皮、芥子、鸡冠花、锦灯笼、鸡内金、荆芥穗、金钱白花蛇、橘核、苦地丁、莱菔子、莲子、莲子心、灵芝、麦冬、全蝎、人参、柔蜚蠊、桑枝、山茱萸、丝瓜络、苏木、瓦楞子、枳壳、竹茹、贝母。

算法设计

数据增强

为了防止数据集图像单一化,本实训对原始的图像数据集进行增强扩充,通过随机翻转,亮度调节(调亮与调暗),去噪声和增加椒盐噪声四种方式对原始数据加以处理,从而扩充数据集。通过这四种方法将原图像数据集扩充至原来的七倍(其中随机水平翻转扩充 2 张,亮度调节一亮一暗扩充 2 张,去噪声扩充 1 张,增加椒盐噪声扩充1张),即训练集大小为50x60x7=21000张,验证集大小为50x8x7=2800张。

#图像翻转
flipped_img1 = img.transpose(Image.FLIP_LEFT_RIGHT)#左右翻转
flipped_img2=img.transpose(Image.FLIP_TOP_BOTTOM)
flipped_img1.save(os.path.join(output_dir, f"flipped1_{filename}"))
print(f'flipped_img {filename} to flipped1_{filename}')
flipped_img2.save(os.path.join(output_dir, f"flipped2_{filename}"))
print(f'flipped_img {filename} to flipped2_{filename}')
#亮度调节
enhancer = ImageEnhance.Brightness(img)
brighter_img = enhancer.enhance(1.2)
darker_img = enhancer.enhance(0.7)
brighter_img.save(os.path.join(output_dir, f"brighter_{filename}"))
print(f'brighter_img {filename} to brighter_{filename}')
darker_img.save(os.path.join(output_dir, f"darker_{filename}"))
print(f'darker_img {filename} to darker_{filename}')

noisy_img = add_salt_and_pepper_noise(img, amount=0.005)  # 调整 amount 参数来控制噪声的强度
noisy_img.save(os.path.join(output_dir, f"noisy_{filename}"))
print(f'noisy_img {filename} to noisy_{filename}')
#去噪
denoised_img = img.filter(ImageFilter.MedianFilter(size=3))
denoised_img.save(os.path.join(output_dir, f"denoised_{filename}"))
print(f'denoised_img {filename} to denoised_{filename}')
#增加椒盐噪声
num_salt = int(amount * output.size[0] * output.size[1] * salt_vs_pepper)
num_pepper = int(amount * output.size[0] * output.size[1] * (1.0 - salt_vs_pepper))
# 添加盐噪声
for _ in range(num_salt):
    i = random.randint(0, output.size[0] - 1)
    j = random.randint(0, output.size[1] - 1)
    pixels[i, j] = (255, 255, 255)  # 白色
# 添加胡椒噪声
for _ in range(num_pepper):
    i = random.randint(0, output.size[0] - 1)
    j = random.randint(0, output.size[1] - 1)
    pixels[i, j] = (0, 0, 0)  # 黑色

写到这儿,关于图像的预处理部分就终于完成了,接着就可以丢到YOLOv8n-cls 模型里了。。于是YOLOv8n-cls 模型的训练过程我们就省略。。。

模型训练结果分析

混淆矩阵图
混淆矩阵图

界面设计

打开Qt Designer,根据设计需求ui页面可分为6个部分:

设计完页面后,通过信号与槽机制实现照片识别、批量照片识别、视频识别、摄像头识别和批量照片识别时可通过表格中定位到具体照片识别功能。通过 signalconnect 方法将UI控件的事件(按钮点击)与处理事件的槽函数(如 open_img、camera_show 、detact_batch_imgs、video_show、camera_show、on_cell_clicked)连接起来。每当用户在界面上点击某个按钮或表格单元格时,相应的槽函数就会被调用,执行各槽函数功能。

def signalconnect(self):
	self.ui.PicBtn.clicked.connect(self.open_img)
	self.ui.FilesBtn.clicked.connect(self.detact_batch_imgs)
	self.ui.VideoBtn.clicked.connect(self.video_show)
	self.ui.CapBtn.clicked.connect(self.camera_show)
	self.ui.tableWidget.cellClicked.connect(self.on_cell_clicked)

具体各槽函数这里就不放了。

完成后的页面效果如下:


作者:奇亚籽markdown

物联沃分享整理
物联沃-IOTWORD物联网 » Python课设CV方向——yolo中草药识别系统系统设计

发表回复