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

GCP Document AI预处理后边界框与原图对齐问题求助

问题:GCP Document AI预处理后边界框与原图对齐问题

GCP Document AI会对图像进行预处理以消除倾斜等问题,但其生成的边界框对应于预处理后的图像,而非提交给API的原图。目前已能恢复边界框的原始旋转角度,但无法针对GCP添加的裁剪操作完成正确的缩放/调整,导致边界框与原图文字未对齐,标题位置比预期低15%。

相关图像

  • 原图:original image
  • GCP预处理图像:gcp pre-processed image
  • 文本输出:text output

API返回的变换矩阵

[{'rows': 2, 'cols': 3, 'type': 6, 'data': 'r6uHAEEXyL/OYqWImW3vP2QKzkdFXH9AzmKliJlt77+vq4cAQRfIv5yIBglXqaZA'}]

解码倾斜角度的代码

rows = matrix_data[0]["rows"]
cols = matrix_data[0]["cols"]
data_type_code = matrix_data[0]["type"]
data_encoded = matrix_data[0]["data"]
data_binary = base64.b64decode(data_encoded)
matrix = np.frombuffer(data_binary, dtype=dtype).reshape((rows, cols))
rotation_radians = math.atan2(matrix[1, 0], matrix[0, 0])
skew_angle = math.degrees(rotation_radians)

边界框解析代码

box = Box(root=[Point(x=v.get("x", -1), y=v.get("y", -1)) for v in vertices])
box = box.skew_box(self.skew_angle)
box = box.scale_box(self.scale_x, self.scale_y)

比例计算代码

# 提交给API的原图比例
x_ratio = x_len / y_len if y_len != 0 else 1
y_ratio = y_len / x_len if x_len != 0 else 1
longest_side = "x" if x_len > y_len else "y"

# GCP预处理图像的比例
gcp_x_ratio = gcp_height / gcp_width if gcp_width != 0 else 1
gcp_y_ratio = gcp_width / gcp_height if gcp_height != 0 else 1
gcp_longest_side = "x" if gcp_width > gcp_height else "y"

if longest_side != gcp_longest_side:
    gcp_x_ratio, gcp_y_ratio = gcp_y_ratio, gcp_x_ratio

self.scale_x = x_ratio / gcp_x_ratio
self.scale_y = y_ratio / gcp_y_ratio

缩放计算实现代码

def scale_box(self, x: float, y: float, origin: Point = Point(x=0.5, y=0.5)):
    def scale_point_about_origin(point: Point, origin: Point) -> Point:
        translated_x = point.x - origin.x
        translated_y = point.y - origin.y
        scaled_x = translated_x * x
        scaled_y = translated_y * y
        return Point(x=scaled_x + origin.x, y=scaled_y + origin.y)

    return Box(root=[scale_point_about_origin(p, origin) for p in self.root])

边界框校正代码

def skew_box(self, angle: float, width: float = 1, height: float = 1):
    if angle == 0:
        return self

    theta = math.radians(-angle)
    cos_theta = np.cos(theta)
    sin_theta = np.sin(theta)
    origin_x = width / 2
    origin_y = height / 2

    def skew_point(point: Point) -> Point:
        x, y = point.x - origin_x, point.y - origin_y
        x_rotated = x * cos_theta - y * sin_theta
        y_rotated = x * sin_theta + y * cos_theta
        x_rotated, y_rotated = x_rotated + origin_x, y_rotated + origin_y

        return Point(x=x_rotated, y=y_rotated)

    return Box([skew_point(p) for p in self.root])

目前倾斜已校正,但边界框与原图文字未对齐,标题位置比预期低15%。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:16:16