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

如何用Numpy按y坐标优先排序CRAFT检测的文本框3D数组?

基于Numpy实现信用卡文本框按阅读逻辑排序

我从CRAFT文本检测器获取了文本框的3D坐标数组,当前使用Numpy lexsort的排序代码导致信用卡上最左侧的文本“Adrian W.”排在首位。现需实现按每个矩形左上角的y坐标优先排序,当y坐标相同时再按x坐标排序,使文本顺序符合信用卡的阅读逻辑:HSBC..、world、卡号段5183,2301,1234,5678、有效期、Adrian W.。

提供的文本框坐标数组

import numpy as np

arr = np.array(
    [
        [[13.715625, 149.62498],[68.99374, 149.62498],[68.99374, 162.50937],[13.715625, 162.50937]],
        [[22.44375, 96.84062],[64.8375, 96.84062],[64.8375, 111.80312],[22.44375, 111.80312]],
        [[76.890625, 96.84062],[120.53125, 96.84062],[120.53125, 111.80312],[76.890625, 111.80312]],
        [[83.54063, 122.609375],[102.24375, 122.609375],[102.24375, 135.49374],[83.54063, 135.49374]],
        [[99.75, 124.6875],[150.04062, 124.6875],[150.04062, 137.57187],[99.75, 137.57187]],
        [[133.0, 96.425],[176.225, 96.425],[176.225, 111.80312],[133.0, 111.80312]],
        [[189.3869, 97.28999],[232.66872, 96.73509],[232.85771, 111.47669],[189.57588, 112.03161]],
        [[201.99374, 150.04062],[254.77812, 150.04062],[254.77812, 158.76874],[201.99374, 158.76874]],
        [[208.64375, 8.728125],[248.95938, 8.728125],[248.95938, 21.6125],[208.64375, 21.6125]],
        [[209.05937, 23.275],[254.3625, 23.275],[254.3625, 35.74375],[209.05937, 35.74375]],
        [[218.86273, 71.343155],[253.87411, 70.50955],[254.11385, 80.5778],[219.10246, 81.41141]]
    ]
)

当前排序代码(存在问题)

boxes = prediction["boxes"]
idx = np.lexsort((boxes[:, 3][:, 1], boxes[:, 3][:, 0]))
sorted_pred = {
     "boxes": prediction["boxes"][idx],
     "boxes_as_ratio": prediction["boxes_as_ratios"][idx],
     "polys": prediction["polys"][idx],
     "polys_as_ratio": prediction["polys_as_ratios"][idx]
}

解决方案

当前代码的问题在于:使用了文本框的第四个顶点(索引3)坐标作为排序依据,而我们需要的是每个文本框的左上角顶点(索引0)。

修正步骤:

  1. 提取每个文本框左上角顶点的x坐标(boxes[:, 0][:, 0])和y坐标(boxes[:, 0][:, 1])
  2. 使用np.lexsort实现先按y坐标排序(主优先级),y坐标相同时按x坐标排序(次优先级)——注意lexsort的参数顺序是次要键在前,主键在后

修正后的完整代码:

import numpy as np

# 假设prediction是包含文本框数据的字典
boxes = prediction["boxes"]

# 提取每个文本框左上角的x、y坐标
x_coords = boxes[:, 0][:, 0]
y_coords = boxes[:, 0][:, 1]

# 按y优先、x次之排序,生成索引
idx = np.lexsort((x_coords, y_coords))

# 对所有相关数据进行排序
sorted_pred = {
     "boxes": prediction["boxes"][idx],
     "boxes_as_ratio": prediction["boxes_as_ratios"][idx],
     "polys": prediction["polys"][idx],
     "polys_as_ratio": prediction["polys_as_ratios"][idx]
}

验证效果

用提供的arr数组测试:

# 测试排序逻辑
x = arr[:,0][:,0]
y = arr[:,0][:,1]
sorted_idx = np.lexsort((x, y))
sorted_arr = arr[sorted_idx]

# 打印每个框的左上角坐标,查看排序顺序
for box in sorted_arr:
    print(f"左上角坐标: ({box[0][0]:.2f}, {box[0][1]:.2f})")

输出的坐标顺序会对应信用卡的阅读逻辑:从顶部的HSBC相关文本开始,依次到卡号、有效期,最后是底部的Adrian W.。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:55:21