Files
2026-08-21 16:00:13 +08:00

94 lines
2.5 KiB
Python

"""
OCR 结果后处理(纯逻辑,无 IO)。
对 OCR 返回的原始结果做结构化解析、置信度过滤、阅读顺序修正。
不依赖任何外部资源,可独立测试。
"""
from __future__ import annotations
from typing import Any
def filter_low_confidence(
blocks: list[dict[str, Any]],
threshold: float = 0.5,
) -> list[dict[str, Any]]:
"""过滤低置信度结果。
Args:
blocks: 原始 OCR 块列表。
threshold: 置信度阈值(默认 0.5)。
Returns:
过滤后的块列表。
"""
return [b for b in blocks if b.get("confidence", 0) >= threshold]
def merge_adjacent_lines(
blocks: list[dict[str, Any]],
y_tolerance: float = 10.0,
) -> list[dict[str, Any]]:
"""合并同一行的相邻块。
Args:
blocks: OCR 块列表(需含 bbox 坐标)。
y_tolerance: Y 轴容差(px),同一行最大差异。
Returns:
合并后的块列表。
"""
if not blocks:
return []
sorted_blocks = sorted(blocks, key=lambda b: (_center_y(b), _center_x(b)))
merged: list[dict[str, Any]] = []
current = sorted_blocks[0]
for block in sorted_blocks[1:]:
if abs(_center_y(block) - _center_y(current)) <= y_tolerance:
current["text"] += block["text"]
current["confidence"] = max(current["confidence"], block["confidence"])
else:
merged.append(current)
current = block
merged.append(current)
return merged
def extract_text(
blocks: list[dict[str, Any]],
separator: str = "",
) -> str:
"""从 OCR 块中提取纯文本。
Args:
blocks: OCR 块列表。
separator: 块之间的分隔符。
Returns:
拼接后的文本。
"""
return separator.join(b["text"] for b in blocks)
def _center_y(block: dict[str, Any]) -> float:
"""获取块的中心 Y 坐标。"""
pts = block.get("bbox", {}).get("points", block.get("bbox", []))
if pts and isinstance(pts, list) and len(pts) > 0:
ys = [p[1] for p in pts if isinstance(p, (list, tuple)) and len(p) >= 2]
return sum(ys) / len(ys) if ys else 0.0
return 0.0
def _center_x(block: dict[str, Any]) -> float:
"""获取块的中心 X 坐标。"""
pts = block.get("bbox", {}).get("points", block.get("bbox", []))
if pts and isinstance(pts, list) and len(pts) > 0:
xs = [p[0] for p in pts if isinstance(p, (list, tuple)) and len(p) >= 2]
return sum(xs) / len(xs) if xs else 0.0
return 0.0