共计 2557 个字符,预计需要花费 7 分钟才能阅读完成。
格式差异与核心痛点
Halcon 和 AnyLabelImg 的数据结构差异主要体现在三个方面:

- 标注格式差异:
- AnyLabelImg 默认使用 Pascal VOC 的 XML 格式或 COCO 的 JSON 格式
-
Halcon 使用自研的 HDict 数据结构存储 ROI 信息
-
坐标系差异:
- 图像坐标系原点位置不同(左上角 vs 中心点)
-
YOLO 格式使用归一化坐标,需进行反归一化计算
-
数据结构差异:
- Halcon 要求明确区分 Region/XLD 等不同图形类型
- 多边形标注需要特殊处理亚像素精度转换
技术实现方案
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() # 获取绝对路径
性能优化方案
- 批量处理内存管理:
- 使用生成器逐文件处理
-
及时释放 DOM 解析对象
-
多进程加速:
from multiprocessing import Pool
def batch_convert(file_list):
with Pool(processes=4) as pool:
pool.map(process_single_file, file_list)
扩展性设计
- 支持 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
完整工作流程
- 解析原始标注文件(XML/JSON/TXT)
- 执行坐标系统转换
- 生成 Halcon 脚本文件
- 在 HDevelop 中执行脚本
后续改进方向
- 支持更多标注格式(LabelMe、CVAT 等)
- 增加可视化校验环节
- 开发 Halcon 扩展库直接读取标注文件
通过这套方案,我们成功将标注效率提升了 3 - 5 倍,特别适合需要进行大批量数据标注迁移的机器视觉项目。读者可以在此基础上扩展支持更多标注工具的数据转换。
正文完
发表至: 计算机视觉
四天前
