如何基于正则条件提取Google Vision OCR JSON元素并逐个获取坐标?
基于Google Vision API的OCR元素正则匹配与坐标提取方案
需求说明
项目使用Google Vision API的OCR识别结果(JSON格式,包含所有元素的描述与坐标),需要实现:
- 遍历JSON结果,通过正则匹配筛选目标元素
- 提取匹配元素的描述与坐标并存储
- 基于坐标判断元素间是否平行
现有代码仅能硬编码提取描述为a的元素坐标,无法适配动态正则匹配的场景,以下是改进实现方案。
现有代码问题
原代码存在三个核心问题:
- 硬编码匹配字符串
"a",无法支持正则动态筛选 - 循环中未遍历
__nodes列表,直接使用未定义的__node变量,会引发NameError - 仅返回单个元素的坐标列表,无法处理多个匹配元素的情况
改进实现方案
核心思路
- 接收正则表达式作为参数,动态匹配元素描述
- 遍历所有
textAnnotations节点,用正则匹配筛选目标元素 - 将每个匹配元素的描述和坐标集合整理为结构化数据(如字典)存入列表,方便后续处理
完整代码实现
import json import traceback import re def get_json(): try: with open('json_file.json', 'r', encoding="utf-8") as f: origin_data = json.load(f) return origin_data except Exception as e: print(e) print(traceback.format_exc()) return None def get_matched_elements(origin_data, pattern): """ 通过正则匹配提取目标元素的描述与坐标 :param origin_data: Google Vision API返回的OCR JSON数据 :param pattern: 正则表达式字符串,用于匹配元素描述 :return: 匹配元素列表,每个元素为{"description": str, "coords": list} """ matched_elements = [] if not origin_data or 'textAnnotations' not in origin_data: return matched_elements regex = re.compile(pattern) # 跳过第一个元素(textAnnotations第一个是全局识别文本,不是单个元素) for node in origin_data['textAnnotations'][1:]: desc = node.get('description', '') if regex.fullmatch(desc): # 提取四个顶点的坐标,整理为[x1,y1,x2,y2,x3,y3,x4,y4]格式 coords = [] for vertex in node['boundingPoly']['vertices']: coords.append(vertex.get('x', 0)) coords.append(vertex.get('y', 0)) matched_elements.append({ "description": desc, "coords": coords }) return matched_elements
调用示例
# 匹配单个小写字母(如a、b、c、d、e) ocr_data = get_json() if ocr_data: # 正则匹配单个小写英文字母 matched = get_matched_elements(ocr_data, r'^[a-e]$') for elem in matched: print(f"元素: {elem['description']}, 坐标: {elem['coords']}")
元素平行判断思路
要判断两个矩形元素是否平行,可通过计算矩形边的向量叉积实现(叉积为0则两向量平行):
def is_parallel(elem1, elem2): """判断两个矩形元素是否平行""" def get_edge_vectors(coords): # 从坐标列表中提取两条邻边的向量 # coords格式:[x1,y1,x2,y2,x3,y3,x4,y4] v1 = (coords[2]-coords[0], coords[3]-coords[1]) v2 = (coords[4]-coords[2], coords[5]-coords[3]) return [v1, v2] vecs1 = get_edge_vectors(elem1['coords']) vecs2 = get_edge_vectors(elem2['coords']) # 计算向量叉积,叉积为0则平行 def cross_product(v_a, v_b): return v_a[0]*v_b[1] - v_a[1]*v_b[0] # 检查任意一组对应边是否平行 if cross_product(vecs1[0], vecs2[0]) == 0 or cross_product(vecs1[1], vecs2[1]) == 0: return True return False
内容的提问来源于stack exchange,提问作者Chris Chow
相关产品推荐
相关产品推荐

