Tess-two - Tess-two 文字识别(Tess-two 概述、Tess-two 文字识别、补充情况)

一、Tess-two 概述

  1. Tess-two 是 Tesseract OCR 引擎在 Android 平台上的一个封装库,用于实现离线文字识别

  2. Tess-two 的 GitHub 官网:https://github.com/rmtheis/tess-two


二、Tess-two 文字识别

1、演示
(1)Dependencies
  • 模块级 build.gradle
implementation 'com.rmtheis:tess-two:9.1.0'
(2)Tessdata
  1. 从 Tessdata 仓库 https://github.com/tesseract-ocr/tessdata 下载所需语言包

  2. 例如,eng.traineddata 用于英文、chi_sim.traineddata 用于简体中文

  3. 将下载的 .traineddata 文件放在项目的 src/main/assets 目录下

(3)Manifest
  • AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
(4)Test
  • MainActivity.java
public class MainActivity extends AppCompatActivity {public static final String TAG = MainActivity.class.getSimpleName();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED|| checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(),o -> {for (Map.Entry<String, Boolean> entry : o.entrySet()) {Log.i(TAG, entry.getKey() + " : " + entry.getValue());}boolean allGranted = true;for (Map.Entry<String, Boolean> entry : o.entrySet()) {if (!entry.getValue()) {allGranted = false;break;}}if (allGranted) {test();} else {Log.i(TAG, "权限未全部授予");}}).launch(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE});} else {test();}}private void test() {copyTessDataToStorage("chi_sim.traineddata", "eng.traineddata");TessBaseAPI tessBaseAPI = new TessBaseAPI();String tesseractDirPath = getExternalFilesDir(null) + "/tesseract/";boolean initResult = tessBaseAPI.init(tesseractDirPath, "chi_sim+eng");if (!initResult) {Log.i(TAG, "初始化 Tesseract 失败");return;}Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test_img);tessBaseAPI.setImage(bitmap);String result = tessBaseAPI.getUTF8Text();Log.i(TAG, "result: " + result);}public void copyTessDataToStorage(String... tessDataFiles) {String tessDataDirPath = getExternalFilesDir(null) + "/tesseract/tessdata/";File tessDataDir = new File(tessDataDirPath);if (!tessDataDir.exists()) {tessDataDir.mkdirs();}AssetManager assetManager = getAssets();for (String fileName : tessDataFiles) {File outFile = new File(tessDataDirPath + fileName);if (outFile.exists()) continue;try (InputStream in = assetManager.open(fileName);OutputStream out = new FileOutputStream(outFile)) {byte[] buffer = new byte[1024];int read;while ((read = in.read(buffer)) != -1) {out.write(buffer, 0, read);}} catch (IOException e) {e.printStackTrace();}}}
}
# 输出结果result: 张 三
2、解读
(1)请求权限
  1. 通过 checkSelfPermission 方法检查是否已有权限,如果已有权限,执行测试代码

  2. 如果没有权限,则使用 Activity Result API 请求权限

  3. 请求完成后,检查所有权限是否都被授予,如果都被授予,执行测试代码

// 检查是否已有权限
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED|| checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {// 如果没有权限,请求权限registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(),o -> {for (Map.Entry<String, Boolean> entry : o.entrySet()) {Log.i(TAG, entry.getKey() + " : " + entry.getValue());}boolean allGranted = true;for (Map.Entry<String, Boolean> entry : o.entrySet()) {if (!entry.getValue()) {allGranted = false;break;}}// 检查所有权限是否都被授予if (allGranted) {// 如果都被授予,执行测试代码test();} else {Log.i(TAG, "权限未全部授予");}}).launch(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE});
} else {// 如果已有权限,执行测试代码test();
}
(2)复制 Tessdata
  • src/main/assets 目录复制 .traineddata 文件到应用私有存储外部目录的 files/tesseract/tessdata/ 目录
public void copyTessDataToStorage(String... tessDataFiles) {// 创建目标目录String tessDataDirPath = getExternalFilesDir(null) + "/tesseract/tessdata/";File tessDataDir = new File(tessDataDirPath);if (!tessDataDir.exists()) {tessDataDir.mkdirs();}AssetManager assetManager = getAssets();for (String fileName : tessDataFiles) {File outFile = new File(tessDataDirPath + fileName);if (outFile.exists()) continue; // 如果文件已存在则跳过try (InputStream in = assetManager.open(fileName);OutputStream out = new FileOutputStream(outFile)) {byte[] buffer = new byte[1024];int read;while ((read = in.read(buffer)) != -1) {out.write(buffer, 0, read);}} catch (IOException e) {e.printStackTrace();}}
}
(3)初始化与识别
  • 调用 init 方法初始化 Tesseract
  1. 第一个参数是包含 Tessdata 目录的父目录,Tessdata 在 files/tesseract/tessdata/ 目录,那么这里就是 files/tesseract/

  2. 第二个参数是语言代码,多个可以用加号 + 连接,chi_sim+eng 表示识别中文和英文

TessBaseAPI tessBaseAPI = new TessBaseAPI();String tesseractDirPath = getExternalFilesDir(null) + "/tesseract/";boolean initResult = tessBaseAPI.init(tesseractDirPath, "chi_sim+eng");
if (!initResult) {Log.i(TAG, "初始化 Tesseract 失败");return;
}
  • 调用 setImage 方法识别,调用 getUTF8Text 获取识别结果
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test_img);tessBaseAPI.setImage(bitmap);String result = tessBaseAPI.getUTF8Text();Log.i(TAG, "result: " + result);

三、补充情况

1、Bitmap 获取失败的情况
  • 这里从一个不存在的资源文件获取 Bitmap
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), 1001);Log.i(TAG, "bitmap: " + bitmap);tessBaseAPI.setImage(bitmap);String result = tessBaseAPI.getUTF8Text();Log.i(TAG, "result: " + result);
# 输出结果bitmap: null
...
FATAL EXCEPTION: main
Process: com.my.ocr_tesseract, PID: 25149
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.my.ocr_tesseract/com.my.ocr_tesseract.MainActivity}: java.lang.RuntimeException: Failed to read bitmap
2、识别连笔字
  • Tess-two 文字识别,识别连笔字的能力有限,推荐使用 ML Kit 数字墨水识别
# 输出结果result: 
# 输出结果result: 锄
3、使用应用私有存储内部目录
  • 也可以使用应用私有存储内部目录,这样也不需要请求权限
private void test() {copyTessDataToStorage("chi_sim.traineddata", "eng.traineddata");TessBaseAPI tessBaseAPI = new TessBaseAPI();String tesseractDirPath = getFilesDir() + "/tesseract/";boolean initResult = tessBaseAPI.init(tesseractDirPath, "chi_sim+eng");if (!initResult) {Log.i(TAG, "初始化 Tesseract 失败");return;}Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test_img);Log.i(TAG, "bitmap: " + bitmap);tessBaseAPI.setImage(bitmap);String result = tessBaseAPI.getUTF8Text();Log.i(TAG, "result: " + result);
}public void copyTessDataToStorage(String... tessDataFiles) {String tessDataDirPath = getFilesDir() + "/tesseract/tessdata/";File tessDataDir = new File(tessDataDirPath);if (!tessDataDir.exists()) {tessDataDir.mkdirs();}AssetManager assetManager = getAssets();for (String fileName : tessDataFiles) {File outFile = new File(tessDataDirPath + fileName);if (outFile.exists()) continue;try (InputStream in = assetManager.open(fileName);OutputStream out = new FileOutputStream(outFile)) {byte[] buffer = new byte[1024];int read;while ((read = in.read(buffer)) != -1) {out.write(buffer, 0, read);}} catch (IOException e) {e.printStackTrace();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/96346.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/96346.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

八、Win/Linux/macOS全平台彻底卸载Docker的操作指南

八、Win/Linux/macOS全平台彻底卸载Docker的操作指南 系列文章目录 1. 卸载前准备工作(可忽略) 1.1 数据备份 1.2 停止Docker服务 2. 不同操作系统卸载步骤 2.1 Linux系统 2.2 macOS系统 2.3 Windows系统 3. 残留文件深度清理 3.1 Linux系统 3.2 macOS系统 3.3 Windows系统 4…

强化学习-CH9 策略梯度方法

强化学习-CH9 策略梯度方法 当策略被表示为函数时&#xff0c;通过优化目标函数可以得到最优策略。 这种方法称为策略梯度。策略梯度方法是基于策略的&#xff0c;而之前介绍的方法都是基于值的。其本质区别在于基于策略的方法是直接优化关于策略参数的目标函数。 9.1 策略表示…

[玩转GoLang] 5分钟整合Gin / Gorm框架入门

方法 / 步骤 一: Gin框架 1.1 : 环境 & 项目配置 1, GoLand创建项目 创建main.go package mainimport ("github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/", func(c *gin.Context) {c.JSON(200, gin.H{"message": "…

【项目复现】MOOSE-Chem 用于重新发现未见化学科学假说的大型语言模型

项目地址 ZonglinY/MOOSE-Chem: [ICLR 2025] --- ZonglinY/MOOSE-Chem: [ICLR 2025] https://github.com/ZonglinY/MOOSE-Chem git代码同步&#xff1a; 同步地址如下&#xff1a;QianPengfei1/MOOSE-Chem: [ICLR 2025] <MOOSE-Chem: Large Language Models for Rediscove…

深入解析TCP核心机制:连接管理、流量与拥塞控制

目录 一、三次握手与四次挥手&#xff1a;可靠连接的建立与终止 1. 三次握手 - 建立连接 为什么是三次&#xff1f; 2. 四次挥手 - 终止连接 为什么需要TIME_WAIT状态&#xff1f; 二、流量控制与滑动窗口&#xff1a;解决收发速度不匹配 核心机制&#xff1a;滑动窗口协…

如何在 DevOps 管道中实现 AI?

对于许多寻求提升效率、优化性能并缩短上市时间的组织而言,将人工智能 (AI) 集成到 DevOps 流水线中已成为一项战略举措。AI 与 DevOps 的结合,有时被称为 AIOps(面向 IT 运营的人工智能),正在重塑开发和运营团队构建、测试、发布和维护软件应用程序的方式。本文将引导您了…

【Agent】DeerFlow Planner:执行流程与架构设计(基于真实 Trace 深度解析)

本文档系统阐述 DeerFlow 中 Planner 的职责边界、端到端执行流程、关键节点设计、数据结构、容错与人审机制&#xff0c;以及与研究/编码子代理的协同方式。面向开发与运维读者&#xff0c;帮助快速理解与调优 Planner 相关链路。 时序图&#xff08;Sequence Diagram&#xf…

后端接口防止XSS漏洞攻击

有这样一个场景&#xff0c;首先构建一个docx文件并插入超链接&#xff08;恶意的链接&#xff09;&#xff0c;上传到文件服务器后获取对应的文件filekey。现在我们提供一个预览接口&#xff0c;通过filekey便可以预览&#xff0c;在根据filekey转html文档返回给页面的时候由于…

4.1Vue基本使用

1.使用Vue-引入 Vue 的本质,就是一个 JavaScript 的库: 刚开始我们不需要把它想象的非常复杂; 我们就把它理解成一个已经帮我们封装好的库; 在项目中可以引入并且使用它即可。 那么安装和使用 Vue 这个 JavaScript 库有哪些方式呢? 方式一:在页面中通过 CDN 的方式来引…

CAD绘图:杂项

一、样式标注管理器 新建CAD图纸的样式标注是定死的,需要手动去改变合适的大小 1)命令行中直接输入“D”,打开样式标注管理器 2)点击“修改”,可以改变其颜色,线条样式以及文字大小、颜色、字体等 3)若想添加字体: a)在网上下载需要的字体 b)右键Auto CAD图标(…

Git上有更新而本地无更新时的解决方案

问题分析 分支名称不匹配&#xff1a;你尝试推送到 main 分支&#xff0c;但你当前在 master 分支上远程仓库有新内容&#xff1a;远程仓库包含你本地没有的提交&#xff0c;需要先拉取 解决方案 方法1&#xff1a;继续使用 master 分支 # 1. 先拉取远程更改 git pull origin m…

用于骨盆骨折复位与固定自动术前手术规划的基于几何的端到端流水线|文献速递-最新医学人工智能文献

Title题目An End-to-End Geometry-Based Pipeline forAutomatic Preoperative Surgical Planning ofPelvic Fracture Reduction and Fixation用于骨盆骨折复位与固定自动术前手术规划的基于几何的端到端流水线01文献速递介绍骨盆骨折及其术前规划相关研究背景与本文方法 骨盆骨…

【导航】OS复习

【OS】操作系统概述-CSDN博客 【OS】PV-CSDN博客 【OS】进程与线程-CSDN博客 【OS】文件管理-CSDN博客 【OS】IO_检查用户io请求的合法性-CSDN博客

Google Nano-banana AI模型图像生成能力实证分析:基于47个案例的系统化技术验证

Google Nano-banana AI模型官方示例库&#xff08;Awesome-Nano-Banana&#x1f34c;-images&#xff09;&#xff0c;通过系统化分析47个技术案例&#xff0c;实证验证其在图像生成、编辑与转换任务中的核心能力。所有测试基于Apache 2.0开源许可的公开案例数据集&#xff0c;…

MySQL 多表操作与复杂查询:深入理解多表关系和高级查询

大家好&#xff01;今天我们要深入探讨 MySQL 中两个非常重要的主题——多表操作 和 复杂查询。一. 多表操作什么是多表操作&#xff1f;在实际应用中&#xff0c;数据通常分布在多个表中&#xff0c;需要通过多表操作来获取完整信息。比如&#xff0c;一个学生表和一个课程表之…

Java入门级教程7——eclipse新建Maven项目,创建和连接数据库,创建数据库表

目录 1.若没有Maven项目&#xff0c;可以选择新建 2.添加Maven依赖 3.数据库的创建 3.1 新建连接 --> 创建数据库 3.2 创建数据库表 4.连接数据库 1.若没有Maven项目&#xff0c;可以选择新建 步骤一&#xff1a;点击 File --> New --> Project 步骤二&#xf…

请求库-axios

Axios 是一个基于 Promise 的 HTTP 客户端库&#xff0c;用于浏览器和 Node.js 环境。它支持发送异步 HTTP 请求&#xff0c;并提供了简洁的 API 来处理请求和响应。1、安装axios因为axios是一个第三方库&#xff0c;所以在使用之前我们需要先安装第三方模块。安装 Axios 需通过…

电子烟的4种屏幕驱动集成语音方案介绍

目前电子烟在全球市场的表现非常不错&#xff0c;很多国产电子烟厂家都有非常不错的产品&#xff0c;而屏幕驱动方案是电子烟智能化的重要组成部分&#xff0c;今天就给大家带来电子烟的4种主流屏幕驱动方案(含2025年最新版方案)。​  方案一、LED显示方案语音播报集成方案 W…

无法加载 DLL“xxxxxxx.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。

(无法加载 DLL“xxxxxxx.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。) 这个错误&#xff1a; 无法加载 DLL“ZH_P2P_Libx64.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E) 意味着你的程序在运行时试图加载一个名为 xxxxxxx.dll 的动态链接库&#…

Flask/Django 生产部署:Gunicorn vs Nginx,Windows 与 Linux 实战指引

Flask/Django 生产部署&#xff1a;Gunicorn vs Nginx&#xff0c;Windows 与 Linux 实战指引 TL;DR Gunicorn&#xff1a;Python WSGI 应用服务器&#xff0c;运行 Flask/Django&#xff08;Linux 用&#xff09;。Nginx&#xff1a;反向代理/网关&#xff08;TLS、静态、限流…