如何将Google OCR识别的单词框聚类合并为文本块?
单词检测框合并为文本块的解决方案
方法1:基于OpenCV形态学操作(适配你已有的填充矩形步骤)
- 基于你生成的填充矩形掩码图,执行形态学膨胀操作:
- 用
cv2.getStructuringElement(cv2.MORPH_RECT, (w, h))生成矩形结构元素,调整w和h的大小——如果是横向排版,设置w > h来合并同一行的单词;如果要合并整栏,增大h的值 - 调用
cv2.dilate(mask, kernel, iterations=1)膨胀图像,让同一文本块的填充区域连通
- 用
- 对膨胀后的图像提取轮廓:
- 用
cv2.findContours找到所有连通区域的轮廓 - 对每个轮廓计算最小外接矩形(
cv2.boundingRect),得到合并后的文本块边界
- 用
- 注意:结构元素的尺寸需要根据你的文档排版(行间距、栏间距)调整,多测试几组参数找到最优值
方法2:基于几何聚类的DBSCAN算法
适合排版不规则的场景,通过框的位置关系自动聚类:
- 提取所有单词框的中心坐标(或四角坐标),整理成数组格式
- 用DBSCAN算法按距离聚类,把位置相近的框归为同一文本块:
from sklearn.cluster import DBSCAN import numpy as np # 假设boxes是所有单词框的列表,每个框格式为(x1, y1, x2, y2) centers = np.array([[(x1+x2)/2, (y1+y2)/2] for x1, y1, x2, y2 in boxes]) # eps为聚类距离阈值,min_samples为聚类最小样本数,按需调整 db = DBSCAN(eps=40, min_samples=2) cluster_labels = db.fit_predict(centers) # 生成每个聚类对应的文本块边界 text_blocks = [] for label in set(cluster_labels): if label == -1: # 跳过噪声点(孤立的单词框) continue group_boxes = [boxes[i] for i in range(len(boxes)) if cluster_labels[i] == label] # 计算组内所有框的最小外接矩形 all_x = [coord for box in group_boxes for coord in (box[0], box[2])] all_y = [coord for box in group_boxes for coord in (box[1], box[3])] text_blocks.append((min(all_x), min(all_y), max(all_x), max(all_y)))
方法3:基于排版规则的行/栏合并
适合规整的分栏文档:
- 行分组:把所有单词框按y坐标排序,将y坐标差小于行高阈值的框归为同一行
- 行内合并:同一行内的框按x坐标排序,相邻框x间距小于单词间距阈值时,合并为行块
- 栏合并:将上下相邻的行块合并——如果两行块的x范围重叠度超过设定阈值(比如60%),且y间距小于行间距阈值,就合并为一个栏文本块
内容的提问来源于stack exchange,提问作者burlesquel
相关产品推荐
相关产品推荐

