基于Azure OCR与Pandas,如何定位标签边界框的右侧/下方紧邻框?
解决思路与代码实现
假设你的Pandas数据集df包含以下字段:
text: OCR识别出的文本内容bbox_x1,bbox_y1: 边界框左上角坐标bbox_x2,bbox_y2: 边界框右下角坐标mid_x,mid_y: 边界框中点坐标
1. 筛选目标标签框
先定位到包含目标标签(比如"SERIAL NUMBER")的行:
# 模糊匹配标签,避免大小写或空格差异 label_rows = df[df['text'].str.contains('SERIAL NUMBER', case=False)]
2. 定义位置判断逻辑
针对每个标签框,判断其他框是否在右侧有效区域或正下方紧邻区域:
- 右侧判断:
- 目标框的左边界 ≥ 标签框的右边界(确保在右侧)
- 目标框的垂直范围与标签框有重叠(属于同一行附近),即目标框的上边界 ≤ 标签框的下边界,且目标框的下边界 ≥ 标签框的上边界
- 正下方紧邻判断:
- 目标框的上边界 ≥ 标签框的下边界(确保在下方)
- 目标框与标签框的水平范围重叠度≥70%(确保是正下方,而非偏左/偏右)
- 目标框与标签框的垂直间距小于设定阈值(比如20像素,根据图片分辨率调整)
3. 遍历标签框匹配对应数值
import numpy as np # 设置垂直紧邻阈值(根据实际图片调整) vertical_threshold = 20 for idx, label_row in label_rows.iterrows(): # 提取标签框的坐标信息 label_x1 = label_row['bbox_x1'] label_y1 = label_row['bbox_y1'] label_x2 = label_row['bbox_x2'] label_y2 = label_row['bbox_y2'] label_mid_x = label_row['mid_x'] label_mid_y = label_row['mid_y'] # 筛选所有非标签框的行 other_rows = df[df.index != idx] # 判断每个框是否符合右侧或下方条件 candidates = other_rows.copy() # 右侧条件 candidates['is_right'] = ( (candidates['bbox_x1'] >= label_x2) & (candidates['bbox_y1'] <= label_y2) & (candidates['bbox_y2'] >= label_y1) ) # 下方紧邻条件 # 计算水平重叠长度 overlap_x = np.maximum(0, np.minimum(candidates['bbox_x2'], label_x2) - np.maximum(candidates['bbox_x1'], label_x1)) # 计算标签框的宽度 label_width = label_x2 - label_x1 # 重叠率≥70% overlap_ratio = overlap_x / label_width candidates['is_below'] = ( (candidates['bbox_y1'] >= label_y2) & (candidates['bbox_y1'] - label_y2 <= vertical_threshold) & (overlap_ratio >= 0.7) ) # 筛选出所有候选框(右侧或下方) valid_candidates = candidates[candidates['is_right'] | candidates['is_below']] if not valid_candidates.empty: # 计算候选框与标签框中点的欧氏距离,取最近的 valid_candidates['distance'] = np.sqrt( (valid_candidates['mid_x'] - label_mid_x)**2 + (valid_candidates['mid_y'] - label_mid_y)**2 ) closest_candidate = valid_candidates.loc[valid_candidates['distance'].idxmin()] print(f"标签'{label_row['text']}'对应的数值:{closest_candidate['text']}") else: print(f"未找到标签'{label_row['text']}'对应的数值框")
4. 优化建议
- 如果图片存在倾斜,可以先对OCR结果做旋转校正,避免位置判断出错
- 垂直阈值和重叠率可以根据实际设备面板的布局调整,比如密集布局的面板阈值调小,松散布局调大
- 若标签和数值在同一框内(比如"SERIAL NUMBER: 12345"),可以直接对标签文本做分割提取数值,无需匹配边界框
内容的提问来源于stack exchange,提问作者Ian Dunsirn
相关产品推荐
相关产品推荐

