You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过TensorFlow Object Detection API输出检测框的XML坐标文件?

如何将TensorFlow Object Detection API的检测边界框导出为XML文件

嘿,我来帮你搞定这个需求!要把检测出的边界框导出成和labelImg格式一致的XML文件,其实只需要两步:获取检测结果的坐标数据,然后按照PASCAL VOC格式生成XML文件。下面是具体的实现步骤:

1. 从推理结果中提取边界框坐标

首先,在你的推理脚本里,TensorFlow Object Detection API的detect_fn会返回一个包含检测结果的字典detections,里面关键的字段有:

  • detection_boxes:归一化的边界框坐标,格式为[y_min, x_min, y_max, x_max](数值范围0-1)
  • detection_classes:检测到的物体类别ID(注意:通常从1开始计数)
  • detection_scores:每个检测结果的置信度分数

你需要把归一化坐标转换成图像的像素坐标,公式很简单:

# 假设image是你输入的图像,image_height和image_width是图像的像素尺寸
image_height, image_width = image.shape[:2]

# 遍历每个检测结果
for i in range(len(detections['detection_scores'])):
    # 先过滤低置信度的结果,比如只保留分数≥0.5的
    if detections['detection_scores'][i] < 0.5:
        continue
    # 提取归一化坐标
    y_min, x_min, y_max, x_max = detections['detection_boxes'][i]
    # 转换为像素坐标
    x_min_pix = int(x_min * image_width)
    y_min_pix = int(y_min * image_height)
    x_max_pix = int(x_max * image_width)
    y_max_pix = int(y_max * image_height)

2. 编写函数生成PASCAL VOC格式的XML

labelImg生成的是PASCAL VOC标准的XML,我们可以用Python的xml.etree.ElementTree库来构建这个结构。下面是一个完整的生成函数:

import os
import xml.etree.ElementTree as ET

def create_voc_xml(image_path, image_width, image_height, detections, class_names, output_path):
    # 创建XML根节点
    root = ET.Element("annotation")
    
    # 添加folder节点
    folder = ET.SubElement(root, "folder")
    folder.text = os.path.basename(os.path.dirname(image_path))
    
    # 添加filename节点
    filename = ET.SubElement(root, "filename")
    filename.text = os.path.basename(image_path)
    
    # 添加path节点
    path = ET.SubElement(root, "path")
    path.text = image_path
    
    # 添加source节点
    source = ET.SubElement(root, "source")
    database = ET.SubElement(source, "database")
    database.text = "Unknown"
    
    # 添加size节点(图像尺寸)
    size = ET.SubElement(root, "size")
    width_elem = ET.SubElement(size, "width")
    width_elem.text = str(image_width)
    height_elem = ET.SubElement(size, "height")
    height_elem.text = str(image_height)
    depth_elem = ET.SubElement(size, "depth")
    depth_elem.text = "3"  # 彩色图像是3,灰度图改成1
    
    # 添加segmented节点(固定为0即可)
    segmented = ET.SubElement(root, "segmented")
    segmented.text = "0"
    
    # 遍历所有符合条件的检测结果,添加object节点
    for i in range(len(detections['detection_scores'])):
        score = detections['detection_scores'][i]
        # 过滤低置信度结果,可根据需求调整阈值
        if score < 0.5:
            continue
        
        # 获取类别名称(注意class_id从1开始,所以要减1对应列表索引)
        class_id = int(detections['detection_classes'][i])
        class_name = class_names[class_id - 1]
        
        # 转换坐标为像素值
        y_min, x_min, y_max, x_max = detections['detection_boxes'][i]
        x_min_pix = int(x_min * image_width)
        y_min_pix = int(y_min * image_height)
        x_max_pix = int(x_max * image_width)
        y_max_pix = int(y_max * image_height)
        
        # 创建object节点
        obj = ET.SubElement(root, "object")
        name_elem = ET.SubElement(obj, "name")
        name_elem.text = class_name
        pose_elem = ET.SubElement(obj, "pose")
        pose_elem.text = "Unspecified"
        truncated_elem = ET.SubElement(obj, "truncated")
        truncated_elem.text = "0"
        difficult_elem = ET.SubElement(obj, "difficult")
        difficult_elem.text = "0"
        
        # 添加边界框节点
        bndbox = ET.SubElement(obj, "bndbox")
        xmin_elem = ET.SubElement(bndbox, "xmin")
        xmin_elem.text = str(x_min_pix)
        ymin_elem = ET.SubElement(bndbox, "ymin")
        ymin_elem.text = str(y_min_pix)
        xmax_elem = ET.SubElement(bndbox, "xmax")
        xmax_elem.text = str(x_max_pix)
        ymax_elem = ET.SubElement(bndbox, "ymax")
        ymax_elem.text = str(y_max_pix)
    
    # 生成XML文件并保存
    tree = ET.ElementTree(root)
    # 写入时指定编码和XML声明,和labelImg的输出保持一致
    tree.write(output_path, encoding='utf-8', xml_declaration=True)

3. 在推理代码中调用函数

把上面的函数整合到你的推理流程里,示例代码如下:

# 假设你已经加载了检测模型,定义了detect_fn
import cv2

# 输入图像路径
image_path = "test_image.jpg"
# 读取图像
image = cv2.imread(image_path)
image_height, image_width = image.shape[:2]
# 执行推理
detections = detect_fn(image)
# 你的类别名称列表,要和训练时的label map完全对应
class_names = ["cat", "dog", "bird"]  # 示例类别,替换成你的实际类别
# 输出XML文件的路径
output_xml_path = "test_image_output.xml"

# 调用函数生成XML
create_voc_xml(image_path, image_width, image_height, detections, class_names, output_xml_path)

这样生成的XML文件就和你用labelImg标注的格式完全一致了!如果需要调整置信度阈值、修改XML里的字段(比如database内容),直接修改函数里的对应部分就行。

内容的提问来源于stack exchange,提问作者Ajinkya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:23:21