YOLOv11-ultralytics-8.3.67部分代码阅读笔记-VOC.yaml
- 人工智能
- 2025-09-21 23:15:02

VOC.yaml
ultralytics\cfg\datasets\VOC.yaml
目录
VOC.yaml
1.YAML文件内容
2.所需的库和模块
3.def convert_label(path, lb_path, year, image_id):
4.Download
5.Convert
1.YAML文件内容 # Ultralytics 🚀 AGPL-3.0 License - ultralytics /license # PASCAL VOC dataset http://host.robots.ox.ac.uk/pascal/VOC by University of Oxford # Documentation: # Documentation: docs.ultralytics /datasets/detect/voc/ # Example usage: yolo train data=VOC.yaml # parent # ├── ultralytics # └── datasets # └── VOC ← downloads here (2.8 GB) # 示例用法: yolo train data=VOC.yaml # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 训练/验证/测试集为 1)目录:path/to/imgs,2)文件:path/to/imgs.txt,或 3)列表:[path/to/imgs1, path/to/imgs2, ..] path: ../datasets/VOC train: # train images (relative to 'path') 16551 images 训练图像(相对于“path”) 16551 幅图像。 - images/train2012 - images/train2007 - images/val2012 - images/val2007 val: # val images (relative to 'path') 4952 images val 图像(相对于“path”) 4952 幅图像。 - images/test2007 test: # test images (optional) 测试图像(可选)。 - images/test2007 # Classes names: 0: aeroplane 1: bicycle 2: bird 3: boat 4: bottle 5: bus 6: car 7: cat 8: chair 9: cow 10: diningtable 11: dog 12: horse 13: motorbike 14: person 15: pottedplant 16: sheep 17: sofa 18: train 19: tvmonitor # Download script/URL (optional) 下载脚本/URL(可选) --------------------------------------------------------------------------------------- download: | import xml.etree.ElementTree as ET from tqdm import tqdm from ultralytics.utils.downloads import download from pathlib import Path def convert_label(path, lb_path, year, image_id): def convert_box(size, box): dw, dh = 1. / size[0], 1. / size[1] x, y, w, h = (box[0] + box[1]) / 2.0 - 1, (box[2] + box[3]) / 2.0 - 1, box[1] - box[0], box[3] - box[2] return x * dw, y * dh, w * dw, h * dh in_file = open(path / f'VOC{year}/Annotations/{image_id}.xml') out_file = open(lb_path, 'w') tree = ET.parse(in_file) root = tree.getroot() size = root.find('size') w = int(size.find('width').text) h = int(size.find('height').text) names = list(yaml['names'].values()) # names list for obj in root.iter('object'): cls = obj.find('name').text if cls in names and int(obj.find('difficult').text) != 1: xmlbox = obj.find('bndbox') bb = convert_box((w, h), [float(xmlbox.find(x).text) for x in ('xmin', 'xmax', 'ymin', 'ymax')]) cls_id = names.index(cls) # class id out_file.write(" ".join(str(a) for a in (cls_id, *bb)) + '\n') # Download dir = Path(yaml['path']) # dataset root dir url = ' github /ultralytics/assets/releases/download/v0.0.0/' urls = [f'{url}VOCtrainval_06-Nov-2007.zip', # 446MB, 5012 images f'{url}VOCtest_06-Nov-2007.zip', # 438MB, 4953 images f'{url}VOCtrainval_11-May-2012.zip'] # 1.95GB, 17126 images download(urls, dir=dir / 'images', curl=True, threads=3, exist_ok=True) # download and unzip over existing paths (required) # Convert path = dir / 'images/VOCdevkit' for year, image_set in ('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test'): imgs_path = dir / 'images' / f'{image_set}{year}' lbs_path = dir / 'labels' / f'{image_set}{year}' imgs_path.mkdir(exist_ok=True, parents=True) lbs_path.mkdir(exist_ok=True, parents=True) with open(path / f'VOC{year}/ImageSets/Main/{image_set}.txt') as f: image_ids = f.read().strip().split() for id in tqdm(image_ids, desc=f'{image_set}{year}'): f = path / f'VOC{year}/JPEGImages/{id}.jpg' # old img path lb_path = (lbs_path / f.name).with_suffix('.txt') # new label path f.rename(imgs_path / f.name) # move image convert_label(path, lb_path, year, id) # convert labels to YOLO format 2.所需的库和模块 # Example usage: yolo train data=VOC.yaml import xml.etree.ElementTree as ET from tqdm import tqdm from ultralytics.utils.downloads import download from pathlib import Path 3.def convert_label(path, lb_path, year, image_id): # 这段代码定义了一个名为 convert_label 的函数,用于将 VOC 数据集中的标注文件从 XML 格式转换为 YOLO 格式的标注文件。 # 定义了一个函数 convert_label ,它接受四个参数。 # path :数据集的根目录路径。 # lb_path :转换后的标注文件保存路径。 # year :VOC 数据集的年份(如 2007 或 2012)。 # image_id :图像的 ID,用于定位对应的 XML 标注文件。 def convert_label(path, lb_path, year, image_id): # 在函数内部定义了一个嵌套函数 convert_box ,用于将 VOC 标注格式的边界框( xmin , xmax , ymin , ymax )转换为 YOLO 格式( x_center , y_center , width , height )。 def convert_box(size, box): # 计算 宽度和高度的 归一化因子 dw 和 dh ,分别为图像宽度和高度的倒数。 dw, dh = 1. / size[0], 1. / size[1] # 将 VOC 标注格式的边界框转换为 YOLO 格式。 # x 和 y 分别是边界框中心点的坐标,计算公式为 (xmin + xmax) / 2 和 (ymin + ymax) / 2 ,减去 1 是为了将坐标从 1 开始的索引转换为从 0 开始的索引。 # w 和 h 分别是边界框的宽度和高度,计算公式为 xmax - xmin 和 ymax - ymin 。 x, y, w, h = (box[0] + box[1]) / 2.0 - 1, (box[2] + box[3]) / 2.0 - 1, box[1] - box[0], box[3] - box[2] # 返回 归一化后的边界框坐标 ,通过乘以 dw 和 dh ,将坐标值归一化到 [0, 1] 范围内。 return x * dw, y * dh, w * dw, h * dh # 打开 VOC 数据集的 XML 标注文件,文件路径通过组合 path 、 year 和 image_id 构造。 in_file = open(path / f'VOC{year}/Annotations/{image_id}.xml') # 打开 目标标注文件路径 lb_path ,以写入模式打开,用于保存转换后的 YOLO 格式标注。 out_file = open(lb_path, 'w') # ET.parse(source, parser=None) # ET.parse() 是 Python 中 xml.etree.ElementTree 模块提供的一个函数,用于解析 XML 文件并将其加载到内存中,以便进行进一步的处理。 ElementTree 是 Python 标准库中用于解析和操作 XML 数据的模块。 # 参数 : # source :类型 :可以是文件名(字符串)、文件对象或类似文件的对象。 说明 :指定要解析的 XML 文件的路径或文件对象。 # parser (可选) : 类型 : xml.etree.ElementTree.XMLParser 的实例。 说明 :用于解析 XML 的解析器对象。如果不提供,默认使用 XMLParser 。 # 返回值 : # 返回一个 xml.etree.ElementTree.ElementTree 对象,表示解析后的 XML 文档的树形结构。 # 详细说明 : # 解析 XML 文件 : # ET.parse(source) 会读取指定的 XML 文件,并将其解析为一个树形结构。 # 返回的 ElementTree 对象可以用来访问和操作 XML 文档。 # 获取根节点 : # 使用 tree.getroot() 方法可以获取 XML 文档的根节点( <root> )。 # 遍历 XML 文档 : # 使用 findall() 方法可以查找所有匹配的子节点。 # 使用 find() 方法可以查找第一个匹配的子节点。 # 使用 .text 属性可以获取节点的文本内容。 # 使用自定义解析器 : # 如果需要自定义解析行为,可以传递一个 XMLParser 实例作为 parser 参数。例如 : # parser = ET.XMLParser(encoding='utf-8') # tree = ET.parse('example.xml', parser=parser) # 总结 : ET.parse() 是一个用于解析 XML 文件的函数,它将 XML 文件加载为一个树形结构,返回一个 ElementTree 对象。通过这个对象,可以方便地访问和操作 XML 文档的各个节点。 # 使用 xml.etree.ElementTree 模块解析 XML 文件,将其加载到内存中。 tree = ET.parse(in_file) # 获取 XML 文件的根节点,用于 后续遍历 。 root = tree.getroot() # 找到 XML 文件中 <size> 标签,该标签 包含图像的宽度和高度信息 。 size = root.find('size') # 从 <size> 标签中提取图像的 宽度 和 高度 ,并将其转换为整数。 w = int(size.find('width').text) h = int(size.find('height').text) # 从 yaml 文件中提取 类别名称列表 。 yaml 文件中包含类别名称的映射, names 是一个列表,存储了 所有可能的类别名称 。 names = list(yaml['names'].values()) # names list # 遍历 XML 文件中所有的 <object> 标签,每个 <object> 标签代表一个 标注对象 。 for obj in root.iter('object'): # 提取当前对象的 类别名称 ,存储在 <name> 标签中。 cls = obj.find('name').text # 检查 类别名称 是否在 names 列表中,并且对象的难度标记( difficult )不为 1。如果类别名称不存在或难度为 1,则跳过该对象。 if cls in names and int(obj.find('difficult').text) != 1: # 提取当前对象的 边界框信息 ,存储在 <bndbox> 标签中。 xmlbox = obj.find('bndbox') # 调用 convert_box 函数,将 VOC 格式的边界框转换为 YOLO 格式。 xmin , xmax , ymin , ymax 是从 <bndbox> 标签中提取的边界框坐标。 bb = convert_box((w, h), [float(xmlbox.find(x).text) for x in ('xmin', 'xmax', 'ymin', 'ymax')]) # 获取 当前类别的索引 cls_id ,即类别名称在 names 列表中的位置。 cls_id = names.index(cls) # class id # 将 类别 ID 和 归一化后的边界框坐标 写入 目标标注文件 ,格式为 class_id x_center y_center width height ,每行代表一个标注对象。 out_file.write(" ".join(str(a) for a in (cls_id, *bb)) + '\n') # 这段代码的主要功能是将 VOC 数据集的 XML 标注文件转换为 YOLO 格式的标注文件。它通过解析 XML 文件,提取图像尺寸、对象类别和边界框信息,并将这些信息转换为 YOLO 所需的格式。代码中使用了嵌套函数 convert_box 来完成边界框格式的转换,并通过条件判断过滤掉了难度为 1 的标注对象。最终,转换后的标注信息被写入指定的文件中,以便用于 YOLO 模型的训练或推理。 4.Download # 这段代码的作用是下载并解压 VOC 数据集的压缩文件到指定的目录。 # Download # 从 yaml 配置中获取 path 键对应的值,并将其作为 数据集的根目录路径 。 使用 Path (来自 pathlib 模块)来处理路径, Path 提供了更方便的路径操作方法。 dir = Path(yaml['path']) # dataset root dir # 定义一个基础 URL,用于构建完整的下载链接。这里指向的是一个托管在 GitHub 的资源仓库,可能是用于存储数据集文件的仓库。 url = ' github /ultralytics/assets/releases/download/v0.0.0/' # 定义一个列表 urls ,包含三个 VOC 数据集的下载链接。 # VOCtrainval_06-Nov-2007.zip :包含 VOC 2007 的训练和验证集,大小约为 446MB,包含 5012 张图像。 # VOCtest_06-Nov-2007.zip :包含 VOC 2007 的测试集,大小约为 438MB,包含 4953 张图像。 # VOCtrainval_11-May-2012.zip :包含 VOC 2012 的训练和验证集,大小约为 1.95GB,包含 17126 张图像。 urls = [f'{url}VOCtrainval_06-Nov-2007.zip', # 446MB, 5012 images f'{url}VOCtest_06-Nov-2007.zip', # 438MB, 4953 images f'{url}VOCtrainval_11-May-2012.zip'] # 1.95GB, 17126 images # 调用 download 函数,用于 下载和解压数据集文件 。 # urls :包含下载链接的列表。 # dir=dir / 'images' :指定下载和解压的目标目录,路径为 yaml['path'] 下的 images 文件夹。 # curl=True :使用 curl 命令进行下载( curl 是一个常用的命令行工具,用于从网络下载文件)。 # threads=3 :同时使用 3 个线程进行下载,提高下载效率。 # exist_ok=True :如果目标路径已经存在,允许覆盖现有文件。这对于重新下载或更新数据集很有用。 # def download(url, dir=Path.cwd(), unzip=True, delete=False, curl=False, threads=1, retry=3, exist_ok=False): -> 用于从指定的 URL 下载文件,并支持多种功能,包括多线程下载、自动解压、删除源文件、使用 curl 下载等。 download(urls, dir=dir / 'images', curl=True, threads=3, exist_ok=True) # download and unzip over existing paths (required) # 这段代码的作用是下载 VOC 数据集的三个压缩文件,并将它们解压到指定的目录。具体步骤如下。从 yaml 配置中获取数据集的根目录路径。构建包含数据集压缩文件下载链接的列表。调用 download 函数,使用 curl 和多线程下载并解压文件到目标目录。如果目标路径已存在,允许覆盖现有文件。 5.Convert # 这段代码的作用是将 VOC 数据集的图像和标注文件从原始格式转换为 YOLO 格式,并将它们重新组织到指定的目录结构中。 # Convert # 定义 path ,指向 VOC 数据集的根目录,通常是 VOCdevkit 文件夹。 path = dir / 'images/VOCdevkit' # 遍历 VOC 数据集的 不同年份 和 数据集类型 (训练集、验证集、测试集)。这里涉及 VOC 2007 和 VOC 2012 的 train 、 val 和 VOC 2007 的 test 。 for year, image_set in ('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test'): # 定义 目标图像路径 ,格式为 dir/images/{image_set}{year} ,例如 dir/images/train2012 。 imgs_path = dir / 'images' / f'{image_set}{year}' # 定义 目标标注路径 ,格式为 dir/labels/{image_set}{year} ,例如 dir/labels/train2012 。 lbs_path = dir / 'labels' / f'{image_set}{year}' # 创建目标图像路径的目录,如果目录已存在则忽略( exist_ok=True ),同时创建所有必要的父目录( parents=True )。 imgs_path.mkdir(exist_ok=True, parents=True) # 创建目标标注路径的目录,逻辑同上。 lbs_path.mkdir(exist_ok=True, parents=True) # 打开 VOC 数据集的图像列表文件,路径为 VOCdevkit/VOC{year}/ImageSets/Main/{image_set}.txt 。这个文件包含当前数据集的图像 ID 列表。 with open(path / f'VOC{year}/ImageSets/Main/{image_set}.txt') as f: # 读取文件内容,去除首尾空白字符后按空格分割,得到图像 ID 列表。 image_ids = f.read().strip().split() # 遍历图像 ID 列表,使用 tqdm 显示进度条,进度条的描述为 {image_set}{year} 。 for id in tqdm(image_ids, desc=f'{image_set}{year}'): # 构造 原始图像路径 ,格式为 VOCdevkit/VOC{year}/JPEGImages/{id}.jpg 。 f = path / f'VOC{year}/JPEGImages/{id}.jpg' # old img path # 构造 目标标注路径 ,将图像文件名( f.name )替换为 .txt 后缀,用于保存 YOLO 格式的标注文件。 lb_path = (lbs_path / f.name).with_suffix('.txt') # new label path # Path.rename(target) # 在 Python 的 pathlib 模块中, Path.rename() 是一个方法,用于将文件或目录从一个路径重命名为另一个路径。它是 pathlib.Path 类的一部分,提供了面向对象的方式来操作文件系统路径。 # 参数 : # source :调用 rename() 方法的 Path 对象,表示要被重命名的文件或目录的原始路径。 # target :目标路径,表示重命名后的文件或目录的路径。 # 功能 : # rename() 方法将文件或目录从 source 路径移动到 target 路径。如果目标路径已经存在 : # 如果目标路径是一个文件,它会被覆盖。 # 如果目标路径是一个目录,行为取决于操作系统。在某些系统中,会抛出错误;在其他系统中,可能会将文件移动到该目录下。 # 返回值 : # rename() 方法返回一个新的 Path 对象,表示目标路径。 # 注意事项 : # 覆盖文件 :如果目标路径已经存在, rename() 会覆盖目标文件。 # 跨文件系统移动 :在某些操作系统中,如果 source 和 target 不在同一个文件系统上,可能会抛出错误。在这种情况下,可以先复制文件,然后删除原始文件。 # 权限问题 :如果目标路径的目录不可写, rename() 会抛出 PermissionError 。 # 将原始图像移动到目标图像路径。 rename 方法会将文件从原始路径移动到新路径。 f.rename(imgs_path / f.name) # move image # 调用 convert_label 函数,将 VOC 格式的标注文件转换为 YOLO 格式,并保存到目标标注路径。 convert_label(path, lb_path, year, id) # convert labels to YOLO format # 这段代码的主要功能是将 VOC 数据集的图像和标注文件从原始格式转换为 YOLO 格式,并重新组织到指定的目录结构中。具体步骤如下。遍历 VOC 数据集的不同年份和数据集类型。创建目标图像和标注文件的目录。读取每个数据集的图像 ID 列表。遍历图像 ID,将原始图像移动到目标目录。调用 convert_label 函数,将 VOC 格式的标注文件转换为 YOLO 格式,并保存到目标路径。通过这种方式,代码实现了 VOC 数据集到 YOLO 格式的转换,同时将文件组织到适合 YOLO 训练的目录结构中。
YOLOv11-ultralytics-8.3.67部分代码阅读笔记-VOC.yaml由讯客互联人工智能栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“YOLOv11-ultralytics-8.3.67部分代码阅读笔记-VOC.yaml”
上一篇
网络安全完成mysql加固
下一篇
目录遍历文件包含测试