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

如何在Vision API中从上到下排序TextBlock?解决文本读取顺序错乱问题

解决Vision API OCR文本读取顺序错误的问题

嘿,我碰到过不少开发者遇到这个问题——Google Vision API的OCR检测返回的TextBlock默认是按检测算法的内部逻辑排序的,完全不是我们常规的从上到下、从左到右的阅读顺序,所以才会出现页面底部文本先被读取的混乱情况。

问题根源

Vision API的检测结果顺序取决于它识别文本块的先后优先级,和文本在页面上的空间位置没有直接关联。如果不对结果做额外处理,直接按默认顺序遍历,自然会出现顺序错乱的问题。

解决方案:按空间位置重新排序文本块

我们可以把返回的SparseArray<TextBlock>转换成可排序的集合,然后根据每个文本块的**垂直坐标(y轴)和水平坐标(x轴)**来排序,模拟人类的阅读顺序:

  1. 优先按文本块顶部的y坐标排序,y值越小(越靠上)越靠前
  2. 对于同一行的文本块(y坐标相近),再按左侧的x坐标排序,x值越小(越靠左)越靠前

修改后的receiveDetections方法示例

@Override 
public void receiveDetections(Detector.Detections<TextBlock> detections) { 
    mGraphicOverlay.clear(); 
    SparseArray<TextBlock> items = detections.getDetectedItems();
    
    // 把SparseArray转换成List以便排序
    List<TextBlock> textBlockList = new ArrayList<>();
    for (int i = 0; i < items.size(); i++) {
        textBlockList.add(items.valueAt(i));
    }
    
    // 自定义排序规则:先按y轴区分行,再按x轴排序同行文本
    Collections.sort(textBlockList, new Comparator<TextBlock>() {
        @Override
        public int compare(TextBlock o1, TextBlock o2) {
            // 获取文本块的顶部y坐标
            float y1 = o1.getBoundingBox().top;
            float y2 = o2.getBoundingBox().top;
            
            // 设定行间距阈值,判断是否属于同一行(可根据实际场景调整)
            float lineThreshold = 25;
            if (Math.abs(y1 - y2) < lineThreshold) {
                // 同一行内按x轴从左到右排序
                float x1 = o1.getBoundingBox().left;
                float x2 = o2.getBoundingBox().left;
                return Float.compare(x1, x2);
            } else {
                // 不同行按y轴从上到下排序
                return Float.compare(y1, y2);
            }
        }
    });
    
    // 遍历排序后的文本块进行处理
    for (TextBlock textBlock : textBlockList) {
        if (textBlock != null && textBlock.getValue() != null) {
            mGraphicOverlay.add(new TextGraphic(mGraphicOverlay, textBlock));
            // 这里可以添加你的文本处理逻辑,比如拼接、输出等
            String detectedText = textBlock.getValue();
            // ...
        }
    }
}

小提示

  • lineThreshold的值可以根据你的实际场景调整:如果文本行间距较大,适当增大阈值;如果是密集排版的文本,减小阈值能更精准地判断同行文本。
  • 如果需要支持竖排文本(比如中文竖排),只需要调换排序逻辑,优先按x轴区分列,再按y轴排序同列文本即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:10:12