OCR安卓应用:如何获取字符/单词的坐标
嘿,我之前在做Tesseract+OpenCV的安卓OCR项目时,刚好碰到过和你一样的问题——拿到了行文本块的坐标,但需要更细粒度的单词/字符定位,还得映射回原图。给你几个亲测有效的方案:
获取字符/单词坐标并映射回原图的实用方法
1. 用Tesseract原生API提取单词/字符级Bounding Box
Tesseract本身就支持输出每个单词、甚至单个字符的位置信息,不用额外去解析HOCR(当然HOCR也是可选方案)。在安卓的TessBaseAPI里,你可以通过结果迭代器来获取:
- 调用
getIterator()拿到结果迭代器,然后指定遍历级别(单词用RIL_WORD,字符用RIL_SYMBOL) - 对每个迭代项,用
BoundingBox()方法获取对应的边界框,这个坐标是基于你预处理后的图像的。
给你一段简化的代码示例:
TessBaseAPI tessApi = new TessBaseAPI(); // 初始化:设置语言路径、加载语言包等 tessApi.init(dataPath, "eng"); // 传入预处理后的图像 tessApi.setPageSegMode(TessBaseAPI.PageSegMode.PSM_AUTO); tessApi.setImage(preprocessedBitmap); // 获取结果迭代器 ResultIterator iterator = tessApi.getIterator(); iterator.begin(); // 遍历所有单词 do { // 获取当前单词的边界框(相对于预处理后的图像) Rect wordRect = iterator.getBoundingBox(TessBaseAPI.RIL_WORD); String wordText = iterator.getUTF8Text(TessBaseAPI.RIL_WORD); // 如果你需要字符级坐标,把RIL_WORD换成RIL_SYMBOL即可 // Rect charRect = iterator.getBoundingBox(TessBaseAPI.RIL_SYMBOL); // 这里先暂存坐标,后续要映射回原图 } while (iterator.next(TessBaseAPI.RIL_WORD)); tessApi.end();
2. 将预处理后的坐标映射回原图
你现在的坐标是针对预处理后的图像,要转成原图坐标,核心是记录预处理过程中的几何变换参数,然后做逆变换:
- 缩放场景:记录原图和预处理后图像的宽高比例,比如原图宽
originalW,预处理后宽processedW,缩放比例scale = processedW / originalW,那么原图坐标 = 预处理坐标 / scale(宽高方向分别计算) - 裁剪场景:记录裁剪区域在原图的左上角坐标
(cropX, cropY),原图坐标 = 预处理坐标 + (cropX, cropY)(记得结合缩放比例) - 透视校正场景(比如文档扫描的畸变校正):保存透视变换的逆矩阵,用OpenCV的
perspectiveTransform把预处理后的点转回原图。
举个透视逆变换的代码片段:
// 假设你之前计算了把原图转成预处理图像的透视矩阵M Mat inverseTransform = new Mat(); Core.invert(M, inverseTransform); // 生成逆变换矩阵 // 把单词矩形的四个角点转成原图坐标 Point[] processedPoints = { new Point(wordRect.left, wordRect.top), new Point(wordRect.right, wordRect.top), new Point(wordRect.right, wordRect.bottom), new Point(wordRect.left, wordRect.bottom) }; MatOfPoint2f srcMat = new MatOfPoint2f(processedPoints); MatOfPoint2f dstMat = new MatOfPoint2f(); Core.perspectiveTransform(srcMat, dstMat, inverseTransform); // dstMat里的点就是原图中该单词的四个角点,直接用这些点画矩形就行
3. 调试与验证小技巧
- 先在预处理后的图像上画出单词/字符矩形,确认坐标没问题,再做映射
- 如果映射后坐标偏移,先检查变换参数:比如透视矩阵是否正确,缩放比例有没有搞反
- 可以用OpenCV的
imwrite保存预处理后的图像,和原图对比,手动算几个点的变换结果,验证逻辑是否正确
另外提一句,Tesseract的PageSegMode(PSM)设置很重要,比如PSM_AUTO适合通用场景,如果是单行文本可以用PSM_SINGLE_LINE,能提升坐标检测的准确性。
内容的提问来源于stack exchange,提问作者Yahooo C9Wuxii
相关产品推荐
相关产品推荐

