基于YOLOV11的草莓分级采摘应用平台【YOLOV11+数据集+Python项目源码+UI界面】
本文基于YOLOv11模型开发了草莓分级采摘应用平台,使用DaBai DCW深度相机和手机采集约1000张草莓图像,分为成熟果实(大、中、小三级)和未成熟果实(一级)四类。通过labelimg手动标注后,将XML格式转为YOLO所需的TXT格式,并按8:1:1比例划分训练集、验证集和测试集。该平台支持单张/多张图片检测、结果保存功能,主要用于实验室机械臂抓取实验和比赛演示。文中详细展示了软件功能界
文章目录
前言
本文基于 YOLOv11 模型开发关于草莓分级采摘的应用平台,数据集为网上购买的草莓模型经采集设备端完成,采集设备主要用DaBai DCW深度相机采集,部分为手机端拍摄的高清图像,数据分成熟果实(大、中、小三级)以及未成熟果实(一级),约1000张,标签采用labelimg手动标注。该草莓分级采摘应用平台主要服务实验室室内机械臂抓取实验、比赛演示等使用,可提供草莓模型链接。
一、软件功能演示与使用
软件主要功能演示
(1)单张、多张图片检测
单张检测:
文件夹检测:
(2)保存检测图片与信息
二、环境搭建
pytorch环境配置可参考以下内容:PyTorch全网最全安装实践教程【上篇】
三、模型训练、评估、预测
1、数据集准备
(1)数据集与标签
(2)数据标注
(3)原始数据集采用如下代码(voc_to_yolo.py)将xml格式转为txt格式:
import os
import xml.etree.ElementTree as ET
# 定义类别顺序
categories = ['ripe1', 'ripe2','ripe3','unripe']
category_to_index = {category: index for index, category in enumerate(categories)}
# 定义输入文件夹和输出文件夹
input_folder = r'./data/annotations' # 替换为实际的XML文件夹路径
output_folder = r'./data/labels' # 替换为实际的输出TXT文件夹路径
# 确保输出文件夹存在
os.makedirs(output_folder, exist_ok=True)
# 遍历输入文件夹中的所有XML文件
for filename in os.listdir(input_folder):
if filename.endswith('.xml'):
xml_path = os.path.join(input_folder, filename)
# 解析XML文件
tree = ET.parse(xml_path)
root = tree.getroot()
# 提取图像的尺寸
size = root.find('size')
width = int(size.find('width').text)
height = int(size.find('height').text)
# 存储name和对应的归一化坐标
objects = []
# 遍历XML中的object标签
for obj in root.findall('object'):
name = obj.find('name').text
if name in category_to_index:
category_index = category_to_index[name]
else:
continue # 如果name不在指定类别中,跳过该object
bndbox = obj.find('bndbox')
xmin = int(bndbox.find('xmin').text)
ymin = int(bndbox.find('ymin').text)
xmax = int(bndbox.find('xmax').text)
ymax = int(bndbox.find('ymax').text)
# 转换为中心点坐标和宽高
x_center = (xmin + xmax) / 2.0
y_center = (ymin + ymax) / 2.0
w = xmax - xmin
h = ymax - ymin
# 归一化
x = x_center / width
y = y_center / height
w = w / width
h = h / height
objects.append(f"{category_index} {x} {y} {w} {h}")
# 输出结果到对应的TXT文件
txt_filename = os.path.splitext(filename)[0] + '.txt'
txt_path = os.path.join(output_folder, txt_filename)
with open(txt_path, 'w') as f:
for obj in objects:
f.write(obj + '\n')
结果如下图:
(4)数据集划分为yolov11可训练模式,取8:1:1(可调整)
采用如下代码(datas_split.py)实现:
import os
import shutil
import random
# random.seed(0) #随机种子,可自选开启
def split_data(file_path, label_path, new_file_path, train_rate, val_rate, test_rate):
images = os.listdir(file_path)
labels = os.listdir(label_path)
images_no_ext = {os.path.splitext(image)[0]: image for image in images}
labels_no_ext = {os.path.splitext(label)[0]: label for label in labels}
matched_data = [(img, images_no_ext[img], labels_no_ext[img]) for img in images_no_ext if img in labels_no_ext]
unmatched_images = [img for img in images_no_ext if img not in labels_no_ext]
unmatched_labels = [label for label in labels_no_ext if label not in images_no_ext]
if unmatched_images:
print("未匹配的图片文件:")
for img in unmatched_images:
print(images_no_ext[img])
if unmatched_labels:
print("未匹配的标签文件:")
for label in unmatched_labels:
print(labels_no_ext[label])
random.shuffle(matched_data)
total = len(matched_data)
train_data = matched_data[:int(train_rate * total)]
val_data = matched_data[int(train_rate * total):int((train_rate + val_rate) * total)]
test_data = matched_data[int((train_rate + val_rate) * total):]
# 处理训练集
for img_name, img_file, label_file in train_data:
old_img_path = os.path.join(file_path, img_file)
old_label_path = os.path.join(label_path, label_file)
new_img_dir = os.path.join(new_file_path, 'train', 'images')
new_label_dir = os.path.join(new_file_path, 'train', 'labels')
os.makedirs(new_img_dir, exist_ok=True)
os.makedirs(new_label_dir, exist_ok=True)
shutil.copy(old_img_path, os.path.join(new_img_dir, img_file))
shutil.copy(old_label_path, os.path.join(new_label_dir, label_file))
# 处理验证集
for img_name, img_file, label_file in val_data:
old_img_path = os.path.join(file_path, img_file)
old_label_path = os.path.join(label_path, label_file)
new_img_dir = os.path.join(new_file_path, 'val', 'images')
new_label_dir = os.path.join(new_file_path, 'val', 'labels')
os.makedirs(new_img_dir, exist_ok=True)
os.makedirs(new_label_dir, exist_ok=True)
shutil.copy(old_img_path, os.path.join(new_img_dir, img_file))
shutil.copy(old_label_path, os.path.join(new_label_dir, label_file))
# 处理测试集
for img_name, img_file, label_file in test_data:
old_img_path = os.path.join(file_path, img_file)
old_label_path = os.path.join(label_path, label_file)
new_img_dir = os.path.join(new_file_path, 'test', 'images')
new_label_dir = os.path.join(new_file_path, 'test', 'labels')
os.makedirs(new_img_dir, exist_ok=True)
os.makedirs(new_label_dir, exist_ok=True)
shutil.copy(old_img_path, os.path.join(new_img_dir, img_file))
shutil.copy(old_label_path, os.path.join(new_label_dir, label_file))
print("数据集已划分完成")
if __name__ == '__main__':
file_path = r"data\images" # 图片文件夹
label_path = r'data\labels' # 标签文件夹
new_file_path = r"data\VOCdevkit" # 新数据存放位置
split_data(file_path, label_path, new_file_path, train_rate=0.8, val_rate=0.1, test_rate=0.1)
2、数据集训练
(1)新建data.yaml文件,train/data.yaml,内容如下:
train: ultralytics-main/data/VOCdevkit/train/images # train images (relative to 'path') 128 images
val: ultralytics-main/data/VOCdevkit/val/images # val images (relative to 'path') 128 images
test: ultralytics-main/data/VOCdevkit/test/images
nc: 4
# Classes
names: ['ripe1', 'ripe2','ripe3','unripe']
介绍:
train、val、test为上一步datas_split.py生成结果,填写本地相对应路径即可。
nc:标签类别数量。
names:自己数据集的标签名称,我的数据集标签名称分两种“helmet”和“head”。
(2)新建训练文件train.py。
import warnings
warnings.filterwarnings('ignore')
from ultralytics import YOLO
if __name__ == '__main__':
model = YOLO('ultralytics/cfg/models/11/yolo11n.yaml')
model.load('model/yolo11n.pt') #注释则不加载
results = model.train(
data='ultralytics-main/train/data.yaml', #数据集配置文件的路径
epochs=200, #训练轮次总数
batch=32, #批量大小,即单次输入多少图片训练
imgsz=640, #训练图像尺寸
workers=8, #加载数据的工作线程数
device= 0, #指定训练的计算设备,无nvidia显卡则改为 'cpu'
optimizer='SGD', #训练使用优化器,可选 auto,SGD,Adam,AdamW 等
amp= True, #True 或者 False, 解释为:自动混合精度(AMP) 训练
cache=False # True 在内存中缓存数据集图像,服务器推荐开启
)
(3)运行train.py训练文件。
python train.py
成功开始训练!
3、训练结果评估
训练完毕后,训练结果保存在run/detect/目录下,包含权重文件、训练损失函数等信息。
4、模型预测
本文提供多种预测方式,支持单张预测、文件夹批量预测、视频预测、开启摄像头预测。在这里仅展示单张图片预测效果,代码和结果如下:
代码展示:
from ultralytics import YOLO
# 加载一个预训练的 YOLO11n 模型
model = YOLO(r"E:\Projects\YOLOV11-pyqt5\4-strawberry\model\strawberry.pt")
# 对图像执行目标检测
results = model(r"E:\Projects\YOLOV11-pyqt5\4-strawberry\interface\input\img1\100.jpg") # 对图像进行预测
results[0].show() # 显示结果
结果展示:
(注:yolov11提供5种预训练权重模型(n、s、m、l、x),不同模型会对精度和推理速度有一定影响,按精度顺序大小:x>l>m>s>n,相应的推理速度快慢:n>s>m>l>x,根据自己的需求选择适合自己的模型。展示所用模型为“yolov11n”)
关注公众号【码上视觉】,分享更多有趣项目~
更多推荐
所有评论(0)