如何从图表图片提取数据并保留原有层级顺序?
组织架构图OCR层级保留方案
实现原理
常规tesseract.image_to_string仅返回纯文本内容,丢失了文本块的坐标信息,而组织架构图的层级关系完全可以通过「文本块相对位置+通用排版规则」还原,不需要引入额外复杂模型即可实现需求。
具体实现步骤
1. 提取带坐标的文本块
改用tesseract的image_to_data接口,获取每个识别结果的位置、置信度信息,过滤无效值后计算每个文本块的中心坐标,用于后续层级判断。
import pytesseract from PIL import Image import pandas as pd # 读取图片并提取全量OCR信息 img = Image.open('test.png') ocr_df = pytesseract.image_to_data(img, output_type=pytesseract.Output.DATAFRAME) # 过滤低置信度和空文本结果 valid_ocr = ocr_df[(ocr_df['conf'] > 60) & (ocr_df['text'].str.strip() != '')].copy() # 计算每个文本块的中心坐标,方便后续位置判断 valid_ocr['center_x'] = valid_ocr['left'] + valid_ocr['width'] / 2 valid_ocr['center_y'] = valid_ocr['top'] + valid_ocr['height'] / 2
2. 按垂直坐标划分层级
常规组织架构图的排版逻辑为:垂直位置越靠上的节点层级越高,同一层级节点的垂直坐标差值在固定阈值内。我们可以基于这个规则把所有节点划到不同层级:
# 按垂直坐标升序排序,越靠前的节点层级越高 valid_ocr = valid_ocr.sort_values('center_y').reset_index(drop=True) y_threshold = 50 # 可根据图片分辨率调整阈值 layers = [] current_layer = [valid_ocr.iloc[0]] for idx in range(1, len(valid_ocr)): node = valid_ocr.iloc[idx] # 和当前层第一个节点的y坐标差值小于阈值则归为同一层 if abs(node['center_y'] - current_layer[0]['center_y']) < y_threshold: current_layer.append(node) else: layers.append(current_layer) current_layer = [node] layers.append(current_layer)
3. 匹配上下级关系
遍历所有层级,每个节点的直属上级为上一层中水平坐标和它最接近的节点,最终输出结构化层级字典:
hierarchy = {} # 从第二层开始匹配上级 for layer_idx in range(1, len(layers)): current_layer = layers[layer_idx] prev_layer = layers[layer_idx - 1] for node in current_layer: # 找上层水平坐标最接近的节点作为直属上级 nearest_manager = min(prev_layer, key=lambda x: abs(x['center_x'] - node['center_x'])) if nearest_manager['text'] not in hierarchy: hierarchy[nearest_manager['text']] = [] hierarchy[nearest_manager['text']].append(node['text'])
优化方案(可选)
如果你的架构图存在清晰的上下级连接线,可以用OpenCV做简单的直线检测,判断两个节点之间是否存在连接线,进一步提升匹配准确率。
输出说明
最终输出的hierarchy为嵌套字典结构,完全保留原架构图的上下级关系,你可以根据需求转换为JSON、树形列表等任意结构化格式。
内容的提问来源于stack exchange,提问作者user_12
相关产品推荐
相关产品推荐

