如何根据图像上的文本实例分离JSON中对应的不同图像名称
问题根因
现有代码存在4个核心问题导致标注无法按图像拆分:
- 未建立图像与文本的索引映射:
imnames存储全量图像名,但遍历文本时没有关联当前文本所属的图像,直接把全量图像名列表拼接到gt键名中 - 标注结构逻辑错误:逐词处理时直接新建gt条目,没有将同一张图像下的多个文本实例归并到同一个gt数组下
- IO逻辑冗余:每处理一个单词就重复读写整个JSON文件,易出现写入覆盖、性能低下问题
- 坐标索引错位:
start变量累加逻辑未和图像维度绑定,易出现跨图像的坐标、文本混淆
修复代码
核心逻辑是先按图像维度分组所有文本实例,再统一生成符合格式的标注文件,避免逐词处理的映射混乱:
import h5py import json import numpy as np # 加载H5文件,一次性读取全量数据避免重复IO db = h5py.File('results/Output.h5', 'r') imnames = sorted(db['data'].keys()) result = {} # 逐图像处理,保证图像、文本、坐标一一对应 for gt_idx, img_name in enumerate(imnames, start=1): # 读取当前图像关联的所有数据,按你实际H5字段名调整读取逻辑 img_group = db['data'][img_name] text_list = [item.decode('utf-8') for item in img_group['text'][:]] # 读取当前图所有文本 char_bb = img_group['charBB'][:] # 读取当前图所有字符边界框 img_annotations = [] char_offset = 0 # 遍历当前图像内的所有单词,生成单条标注 for word in text_list: word_len = len(word) word_points = [] # 提取单词四个角点坐标(如果需要字符级点可调整该段逻辑) for corner in range(4): x_cor = float(np.mean(char_bb[0][0][corner][char_offset : char_offset + word_len])) y_cor = float(np.mean(char_bb[0][1][corner][char_offset : char_offset + word_len])) word_points.append([round(x_cor, 2), round(y_cor, 2)]) # 语言判断逻辑可自行扩展 lang = "Chinese" if any('\u4e00' <= c <= '\u9fff' for c in word) else "Latin" img_annotations.append({ "points": word_points, "transcription": word, "language": lang, "illegibility": False }) char_offset += word_len # 按要求格式绑定gt键和当前图的所有标注 result[f"gt_{gt_idx}"] = img_annotations # 一次性写入标注文件 with open("annotation.json", "w", encoding="utf-8") as f: json.dump(result, f, ensure_ascii=False, indent=2) db.close()
适配说明
- 如果你的H5文件是全局存储所有文本、边界框而非按图像分组存储,只需额外维护一个长度与
textToList一致的word_img_map数组,每个位置存储对应单词所属的图像索引,遍历文本时按索引分组即可,核心标注结构逻辑不变 - 如果需要保留图像名与gt键的映射关系,可以额外在结果中加一个
img_name_map字段存储{gt_idx: img_name}的对应关系,方便后续溯源 - 坐标提取逻辑如果是输出字符级多边形点,直接修改角点计算部分的代码即可,不需要调整分组和JSON结构逻辑
- 输出结构完全匹配预期:每个
gt_*键对应一个数组,数组内为该图像包含的所有文本实例标注
内容的提问来源于stack exchange,提问作者Leon
相关产品推荐
相关产品推荐

