VOC格式核心是XML标注文件 + 固定目录结构

发布时间:2026/5/20 5:25:41

VOC格式核心是XML标注文件 + 固定目录结构 在数据标注场景下VOC格式核心是XML标注文件 固定目录结构是目标检测/分割任务中最常用的标注规范之一。下面我会从标注规则、XML结构详解、实操代码、常见问题四个维度帮你彻底搞懂标注场景下的VOC格式。一、VOC标注的核心规则一一对应每张图片如000001.jpg对应一个同名XML标注文件000001.xml存放于Annotations目录。坐标规则边界框bndbox使用像素绝对坐标遵循xmin ≤ xmax、ymin ≤ ymax且坐标值需在图片尺寸范围内如宽500则x≤500。类别规范name标签必须是纯文本字符串如cat/car大小写敏感建议统一小写。可选标注截断truncated、难例difficult等标签可根据实际标注需求选择无则填0。二、XML标注文件完整解析标注场景常用版以下是标注时最常用的XML模板每个标签的作用和填写规则都标注清楚了annotation!-- 图片所在文件夹名可选建议填JPEGImages --folderJPEGImages/folder!-- 图片文件名必须与图片名完全一致含后缀 --filename000001.jpg/filename!-- 图片路径可选标注时可省略或填绝对路径 --path/home/VOCdevkit/VOC2007/JPEGImages/000001.jpg/path!-- 图片来源可选标注时可忽略 --sourcedatabaseUnknown/database/source!-- 图片尺寸必须准确宽/高/通道数 --sizewidth500/width!-- 图片宽度像素 --height375/height!-- 图片高度像素 --depth3/depth!-- 通道数RGB3灰度图1 --/size!-- 是否分割标注检测任务填0即可 --segmented0/segmented!-- 第一个标注目标有多个目标就加多个object节点 --objectnameperson/name!-- 类别名核心必须准确 --poseUnspecified/pose!-- 物体姿态标注时填Unspecified即可 --truncated0/truncated!-- 0未截断1物体被图片边缘截断 --difficult0/difficult!-- 0易检测1难例如模糊/遮挡严重 --!-- 边界框核心标注的关键坐标 --bndboxxmin174/xmin!-- 左上角x坐标 --ymin101/ymin!-- 左上角y坐标 --xmax349/xmax!-- 右下角x坐标 --ymax351/ymax!-- 右下角y坐标 --/bndbox/object!-- 第二个标注目标示例 --objectnamecar/nameposeUnspecified/posetruncated1/truncateddifficult0/difficultbndboxxmin50/xminymin200/yminxmax200/xmaxymax300/ymax/bndbox/object/annotation三、实操Python生成VOC格式标注文件标注完成后通常需要用代码批量生成XML文件以下是可直接运行的工具函数importosimportxml.etree.cElementTreeasETfromxml.domimportminidomdefcreate_voc_xml(image_path,save_path,objects,image_size): 生成VOC格式的XML标注文件 :param image_path: 图片路径用于提取文件名 :param save_path: XML文件保存路径 :param objects: 标注目标列表格式[{name: person, bndbox: [xmin, ymin, xmax, ymax], truncated: 0, difficult: 0}, ...] :param image_size: 图片尺寸格式(width, height, depth) # 1. 创建根节点rootET.Element(annotation)# 2. 添加基础信息ET.SubElement(root,folder).textos.path.basename(os.path.dirname(image_path))ET.SubElement(root,filename).textos.path.basename(image_path)ET.SubElement(root,path).textimage_path# 3. 添加source节点sourceET.SubElement(root,source)ET.SubElement(source,database).textUnknown# 4. 添加图片尺寸节点sizeET.SubElement(root,size)ET.SubElement(size,width).textstr(image_size[0])ET.SubElement(size,height).textstr(image_size[1])ET.SubElement(size,depth).textstr(image_size[2])# 5. 添加分割标记ET.SubElement(root,segmented).text0# 6. 添加每个标注目标forobjinobjects:obj_nodeET.SubElement(root,object)ET.SubElement(obj_node,name).textobj[name]ET.SubElement(obj_node,pose).textUnspecifiedET.SubElement(obj_node,truncated).textstr(obj.get(truncated,0))ET.SubElement(obj_node,difficult).textstr(obj.get(difficult,0))# 添加边界框bndboxET.SubElement(obj_node,bndbox)ET.SubElement(bndbox,xmin).textstr(obj[bndbox][0])ET.SubElement(bndbox,ymin).textstr(obj[bndbox][1])ET.SubElement(bndbox,xmax).textstr(obj[bndbox][2])ET.SubElement(bndbox,ymax).textstr(obj[bndbox][3])# 7. 格式化XML并保存xml_strminidom.parseString(ET.tostring(root)).toprettyxml(indent )withopen(save_path,w,encodingutf-8)asf:f.write(xml_str)# ------------------- 测试使用 -------------------if__name____main__:# 示例标注一张包含1个人、1辆车的图片image_pathJPEGImages/000001.jpg# 图片路径save_pathAnnotations/000001.xml# XML保存路径# 标注目标模拟标注结果objects[{name:person,bndbox:[174,101,349,351],truncated:0,difficult:0},{name:car,bndbox:[50,200,200,300],truncated:1,difficult:0}]image_size(500,375,3)# 图片尺寸宽500高3753通道# 确保Annotations目录存在os.makedirs(os.path.dirname(save_path),exist_okTrue)# 生成XML文件create_voc_xml(image_path,save_path,objects,image_size)print(fVOC格式XML文件已生成{save_path})四、标注时的常见问题与避坑坐标越界标注的xmin/xmax超过图片宽度或ymin/ymax超过高度 → 标注时需核对图片尺寸代码中可加坐标校验。坐标顺序错误把xmax填成小于xmin → 建议在代码中增加assert xmin xmax and ymin ymax校验。类别名不统一同一类目标标注为Person/person/PERSON→ 标注前制定类别表统一大小写和命名。文件命名不一致图片是000001.jpgXML是000001_anno.xml→ 必须保证文件名不含后缀完全一致。总结VOC标注格式的核心是XML文件包含图片元信息和目标的类别、边界框等标注数据需与图片一一对应。边界框采用像素绝对坐标xmin/ymin/xmax/ymax标注时需保证坐标在图片尺寸范围内且顺序正确。可通过Python批量生成XML文件核心是构建annotation根节点并依次添加size尺寸、object目标等子节点。

相关新闻