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

如何将图像标注的多边形坐标转换为YOLO格式矩形标注

任意点多边形标注转YOLO格式实现(水表ROI检测场景)

问题背景

  • 做水表OCR读数识别时,首要步骤是提取表盘ROI区域
  • 所用数据集的标注不是标准矩形框,而是任意顶点数的多边形结构:根据图像内容不同,多边形可能包含4、5、8个不等的坐标点
  • 转换核心思路是取多边形的最小外接矩形,匹配YOLO检测格式要求,但原始标注为字符串存储的字典结构,解析环节存在障碍

原始标注格式

标注字段结构为文件名 | 水表读数值 | 多边形坐标,样例如下:

id_53_value_595_825.jpg 595.825 {'type': 'polygon', 'data': [{'x': 0.30788, 'y': 0.30207}, {'x': 0.30676, 'y': 0.32731}, {'x': 0.53501, 'y': 0.33068}, {'x': 0.53445, 'y': 0.33699}, {'x': 0.56529, 'y': 0.33741}, {'x': 0.56697, 'y': 0.29786}, {'x': 0.53501, 'y': 0.29786}, {'x': 0.53445, 'y': 0.30417}]}

id_553_value_65_475.jpg 65.475 {'type': 'polygon', 'data': [{'x': 0.26133, 'y': 0.24071}, {'x': 0.31405, 'y': 0.23473}, {'x': 0.31741, 'y': 0.26688}, {'x': 0.30676, 'y': 0.26763}, {'x': 0.33985, 'y': 0.60851}, {'x': 0.29386, 'y': 0.61449}]}

id_407_value_21_86.jpg 21.86 {'type': 'polygon', 'data': [{'x': 0.27545, 'y': 0.19134}, {'x': 0.37483, 'y': 0.18282}, {'x': 0.38935, 'y': 0.76071}, {'x': 0.28185, 'y': 0.76613}]}

转换逻辑

不管多边形包含多少个顶点,统一通过坐标极值计算最小外接矩形,再转换为YOLO要求的归一化格式,步骤如下:

  • 解析字符串格式的标注字段,提取多边形所有顶点的x、y坐标
  • 计算x坐标的最小值min_x、最大值max_x,y坐标的最小值min_y、最大值max_y
  • 推导YOLO格式所需参数:
    • 检测框宽度:width = max_x - min_x
    • 检测框高度:height = max_y - min_y
    • 检测框中心点x坐标:center_x = min_x + width/2
    • 检测框中心点y坐标:center_y = min_y + height/2

注:该数据集的坐标本身就是相对图像宽高的归一化值,无需再除以图像分辨率做二次转换

  • 为每张图片生成同名的txt标注文件,按类别ID 中心点x 中心点y 框宽度 框高度的格式写入参数即可

可直接运行的转换代码

对原始实现的参数顺序、写入逻辑做了修正,适配标准YOLO标注格式:

import pandas as pd
import ast

def polygon_to_yolo(csv_path, label_save_dir, class_id=0):
    """
    批量将CSV格式的多边形水表标注转换为YOLO检测格式txt标注
    :param csv_path: 原始标注CSV文件路径
    :param label_save_dir: 生成的txt标注文件存储目录
    :param class_id: 表盘ROI类别对应的ID,单类别检测默认设为0
    """
    df = pd.read_csv(csv_path)
    for _, row in df.iterrows():
        # 获取无后缀的文件名,用于生成同名txt标注
        img_full_name = row['photo_name']
        file_name = img_full_name.split('.')[0]
        
        # 解析字符串存储的多边形字典
        poly_anno = ast.literal_eval(row['location'])
        points = poly_anno['data']
        
        # 提取所有顶点的x、y坐标
        x_coords = [p['x'] for p in points]
        y_coords = [p['y'] for p in points]
        
        # 计算最小外接矩形的YOLO格式参数
        min_x, max_x = min(x_coords), max(x_coords)
        min_y, max_y = min(y_coords), max(y_coords)
        bbox_w = max_x - min_x
        bbox_h = max_y - min_y
        center_x = min_x + bbox_w / 2
        center_y = min_y + bbox_h / 2
        
        # 写入标注文件
        with open(f"{label_save_dir}/{file_name}.txt", "w", encoding='utf-8') as f:
            f.write(f"{class_id} {center_x:.6f} {center_y:.6f} {bbox_w:.6f} {bbox_h:.6f}")

# 函数调用示例
# polygon_to_yolo(csv_path='water_meter_labels.csv', label_save_dir='./dataset/labels/train')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.07 16:15:42