AnyLabelImg标注数据高效导入Halcon的完整解决方案

1次阅读
没有评论

共计 2557 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

格式差异与核心痛点

Halcon 和 AnyLabelImg 的数据结构差异主要体现在三个方面:

AnyLabelImg 标注数据高效导入 Halcon 的完整解决方案

  1. 标注格式差异
  2. AnyLabelImg 默认使用 Pascal VOC 的 XML 格式或 COCO 的 JSON 格式
  3. Halcon 使用自研的 HDict 数据结构存储 ROI 信息

  4. 坐标系差异

  5. 图像坐标系原点位置不同(左上角 vs 中心点)
  6. YOLO 格式使用归一化坐标,需进行反归一化计算

  7. 数据结构差异

  8. Halcon 要求明确区分 Region/XLD 等不同图形类型
  9. 多边形标注需要特殊处理亚像素精度转换

技术实现方案

1. Python 解析模块

import xml.etree.ElementTree as ET
import json
from pathlib import Path

def parse_voc_xml(xml_path):
    """
    解析 Pascal VOC 格式 XML 文件
    :param xml_path: 标注文件路径
    :return: 包含所有 ROI 的字典列表
    """
    tree = ET.parse(xml_path)
    root = tree.getroot()

    rois = []
    for obj in root.findall('object'):
        roi = {'name': obj.find('name').text,
            'bndbox': {'xmin': float(obj.find('bndbox/xmin').text),
                'ymin': float(obj.find('bndbox/ymin').text),
                'xmax': float(obj.find('bndbox/xmax').text),
                'ymax': float(obj.find('bndbox/ymax').text)
            }
        }
        rois.append(roi)
    return rois

2. 坐标转换核心算法

def convert_coordinates(roi_dict, img_width, img_height):
    """
    坐标系统一转换(VOC→Halcon):param roi_dict: 原始 ROI 数据
    :param img_width: 图像宽度
    :param img_height: 图像高度
    :return: 转换后的坐标序列
    """
    # 从 VOC 格式转换到 Halcon 坐标系
    x1 = roi_dict['bndbox']['xmin']
    y1 = roi_dict['bndbox']['ymin']
    x2 = roi_dict['bndbox']['xmax']
    y2 = roi_dict['bndbox']['ymax']

    # 转换为 Halcon 格式(中心点坐标)center_x = (x1 + x2) / 2.0
    center_y = (y1 + y2) / 2.0

    return [center_x, center_y, x2-x1, y2-y1]

3. Halcon 接口生成

def generate_hdevelop_script(roi_data, output_path):
    """
    生成 HDevelop 可执行脚本
    :param roi_data: 转换后的 ROI 数据
    :param output_path: 输出脚本路径
    """with open(output_path,'w') as f:
        f.write('* Halcon 自动生成的标注数据加载脚本 \n')
        f.write('dev_update_off()\n')

        for idx, roi in enumerate(roi_data):
            f.write(f'gen_rectangle1(\'roi_{idx}\', {roi[1]}, {roi[0]}, {roi[3]}, {roi[2]})\n')

        f.write('dev_update_on()\n')

关键问题解决方案

1. 编码问题处理

  • 强制指定文件编码为 UTF-8
  • 使用 try-catch 块捕获编码异常
try:
    with open(xml_path, 'r', encoding='utf-8') as f:
        content = f.read()
except UnicodeDecodeError:
    with open(xml_path, 'r', encoding='gbk') as f:
        content = f.read()

2. 路径处理策略

  • 使用 pathlib 模块处理跨平台路径
  • 自动识别相对 / 绝对路径
  • 示例代码:
from pathlib import Path

img_path = Path("dataset/images/img001.jpg")
abs_path = img_path.resolve()  # 获取绝对路径

性能优化方案

  1. 批量处理内存管理
  2. 使用生成器逐文件处理
  3. 及时释放 DOM 解析对象

  4. 多进程加速

from multiprocessing import Pool

def batch_convert(file_list):
    with Pool(processes=4) as pool:
        pool.map(process_single_file, file_list)

扩展性设计

  1. 支持 YOLO 格式的转换适配器:
def parse_yolo_txt(txt_path, img_width, img_height):
    """
    解析 YOLO 格式标注文件
    :param txt_path: 标注文件路径
    :param img_width: 对应图像宽度
    :param img_height: 对应图像高度
    """
    with open(txt_path) as f:
        lines = f.readlines()

    rois = []
    for line in lines:
        class_id, x_center, y_center, w, h = map(float, line.split())
        # 反归一化处理
        x_center *= img_width
        y_center *= img_height
        w *= img_width
        h *= img_height

        rois.append([x_center, y_center, w, h])
    return rois

完整工作流程

  1. 解析原始标注文件(XML/JSON/TXT)
  2. 执行坐标系统转换
  3. 生成 Halcon 脚本文件
  4. 在 HDevelop 中执行脚本

后续改进方向

  • 支持更多标注格式(LabelMe、CVAT 等)
  • 增加可视化校验环节
  • 开发 Halcon 扩展库直接读取标注文件

通过这套方案,我们成功将标注效率提升了 3 - 5 倍,特别适合需要进行大批量数据标注迁移的机器视觉项目。读者可以在此基础上扩展支持更多标注工具的数据转换。

正文完
 0
评论(没有评论)