Ocr之TesseractOcr的安装及使用

目录

一、安装环境

二、安装内容

三、安装过程及识别测试

1. 安装过程
2. 程序编写

总结

1. 安装复杂度较低
2. 国外开源Ocr
3. 可设置识别参数
4. 工具类

一、 系统环境windows 10

linux环境也可安装, 可借鉴此篇文章>> |

二、安装内容

Tesseract exe 程序安装
exe程序下载地址, 可选择版本安装>> |

# 我们这里安装的版本是
tesseract-ocr-w64-setup-5.3.1.20230401.exe

三、安装过程及识别测试

1. 安装过程
  • 安装后的目录结构
    默认安装在C盘。可选择路径。傻瓜式安装就可以
    在这里插入图片描述
  • 添加环境变量 TESSDATA_PREFIX=<安装的tessoract-ocr.exe后文件夹根路径>/tessdata
    在这里插入图片描述
2. 程序编写
  • 使用Tesseract进行识别程序的编写
    目前使用TesseractOcr已经更换为 PaddleOcr 了。源于TesseractOcr对背景模糊的图片识别率不高,使用PaddleOcr后识别率有明显提高。
    不过使用PaddleOcr识别过程会将图片进行预处理(图片放大和模糊处理再使用paddleocr识别效果更佳:后期会做记录并将链接加到此处)

  • 使用java程序进行识别需要引用 mvn 第三方依赖

    <!--ocr图像识别-->
     <dependency>
         <groupId>net.sourceforge.tess4j</groupId>
         <artifactId>tess4j</artifactId>
         <version>5.3.0</version>
     </dependency>
    
  • 单元测试用例+执行结果
    在这里插入图片描述
    下方代码中对上方图片进行识别(图片名称:new33.jpg)

    @Test
    public void readImageByOcr() throws TesseractException {
        String imgSrc = "C:\\...\\changepic\\new33.jpg";
        File imgFile = new File(imgSrc);
        //创建tesseract对象
        Tesseract tes = new Tesseract();
        //语言包位置  根据实际环境修改替换
        tes.setDatapath("E:\\...\\Tesseract-OCR\\tessdata");
        //配置使用的语言  中文
        tes.setLanguage("eng");
        String imgText = tes.doOCR(imgFile);
        System.out.println("解析结果:" + imgText);
    }
    

    执行后
    在这里插入图片描述

  • 业务代码示例
    结合业务代码使用TesseractOcr。TesseractOcr使用时可传入不通参数。如language, variable等。
    tessedit_char_whitelist:设置白名单。下方demo限制内容为只能识别数字和字母

    /**
      * ocr识别
      * @param img
      * @param dataPath
      * @param replacedEmp 是否替换回车和空格为空, true:替换, false, 不替换(含回车和空格符)
      * @param dpi 分辨率, 默认 96
      * @param charNoLimit 识别空格: true, 不识别空格: false
      * @return
      * @throws TesseractException
      */
     private static String doOcrImpl(BufferedImage img, String dataPath, boolean replacedEmp, String dpi, boolean charNoLimit) throws TesseractException {
         // 初始化 OCR 引擎
         Tesseract tesseract = new Tesseract();
         File tessDataFolder = LoadLibs.extractTessResources("tessdata");
         tesseract.setDatapath(tessDataFolder.getAbsolutePath());
         //语言包位置  根据实际环境修改替换
         tesseract.setDatapath(dataPath);
         //配置使用的语言  中文
         tesseract.setLanguage("eng");
         if(!charNoLimit) {
             //限制只识别数字字母
             tesseract.setVariable("tessedit_char_whitelist", "0123456789CDFGMRTX");
         }
         //设置分辨率
         tesseract.setVariable("user_defined_dpi", dpi);
         String result = tesseract.doOCR(img);
         if(replacedEmp) {
             // 文字识别-过滤空白、换行符
             result = result.replace(StrUtil.SPACE, StrUtil.EMPTY).replace(StrUtil.LF, StrUtil.EMPTY);
         }
         return result;
     }
    

总结

  1. 安装复杂度较低。
    相比于paddleocr的安装要简单的多(需要安装python环境及下载paddleocr相关内容)。paddleocr安装借鉴 gitee paddleocr开源代码>> |
  2. 属于国外开源Ocr。
  3. 可设置识别参数。可设置变量与识别语言。
  4. 使用Ocr时用到的工具类。可自行测试
package util;

import cn.hutool.core.util.StrUtil;
import common.aspect.core.StringUtils;
import common.exception.CustomException;
import PO.RecognizeTemplate;
import service.PrintDcmOcrRecognizeService;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import net.sourceforge.tess4j.util.LoadLibs;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.beans.factory.annotation.Value;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RasterFormatException;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class ReadTextFromFileRegion {
    /**
     * @Description: ocr按区域识别文件
     **/
    public static String doRecognize(File file, Rectangle rectangle, String dataPath, String formateName, String dpi)
            throws Exception {
        if (!file.exists()) {
            throw new CustomException(0, "待识别文件不存在");
        }
        // OCR 文字识别
        return doOcr(createImg(file, rectangle, formateName), dataPath, dpi);
    }
	  /**
	   * file: 图片文件
	   * rectangle: 图片中需要识别的区域。如new Rectangle(x, y, w, h), 坐标及宽高
	   * dataPath: tessData的路径(文章开头已添加到环境变量,也可传入)
	   * formateName: file文件的格式。如 JPG, PNG, DICOM等, 
	   * dpi: tesseractOcr识别时传入的参数。如:tesseract.setVariable("user_defined_dpi", dpi);
	   */
    public static String doRecognizeOrcOriginResult(File file, Rectangle rectangle, String dataPath, String formateName, String dpi)
            throws Exception {
        if (!file.exists()) {
            throw new CustomException(0, "待识别文件不存在");
        }
        // OCR 文字识别
        return doOcrImpl(createImg(file, rectangle, formateName), dataPath, false, dpi, true);
    }
	/**
	 * 截取的图像缓冲区
	 */
    private static BufferedImage createImg(File file, Rectangle rectangle, String formateName) throws Exception {
        BufferedImage img = readFile(file, rectangle, formateName);
        if(img == null) {
            log.warn("读取图像异常: img == null");
            throw new Exception("文件读取异常, 创建img为空.");
        }
        return img;
    }
    
    /**
     * @Description: 把文件转为BufferedImage对象,并截取指定区域
     **/
    private static BufferedImage readFile(File file, Rectangle region, String formateName) throws IOException {
        ImageInputStream iis = null;
        ImageReader reader = null;
        try {
            // 创建 ImageInputStream 对象
            iis = ImageIO.createImageInputStream(file);
            // 获取 指定 文件的 ImageReader 实例
            reader = ImageIO.getImageReadersByFormatName(formateName).next();
            // 设置解码器
            reader.setInput(iis);
            // 如果需要截取图像,获取完整的BufferedImage,然后截取指定区域
            BufferedImage image = reader.read(0);
            BufferedImage subImage = null;
            try{
                subImage = image.getSubimage(region.x, region.y, region.width, region.height);
            }catch (RasterFormatException e) {
                log.warn("截取图像异常: 识别区域超出边界. err.msg: {}", e.toString());
                return subImage;
            }
            // 释放完整的BufferedImage
            image.flush();
            return subImage;
        } finally {
            // 关闭资源
            if (reader != null) {
                reader.dispose();
            }
            if (iis != null) {
                iis.close();
            }
        }
    }

    /**
     * @Description: ocr按区域识别pdf文件
     **/
    public static String doPdfRecognize(File pdfFile, String dataPath) throws Exception {
        BufferedImage img = readPdfToImage(pdfFile);
        // 按自定义区域截取图像
        BufferedImage subImage = img.getSubimage(460, 170, 320, 100);
        // OCR 文字识别
        return doOcr(subImage, dataPath, "120");
    }

    /**
     * @Description: 把pdf转为图像,renderImageWithDPI方法的第二个参数dpi影响图像分辨率,经测试dpi为300,生成2k分辨率的图像
     **/
    private static BufferedImage readPdfToImage(File pdfFile) throws IOException {
        try (PDDocument document = PDDocument.load(pdfFile)) {
            PDFRenderer renderer = new PDFRenderer(document);
            return renderer.renderImageWithDPI(0, 300);
        }
    }

    /**
     * @Description: 使用Tesseract进行ocr识别
     **/
    private static String doOcr(BufferedImage img, String dataPath, String dpi) throws TesseractException {
        return doOcrImpl(img, dataPath, true, dpi, false);
    }

    /**
     * ocr识别
     * @param img
	   * dataPath: tessData的路径(文章开头已添加到环境变量,也可传入)
     * @param replacedEmp 是否替换回车和空格为空, true:替换, false, 不替换(含回车和空格符)
     * @param dpi 分辨率, 默认 96
     * @param charNoLimit 识别空格: true, 不识别空格: false
     * @return
     * @throws TesseractException
     */
    private static String doOcrImpl(BufferedImage img, String dataPath, boolean replacedEmp, String dpi, boolean charNoLimit) throws TesseractException {
        // 初始化 OCR 引擎
        Tesseract tesseract = new Tesseract();
        File tessDataFolder = LoadLibs.extractTessResources("tessdata");
        tesseract.setDatapath(tessDataFolder.getAbsolutePath());
        //语言包位置  根据实际环境修改替换
        tesseract.setDatapath(dataPath);
        //配置使用的语言  中文
        tesseract.setLanguage("eng");
        if(!charNoLimit) {
            //限制只识别数字字母
            tesseract.setVariable("tessedit_char_whitelist", "0123456789CDFGMRTX");
        }
        //设置分辨率
        tesseract.setVariable("user_defined_dpi", dpi);
        String result = tesseract.doOCR(img);
        if(replacedEmp) {
            // 文字识别-过滤空白、换行符
            result = result.replace(StrUtil.SPACE, StrUtil.EMPTY).replace(StrUtil.LF, StrUtil.EMPTY);
        }
        return result;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CVE-2022-25578 漏洞复现

CVE-2022-25578 路由/admin/admin.php是后台&#xff0c;登录账号和密码默认是admin、tao&#xff0c;选择文件管理。 是否还记得文件上传中的.htaccess配置文件绕过发&#xff0c;在这个文件中加入一句AddType application/x-httpd-php .jpg&#xff0c;将所有jpg文件当作php…

位运算+leetcode(1)

基础 1.基础知识 以下都是针对数字的二进制进行操作 >> 右移操作符<< 左移操作符~ 取反操作符 & 有0就是0&#xff0c;全一才一 | 有一才一 &#xff0c;全0才0^ 相同为0&#xff0c;相异为1 异或( ^ )运算的规律 a ^ 0 a a ^ a 0a ^ b ^ c a ^ (b …

【Java程序设计】【C00252】基于Springboot的实习管理系统(有论文)

基于Springboot的实习管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的实习管理系统 本系统分为前台功能模块、管理员功能模块、教师功能模块、学生功能模块以及实习单位功能模块。 前台功能模块&#xf…

hook函数——useMemo

useMemo 1.useMemo定义 useMemo 是一个 React Hook&#xff0c;它在每次重新渲染的时候能够缓存计算的结果。 const 变量名 useMemo(calculateValue, dependencies) calculateValue&#xff1a;要缓存计算值的函数。它应该是一个没有任何参数的纯函数&#xff0c;并且可以返…

【程序设计竞赛】竞赛中的细节优化

必须强调下&#xff0c;以下的任意一种优化&#xff0c;都应该是在本身采用的算法没有任何问题情况下的“锦上添花”&#xff0c;而不是“雪中送炭”。 如果下面的说法存在误导&#xff0c;请专业大佬评论指正 读写优化 C读写优化——解除流绑定 在ACM里&#xff0c;经常出现…

网络协议与攻击模拟_16HTTP协议

1、HTTP协议结构 2、在Windows server去搭建web扫描器 3、分析HTTP协议流量 一、HTTP协议 1、概念 HTTP&#xff08;超文本传输协议&#xff09;用于在万维网服务器上传输超文本&#xff08;HTML&#xff09;到本地浏览器的传输协议 基于TCP/IP(HTML文件、图片、查询结构等&…

Python实现桶排序

如果在对给定的一些数据进行排序的时候&#xff0c;给定的被排序的数据存在某种特征的时候&#xff0c;我们就可以利用这种特征&#xff0c;设计出相应的排序算法&#xff0c;以达到加快排序速度的目的。 而假设要排序的数组的每个元素的取值在一个区间0,1之间随机分布&#x…

C#,卢卡斯数(Lucas Number)的算法与源代码

1 卢卡斯数&#xff08;Lucas Number&#xff09; 卢卡斯数&#xff08;Lucas Number&#xff09;是一个以数学家爱德华卢卡斯&#xff08;Edward Lucas&#xff09;命名的整数序列。爱德华卢卡斯既研究了这个数列&#xff0c;也研究了有密切关系的斐波那契数&#xff08;两个…

【开源】基于JAVA+Vue+SpringBoot的二手车交易系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手车档案管理模块2.3 车辆预约管理模块2.4 车辆预定管理模块2.5 车辆留言板管理模块2.6 车辆资讯管理模块 三、系统设计3.1 E-R图设计3.2 可行性分析3.2.1 技术可行性分析3.2.2 操作可行性3.2.3 经济…

如何升级至ChatGPT Plus:快速指南,ChatGPT的秘密武器GPT4.0是什么?

提到 ChatGPT。想必大家都有所耳闻。自从 2022 年上线以来&#xff0c;就受到国内外狂热的追捧和青睐&#xff0c;上线2个月&#xff0c;月活突破1个亿&#xff01;&#xff01;&#xff01; 而且还在持续上涨中。因为有很多人都在使用 ChatGPT 。无论是各大头条、抖音等 App、…

一些AI工具的初探和使用

0. 前言 目前我自己对于AI的应用还不成熟&#xff0c;先记录一下常用的AI工具&#xff0c;后续再进行探索。 目前AI发展的速度已经超出想象了。可能最开始我对ai的应用 还停留在回答问题以及自己领域的可以生成cursor,还有阿里家通义灵码。都还是程序员的范畴。 然后对于文字…

【Java程序设计】【C00264】基于Springboot的原创歌曲分享平台(有论文)

基于Springboot的原创歌曲分享平台&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的原创歌曲分享平台 本系统分为平台功能模块、管理员功能模块以及用户功能模块。 平台功能模块&#xff1a;在平台首页可以查看首…

蓝牙BLE学习-蓝牙广播

1.概念 什么叫做广播&#xff0c;顾名思义就像广场上的大喇叭一样&#xff0c;不停的向外传输着信号。不同的是&#xff0c;大喇叭传输的是音频信号&#xff0c;而蓝牙传输的是射频信号。 BLE使用的是无线电波传递信息&#xff0c;就是将数据编码&#xff0c;调制到射频信号中发…

【Java程序设计】【C00269】基于Springboot的漫画网站(有论文)

基于Springboot的漫画网站&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的漫画网站 本系统分为系统功能模块、管理员功能模块、以及用户功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页、漫画投稿、…

ctfshow-文件上传(web151-web161)

目录 web151 web152 web153 web154 web155 web156 web157 web158 web159 web160 web161 web151 提示前台验证不可靠 那限制条件估计就是在前端设置的 上传php小马后 弹出了窗口说不支持的格式 查看源码 这一条很关键 这种不懂直接ai搜 意思就是限制了上传类型 允许…

HarmonyOS 鸿蒙 ArkTS ArkUI 页面之间切换转换动画设置

第一步&#xff1a;导入 import promptAction from ohos.promptAction 第二步&#xff1a;在build下方写入 pageTransition(){PageTransitionEnter({ duration: 1200 }).slide(SlideEffect.Right)PageTransitionExit({ delay: 100 }).translate({ x: 100.0, y: 100.0 }).opac…

面试:大数据和深度学习之间的关系是什么?

大数据与深度学习之间存在着紧密的相互关系&#xff0c;它们在当今技术发展中相辅相成。 大数据的定义与特点:大数据指的是规模(数据量)、多样性(数据类型)和速度(数据生成及处理速度)都超出了传统数据处理软件和硬件能力范围的数据集。它具有四个主要特点&#xff0c;通常被称…

【十五】【C++】list的简单实现

list 的迭代器解引用探究 /*list的迭代器解引用探究*/ #if 1 #include <list> #include <vector> #include <iostream> #include <algorithm> using namespace std;class Date {private:int _year;int _month;int _day;public:Date(): _year(2024), _m…

数据结构——6.3 图的遍历

6.3 图的遍历 一、概念 图的广度优先遍历 树的广度优先遍历&#xff08;层序遍历&#xff09;&#xff1a;不存在“回路”&#xff0c;搜索相邻的结点时&#xff0c;不可能搜到已经访问过的结点&#xff1a; 若树非空&#xff0c;则根节点入队 若队列非空&#xff0c;队头元素…

CTFSHOW web 89-100

这边建议去我的gitbook或者github看观感更好(图片更完整) github:https://github.com/kakaandhanhan/cybersecurity_knowledge_book-gitbook.22kaka.fun gitbook:http://22kaka.fun 🏈 CTFSHOW PHP特性 (1)WEB 89 ①代码解释 <?php/* # -*- coding: utf-8 -*- # @…