自学内容网 自学内容网

菜品目标检测数据集标注及处理Yolo

在这里插入图片描述

本文摘要

本文主要演示如何使用LabelImg标注菜品数据集,目前数据集有2000+已标注的菜品目标图片,用于后续的菜品目标深度学习模型训练(包含已标注数据集,点击原文链接,关注回复“源码或数据集”,免费获取)

原文链接:菜品目标检测数据集标注及处理Yolo

请添加图片描述

1. 数据格式

目标检测的数据,在一张图像中,需要以最小外接矩形标记出各个目标区域的位置和类别,
一般的目标区域位置用一个矩形框来表示,一般用以下3种方式表达:
在这里插入图片描述
常见的目标检测数据集:

  • VOC采用的[x1,y1,x2,y2],表示物体的最小外接矩形框,VOC数据指的是Pascal VOC比赛使用的数据。VOC数据是每个图像文件对应一个同名的xml文件,xml文件中标记物体框的坐标和类别等信息。
  • COCO采用的[x1,y1,w,h],表示物体的最小外接矩形框,COCO数据是COCO比赛使用的数据。以json文件记录数据格式。
    LabelImg可以标注VOC格式的数据,对图像做目标框的标注。

2. LabelImg标注工具下载

  • 目标检测的数据标注,可以用LabelImg,下载地址:https://github.com/HumanSignal/labelImg/releases
  • 建议直接下载其可执行程序,而不是通过pip安装使用。
  • 是一款开源的图像标注工具,专门用于辅助计算机视觉任务的标注工作。它由python编写,并采用pyqt5作为图形用户界面的框架, LabelImg 是跨平台的,它可以在Windows、Linux 和 macOS 上运行,适应性强。
    [图片]

3. 数据集准备与标注

目前对于菜品目标检测的已标注数据有2000+
在这里插入图片描述
打开labelImg,并打开images文件夹和xml文件夹,如下图所示:
在这里插入图片描述
点击画框create\nRectBox,调出十字光标,框”最小外接矩形框“,并输入标签,然后点击save,就保存了.xml标注文件
在这里插入图片描述
xml文件格式如下所示:
在这里插入图片描述

4. 将LabelImg标注的数据集转为Yolo训练格式

在这里插入图片描述
知道规则后,我们使用如下脚本进行批量转换即可,核心代码如下所示:

import os
from lxml import etree
import shutil

def delete_folder(folder_path):
    try:
        shutil.rmtree(folder_path)
        print(f'文件夹: {folder_path} 所有内容已删除!')
    except Exception as e:
        print(f'删除文件夹及其所有内容报错: {e}')

def xml_to_yolotxt(source_path, label_path, cls=''):
    if not os.path.exists(label_path):
        os.mkdir(label_path)
        # 获取xml文件名称列表
    files = os.listdir(source_path)
    classes = get_classes(files, source_path)
    print('---获取所有xml文件中的cls=', classes)
    # classes = ['fire']
    # 生成分类字典,列如{'apple':0,'banana':1}
    class_dict = dict(zip(classes,range(len(classes))))
    print('------生成分类字典=', class_dict)
    # class_dict = {'fire': 1}
    # class_dict = {cls: 0}
    print('---------------begin convert----')
    count = 0
    if 1:
        for file in files:
            count = count + 1
            # print('------------', file)
            convert_xml2txt(file, source_path, label_path, class_dict, norm=True)
    print('---------------finish convert----,count=', count)

def convert_xml2txt(file_name, source_path, label_path, class_dict, norm=False):
    # 创建txt文件,并打开、写入
    new_name = file_name.split('.')[0] + '.txt'
    f = open(label_path+'/'+new_name,'w')
    print('-----------------------name=', new_name)
    with open(source_path+file_name,'rb') as fb:
        # 开始解析xml文件,获取图像尺寸
        xml = etree.HTML(fb.read())
        width = int(xml.xpath('//size/width/text()')[0])
        height = int(xml.xpath('//size/height/text()')[0])
        # 获取对象标签
        labels = xml.xpath('//object') # 单张图片中的目标数量 len(labels)
        for label in labels:
            name = label.xpath('./name/text()')[0]
            label_class = class_dict[name]
            xmin = int(label.xpath('./bndbox/xmin/text()')[0])
            xmax = int(label.xpath('./bndbox/xmax/text()')[0])
            ymin = int(label.xpath('./bndbox/ymin/text()')[0])
            ymax = int(label.xpath('./bndbox/ymax/text()')[0])
 
            # xyxy-->xywh,且归一化
            if norm :
                dw = 1 / width
                dh = 1 / height
                x_center = (xmin + xmax) / 2
                y_center = (ymax + ymin) / 2
                w = (xmax - xmin)
                h = (ymax - ymin)
                x, y, w, h = x_center * dw, y_center * dh, w * dw, h * dh
                f.write(str(label_class)+' '+str(x)+' '+str(y)+' '+str(w)+' '+str(h)+' '+'\n')
    #关闭文件
    f.close()
    
# 获取分类名称列表
def get_classes(files, source_path):
    class_set = set([])
    for file in files:
        with open(source_path+file,'rb') as fb:
            #解析xml文件
            xml = etree.HTML(fb.read())
            labels = xml.xpath('//object')
            for label in labels:
                name = label.xpath('./name/text()')[0] 
                class_set.add(name)
    return list(class_set)

if __name__ == '__main__':
    source_path = 'C:/mysel/food_plate_images/annotations_xmls/'
    label_path = 'C:/mysel/food_plate_images/labels/'
    delete_folder(label_path)
    xml_to_yolotxt(source_path, label_path)

5. 将数据分成训练集、验证集、测试集

5.1 Yolo

5.1.1 yolo训练目录文件结构

在这里插入图片描述

5.1.2 使用脚本分数据集

使用脚本将所有数据按照80%、10%、10%分成训练集、验证集、测试集

import os
import shutil
import random
from math import ceil

# 定义源文件夹路径和目标文件夹路径
source_path_images = 'C:/ai_datasets/菜品目标检测数据集(餐盘标注2000+)/food_plate_images/images/'
source_path_labels = 'C:/ai_datasets/菜品目标检测数据集(餐盘标注2000+)/food_plate_images/labels/'

# 80% 的文件
train_folder_images = 'C:/ai_datasets/菜品目标检测数据集(餐盘标注2000+)/yolo_images/train/images'
train_folder_labels = 'C:/ai_datasets/菜品目标检测数据集(餐盘标注2000+)/yolo_images/train/labels'

# 10% 的文件   
val_folder_images = 'C:/ai_datasets/菜品目标检测数据集(餐盘标注2000+)/yolo_images/val/images'
val_folder_labels = 'C:/ai_datasets/菜品目标检测数据集(餐盘标注2000+)/yolo_images/val/labels'

 # 10% 的文件
test_folder_images = 'C:/ai_datasets/菜品目标检测数据集(餐盘标注2000+)/yolo_images/test/images'
test_folder_labels = 'C:/ai_datasets/菜品目标检测数据集(餐盘标注2000+)/yolo_images/test/labels'

def delete_folder(folder_path):
    try:
        shutil.rmtree(folder_path)
        print(f'文件夹: {folder_path} 所有内容已删除!')
    except Exception as e:
        print(f'删除文件夹及其所有内容报错: {e}')
        
delete_folder(train_folder_images)
delete_folder(train_folder_labels)
delete_folder(val_folder_images)
delete_folder(val_folder_labels)
delete_folder(test_folder_images)
delete_folder(test_folder_labels)

# 确保目标文件夹存在,不存在则创建
os.makedirs(train_folder_images, exist_ok=True)
os.makedirs(train_folder_labels, exist_ok=True)

os.makedirs(val_folder_images, exist_ok=True)
os.makedirs(val_folder_labels, exist_ok=True)

os.makedirs(test_folder_images, exist_ok=True)
os.makedirs(test_folder_labels, exist_ok=True)

# 获取所有 .jpg 文件
jpg_files = [f for f in os.listdir(source_path_images) if f.endswith('.jpg')]
# 随机打乱文件顺序
random.shuffle(jpg_files)
# 计算每个文件夹的分配数量
total_files = len(jpg_files)
train_count = ceil(total_files * 0.8)
val_count = ceil(total_files * 0.1)
test_count = total_files - train_count - val_count

# 分配文件
train_files = jpg_files[:train_count]
val_files = jpg_files[train_count:train_count + val_count]
test_files = jpg_files[train_count + val_count:]

# 复制文件到对应文件夹
def copy_files(file_list, source_image_folder, destination_image_folder, source_txt_folder, dest_txt_folder):
    for file_name in file_list:
        print(f'处理---- file=', file_name)
        # 处理 .jpg 文件
        jpg_source_file = os.path.join(source_image_folder, file_name)
        jpg_destination_file = os.path.join(destination_image_folder, file_name)
        shutil.copy(jpg_source_file, jpg_destination_file)
        
        # 处理对应的 .txt 文件
        txt_file_name = file_name.replace('.jpg', '.txt')
        txt_source_file = os.path.join(source_txt_folder, txt_file_name)
        if os.path.exists(txt_source_file):  # 如果存在对应的 .txt 文件
            txt_destination_file = os.path.join(dest_txt_folder, txt_file_name)
            shutil.copy(txt_source_file, txt_destination_file)

# 执行复制
copy_files(train_files, source_path_images, train_folder_images, source_path_labels, train_folder_labels)
copy_files(val_files, source_path_images, val_folder_images, source_path_labels, val_folder_labels)
copy_files(test_files, source_path_images, test_folder_images, source_path_labels, test_folder_labels)

5.1.3 Yolo data.yaml

train: C:/xxx/菜品目标检测数据集2600+/images/train
val: C:/xxx/菜品目标检测数据集2600+/images/val
test: C:/xxx/菜品目标检测数据集2600+/images/test

nc: 1
names: ["label"]

往期文章回顾

【深度学习】物体检测/实例分割/物体追踪/姿态估计/定向边框/图像分类检测演示系统【含源码】【深度学习】YOLOV8数据标注及模型训练方法整体流程介绍及演示
【深度学习】行人跌倒行为检测软件系统【深度学习】火灾检测软件系统
【深度学习】吸烟行为检测软件系统【深度学习】数竹签演示软件系统
【深度学习】菜品目标检测软件系统QT5集成FTP实现文件及文件夹的下载
QT集成开源日志库示例python源码加密之Cython方案简单示例
【python源码加密】Cython针对python工程多层级目录处理办法http服务网络请求如何确保数据安全(含python示例源码)
http请求数据传输时确保完整性和保密性方案(含源码)QT集成百度在线地图JS API实现交互及特定效果
【qt小游戏】小老鼠闯迷宫小游戏(附源码)【qt小系统】传感器云平台3D散点图(附源码)
【qt小系统】通过qt折线图实现论文内容-快餐店排队效能分析【qt小系统】使用qt实现透明的3D魔方效果
【qt小系统】qt对sqlite数据库文件设置访问密码并以绑定QT表格视图的形式实现与数据库交互示例【图像识别】摄像头捕捉运动到静止视频帧(免费源码分享)
【深度学习】深度学习模型的加密及解密方案及源码解析-

原文地址:菜品目标检测数据集标注及处理Yolo

结束语

文中源码及数据集文件【获取方式】:点击原文根据提示获取!!!


原文地址:https://blog.csdn.net/oBoLuoChuiXue12/article/details/142890244

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!