使用Tesseract、OpenCV与Python如何获取整行文本的bounding box?
方案1:优先使用pytesseract自带行标识分组
你获取的boxes数据中已经包含block_num、par_num、line_num三个字段,三个字段的组合可以唯一标识一行文本,直接基于这三个字段分组即可得到整行结果,无需额外做坐标判断,准确率最高。
在你原有代码基础上补充以下逻辑即可:
# 按唯一行标识分组 line_groups = boxes.groupby(['block_num', 'par_num', 'line_num']) line_results = [] for (block, par, line), group_df in line_groups: # 计算整行边界框:取当前行所有单词框的最左、最上、最右、最下坐标 line_left = group_df['left'].min() line_top = group_df['top'].min() line_right = (group_df['left'] + group_df['width']).max() line_bottom = (group_df['top'] + group_df['height']).max() line_bbox = (line_left, line_top, line_right - line_left, line_bottom - line_top) # 按单词顺序拼接整行文本 line_text = ' '.join(group_df.sort_values('word_num')['text'].tolist()) line_results.append({'text': line_text, 'bbox': line_bbox}) # 输出结果并绘制整行边界框 for item in line_results: print(f"整行文本:{item['text']},边界框:{item['bbox']}") x, y, w, h = item['bbox'] cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) # 绿色粗框标识整行 cv2.imshow('行识别结果', img) cv2.waitKey(0)
方案2:基于top值相近特征聚类合并
如果遇到tesseract行识别结果偏差的场景,可以基于你观察到的「同一行单词top值相近」的特征做聚类合并,实现逻辑如下:
# 先对所有单词框按top值升序、left值升序排序 sorted_boxes = boxes.sort_values(['top', 'left']).reset_index(drop=True) # 可根据实际文本行高调整容差阈值,示例数据中同个行top值最大差为4,设5即可覆盖 top_diff_threshold = 5 line_groups = [] current_line = [sorted_boxes.iloc[0]] for i in range(1, len(sorted_boxes)): current_box = sorted_boxes.iloc[i] # 和当前行最后一个单词的top值差小于阈值则归为同一行 if abs(current_box['top'] - current_line[-1]['top']) < top_diff_threshold: current_line.append(current_box) else: line_groups.append(pd.DataFrame(current_line)) current_line = [current_box] # 加入最后一行 line_groups.append(pd.DataFrame(current_line)) # 后续计算整行bbox、拼接文本逻辑和方案1一致 line_results = [] for group_df in line_groups: line_left = group_df['left'].min() line_top = group_df['top'].min() line_right = (group_df['left'] + group_df['width']).max() line_bottom = (group_df['top'] + group_df['height']).max() line_bbox = (line_left, line_top, line_right - line_left, line_bottom - line_top) line_text = ' '.join(group_df.sort_values('left')['text'].tolist()) line_results.append({'text': line_text, 'bbox': line_bbox})
如果识别的图像存在倾斜问题,建议先做倾斜校正再识别,可以大幅降低行合并的误差。
内容的提问来源于stack exchange,提问作者MimiS
相关产品推荐
相关产品推荐

