如何通过tess-two的TessBaseAPI正确提取文本及对应boxRects?
如何用tess-two正确提取文本及对应Bounding Box?
我之前也踩过tess-two的这个坑,想要精准提取每个单词和对应的bounding box,确实得用对API才行。下面给你几个靠谱的解决方案,比你用HOCR正则的方法要高效稳定得多:
方法一:使用ResultIterator(官方推荐)
这是最稳妥的方式,能直接保证每个单词的文本和它的bounding box完全对应,不会出现错位问题。
具体代码实现如下:
// 获取结果迭代器 val resultIterator = tesseract.resultIterator // 开始遍历单词级别内容 resultIterator.begin() do { // 提取当前单词的文本 val wordText = resultIterator.getUTF8Text(PageIteratorLevel.RIL_WORD) // 获取bounding box的四个坐标(左、上、右、下) val rectCoords = IntArray(4) resultIterator.boundingBox(PageIteratorLevel.RIL_WORD, rectCoords) val left = rectCoords[0] val top = rectCoords[1] val right = rectCoords[2] val bottom = rectCoords[3] // 这里就可以处理你的单词和对应的位置了 Log.i(TAG, "单词:$wordText,位置:左=$left, 上=$top, 右=$right, 下=$bottom") // 循环遍历下一个单词 } while (resultIterator.next(PageIteratorLevel.RIL_WORD))
这个方法直接调用tess内部的迭代器,性能和准确性都有保障,完全不需要额外的字符串解析操作。
方法二:修复getWords的使用方式
你之前用getWords时出现乱码,是因为Word对象的data是字节数组,不能直接调用toString(),需要指定UTF-8编码来转换:
val words = tesseract.getWords for (word in words) { // 正确将字节数组转为字符串 val wordText = String(word.data, Charsets.UTF_8) // 获取对应的bounding box val boxRect = word.boxRects Log.i(TAG, "单词:$wordText,位置:$boxRect") }
不过这个方法偶尔会出现单词顺序和getUTF8Text不一致的情况,所以还是更推荐第一种迭代器的方式。
为什么不推荐你用HOCR正则的方法?
虽然解析HOCR能实现需求,但它有几个明显的缺点:
- 性能差:需要生成完整的HOCR文本,再用正则反复匹配,比直接调用API慢很多
- 不稳定:如果tess版本更新导致HOCR格式变化,你的正则表达式就会直接失效
- 代码冗余:要写多段正则来分别提取文本和坐标,后续维护成本高
所以尽量优先使用官方提供的API来处理,更省心可靠。
内容的提问来源于stack exchange,提问作者Axel Eriksson
相关产品推荐
相关产品推荐

