You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算文本行多边形的中心线或基线?

文本行Polygon的基线/中心线计算方案

核心思路

历史文档的文本行Polygon通常是水平(或轻微倾斜)的细长形状,直接用几何中心(shapely.centroid)会因边缘不规则偏离实际基准,需针对性提取边缘或中线:


1. 提取基线(文本底部对齐线)

场景1:标准四边形文本行

若Polygon顶点按左上→右上→右下→左下闭合,直接取底部两个顶点连线:

from shapely.geometry import Polygon, LineString

# 示例坐标(左上、右上、右下、左下)
poly_coords = [(12, 65), (145, 65), (145, 42), (12, 42)]
poly = Polygon(poly_coords)

# 提取底部边缘作为基线
baseline = LineString([poly_coords[2], poly_coords[3]])
print("基线坐标:", list(baseline.coords))

场景2:不规则/倾斜文本行

先计算最小外接矩形(MBR),再取MBR的底部边缘:

from shapely.geometry import Polygon, LineString

poly = Polygon(your_irregular_poly_coords)
# 获取旋转后的最小外接矩形
mbr = poly.minimum_rotated_rectangle
mbr_coords = list(mbr.exterior.coords)

# 筛选y值最小的两个点(底部边缘)
sorted_points = sorted(mbr_coords, key=lambda p: p[1])
baseline = LineString(sorted_points[:2])

2. 计算中心线(垂直中线)

通过上下边缘的y值均值生成水平中线:

from shapely.geometry import Polygon, LineString

poly = Polygon(your_poly_coords)
# 提取所有顶点的x、y范围
xs = [p[0] for p in poly.exterior.coords]
ys = [p[1] for p in poly.exterior.coords]

min_x, max_x = min(xs), max(xs)
min_y, max_y = min(ys), max(ys)
mid_y = (min_y + max_y) / 2

# 生成水平中心线
center_line = LineString([(min_x, mid_y), (max_x, mid_y)])
print("中心线坐标:", list(center_line.coords))

3. 倾斜文本行的骨架化提取

针对手写/严重倾斜的文本行,用骨架提取获取中心骨架:

import numpy as np
from shapely.geometry import LineString
from skimage.morphology import skeletonize
from skimage.draw import polygon2mask

poly = Polygon(your_poly_coords)
xs = [p[0] for p in poly.exterior.coords]
ys = [p[1] for p in poly.exterior.coords]
min_x, max_x = min(xs), max(xs)
min_y, max_y = min(ys), max(ys)

# 转换为二进制掩码
width = int(max_x - min_x + 1)
height = int(max_y - min_y + 1)
rel_coords = [(x - min_x, y - min_y) for x, y in poly.exterior.coords]
mask = polygon2mask((height, width), rel_coords).astype(np.uint8)

# 骨架提取
skeleton = skeletonize(mask)

# 提取骨架中最长的水平线段作为中心线
y_coords, x_coords = np.where(skeleton)
abs_points = [(x + min_x, y + min_y) for x, y in zip(x_coords, y_coords)]

# 按y值分组,取点数最多的y组生成线段
from collections import defaultdict
y_groups = defaultdict(list)
for x, y in abs_points:
    y_groups[y].append(x)
max_count = max(len(xs) for xs in y_groups.values())
best_y = [y for y, xs in y_groups.items() if len(xs) == max_count][0]
best_xs = y_groups[best_y]
center_line = LineString([(min(best_xs), best_y), (max(best_xs), best_y)])

问题原因说明

  • shapely.centroid不可靠:几何中心会受Polygon局部不规则(如字符突出)影响,偏离文本行的实际基准线
  • 自行代码得到上线:大概率是误取了y值最大的顶部顶点(需确认Polygon顶点闭合顺序是否为左上→右上→右下→左下)

内容的提问来源于stack exchange,提问作者bsteo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 09:35:11