【SpringBoot】整合百度文字识别

news2024/10/7 13:14:35

流程图

一、前期准备

1.1 打开百度智能云官网找到管理中心创建应用

全选文字识别

1.2 保存好AppId、API Key和Secret Key

1.3 找到通用场景文字识别,立即使用

1.4 根据自己需要,选择要开通的项目

二、代码编写

以通用文字识别(高精度版)为例

2.1 加依赖(pom.xml)

    <dependencies>

        <!-- 引入Spring Boot的web starter依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 引入Lombok依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- 引入Spring Boot的测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 百度人工智能依赖 -->
        <dependency>
            <groupId>com.baidu.aip</groupId>
            <artifactId>java-sdk</artifactId>
            <version>4.11.3</version>
        </dependency>

        <!-- okhttp -->
        <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.12.0</version>
        </dependency>

        <!-- 对象转换成json -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>

        <!-- thymeleaf模板引擎 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

2.2 编写yml文件

# 这是一个配置块,用于设置百度OCR服务的认证信息。
baidu:
  ocr: # OCR服务的配置项
    appId:  # 百度OCR服务的应用ID
    apiKey:  # 百度OCR服务的API密钥
    secretKey:  # 百度OCR服务的密钥

spring:
  thymeleaf:
    cache: false

2.3 工具类

package com.baiduocr.util;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * 这个类定义了全局的异常处理器。
 */
public class GlobalExceptionHandler {
    /**
     * 处理所有类型的异常。
     *
     * @param e 异常对象,捕获到的异常会作为参数传入。
     * @return 返回一个包含异常信息的ResponseEntity对象,状态码为500(内部服务器错误)。
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        // 构造并返回一个包含异常信息的ResponseEntity对象
        return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }

}
package com.baiduocr.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Map;

/**
 * JsonChange 类提供了将 JSON 字符串转换为 Map 对象的静态方法。
 */
public class JsonChange {

    /**
     * 将JSON字符串解析为Map对象。
     * @param jsonString 待转换的JSON字符串。
     * @return 返回一个包含JSON数据的Map对象。
     * @throws Exception 如果转换过程中发生错误,则抛出异常。
     */
    public static Map<Object, Object> json2map(String jsonString) throws Exception {
        // 创建 ObjectMapper 实例用于处理 JSON 字符串
        ObjectMapper mapper = new ObjectMapper();
        // 设置序列化选项,仅包含非空值
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 将 JSON 字符串解析为 Map 对象并返回
        return mapper.readValue(jsonString, Map.class);
    }

}

2.4 Service层

package com.baiduocr.service;

import okhttp3.*;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
public class OcrService {
    @Value("${baidu.ocr.appId}")
    private String appId;

    @Value("${baidu.ocr.apiKey}")
    private String apiKey;

    @Value("${baidu.ocr.secretKey}")
    private String secretKey;

    // accessToken
    private String accessToken;

    // HTTP客户端
    static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();

    /**
     * 调用百度高精度版OCR接口进行文字识别。
     *
     * @param imageBytes 待识别的图片字节数组
     * @return OCR识别结果
     * @throws IOException IO异常
     */
    public String performOcr(byte[] imageBytes) throws IOException {
        // 设置请求体
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "detect_direction=false&paragraph=false&probability=true");
        // 创建请求
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/rest/2.0/ocr/v1/accurate?access_token=" + accessToken)
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "application/json")
                .build();
        // 发送请求并获取响应
        Response response = HTTP_CLIENT.newCall(request).execute();
        // 返回响应内容
        return response.body().string();
    }

    /**
     * 获取百度的Access Token。
     *
     * @return 百度的Access Token
     * @throws IOException IO异常
     */
    private String getAccessToken() throws IOException {
        // 设置请求体
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + apiKey
                + "&client_secret=" + secretKey);
        // 创建请求
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        // 发送请求并获取响应
        Response response = HTTP_CLIENT.newCall(request).execute();
        // 解析响应内容获取Access Token
        return new JSONObject(response.body().string()).getString("access_token");
    }

}

2.5 eneity层

package com.baiduocr.entity;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * BaiduOcrProperties类用于配置百度OCR服务的相关属性。
 * 该类通过@ConfigurationProperties注解与配置文件中的baidu.ocr前缀绑定,
 * 使得我们可以从配置文件中动态读取appId, apiKey和secretKey等属性值。
 *
 * @Configuration 表示这是一个配置类,可以被Spring作为配置源。
 * @ConfigurationProperties(prefix = "baidu.ocr") 将该类的属性与配置文件中的baidu.ocr前缀绑定。
 * @Data 提供了基于Lombok的自动getter/setter等代码生成,方便属性的访问和设置。
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "baidu.ocr")
public class BaiduOcrProperties {
    // 百度OCR的App ID
    private String appId;
    // 百度OCR的API Key
    private String apiKey;
    // 百度OCR的Secret Key
    private String secretKey;
}

2.6 控制器

package com.baiduocr.controller;

import com.baidu.aip.ocr.AipOcr;
import com.baiduocr.entity.BaiduOcrProperties;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import okhttp3.*;

/**
 * OcrController类负责处理OCR相关的请求。
 * 它利用百度OCR服务对上传的文件或文本进行识别,并返回识别结果。
 */

@Controller
public class OcrController {
    // 创建一个日志记录器
    private static final Logger logger = LoggerFactory.getLogger(OcrController.class);
    // 注入BaiduOcrProperties对象
    private final BaiduOcrProperties baiduOcrProperties;
    // 创建一个OkHttpClient对象
    static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();

    // 构造函数,注入BaiduOcrProperties对象
    @Autowired
    public OcrController(BaiduOcrProperties baiduOcrProperties) {
        this.baiduOcrProperties = baiduOcrProperties;
    }

    @RequestMapping(value = {"/", "/ocr"})
    public String index() {
        return "ocr";
    }
    /**
     * 处理OCR识别请求。
     *
     * @param file 用户上传的文件,将进行OCR识别。
     * @param model Spring模型,用于在识别后向视图传递数据。
     * @return 视图名称,根据识别结果决定是显示结果还是错误页面。
     */
    @RequestMapping(value = "/doOcr")
    public String ocr(MultipartFile file, Model model) {
        try {
            List<String> ocrResult = performOcr(file); // 执行OCR识别
            model.addAttribute("ocrResult", ocrResult); // 将识别结果添加到模型中
        } catch (Exception e) {
            logger.error("OCR识别失败", e);
            return "error"; // 识别失败,返回错误页面
        }
        return "ocr_result"; // 识别成功,返回结果页面
    }

    /**
     * 执行OCR识别操作。
     *
     * @param file 需要进行OCR识别的文件。
     * @return 识别到的文本列表。
     * @throws Exception 如果识别过程中出现错误,则抛出异常。
     */
    private List<String> performOcr(MultipartFile file) throws Exception {
        logger.info("Performing OCR on file: {}", file.getOriginalFilename()); // 记录日志,表示开始进行OCR识别

        AipOcr client = new AipOcr(baiduOcrProperties.getAppId(), baiduOcrProperties.getApiKey(), baiduOcrProperties.getSecretKey()); // 创建百度OCR客户端

        // 获取Access Token
        String accessToken = getAccessToken();

        // 在开发环境中记录Access Token(请在生产环境中移除或注释掉此行)
        //logger.debug("Access Token: {}", accessToken);

        HashMap<String, String> options = new HashMap<>(); // 设置OCR识别的选项
        options.put("language_type", "CHN_ENG");
        options.put("detect_direction", "true");
        options.put("detect_language", "true");
        options.put("probability", "true");

        byte[] buf = file.getBytes(); // 从文件中读取内容
        JSONObject res = client.basicAccurateGeneral(buf, options);  // 使用高精度接口进行通用文字识别

        List<String> wordsList = new ArrayList<>(); // 存储识别出的文本
        for (Object obj : res.getJSONArray("words_result")) { // 遍历识别结果,提取文本
            JSONObject jsonObj = (JSONObject) obj;
            wordsList.add(jsonObj.getString("words"));
        }
        return wordsList;
    }

    /**
     * 从百度OCR服务获取Access Token。
     *
     * @return Access Token,用于身份验证。
     * @throws IOException 如果在获取Access Token过程中出现IO错误。
     */
    private String getAccessToken() throws IOException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + baiduOcrProperties.getApiKey()
                + "&client_secret=" + baiduOcrProperties.getSecretKey());
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute(); // 发送请求,获取响应
        return new JSONObject(response.body().string()).getString("access_token"); // 从响应中提取Access Token
    }

    /**
     * 捕获并处理所有异常。
     *
     * @param e 异常对象。
     * @return 响应实体,包含异常信息。
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); // 返回内部服务器错误信息
    }


}

2.6 前端页面(thymeleaf)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>OCR识别</title>
</head>
<body>

<h1>上传图片进行OCR识别</h1>
<form th:action="@{/doOcr}" method="post" enctype="multipart/form-data">
    <input type="file" name="file" accept="image/*">
    <button type="submit">上传并识别</button>
</form>

</body>
<style>
    body {
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        background-color: #f8f9fa;
    }
    h1 {
        color: #343a40;
        margin-top: 20px;
    }
    form {
        margin: 20px 0;
        padding: 20px;
        border: 1px solid #dee2e6;
        border-radius: 5px;
        background-color: #fff;
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    }
    input[type="file"] {
        margin-bottom: 10px;
    }
    button {
        background-color: #007bff;
        color: white;
        padding: 10px 20px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
    }
    button:hover {
        background-color: #0056b3;
    }
</style>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>OCR结果</title>
</head>
<body>

<h1>OCR识别结果</h1>
<div th:if="${ocrResult != null}">
    <ul>
        <li th:each="word : ${ocrResult}" th:text="${word}"></li>
    </ul>
</div>
<a href="/">返回首页</a>

</body>
<style>
    body {
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        background-color: #f8f9fa;
    }
    h1 {
        color: #343a40;
        margin-top: 20px;
    }
    div {
        margin: 20px 0;
        padding: 20px;
        border: 1px solid #dee2e6;
        border-radius: 5px;
        background-color: #fff;
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        width: 80%;
        max-width: 800px;
    }
    ul {
        list-style-type: none;
        padding: 0;
    }
    li {
        padding: 5px 0;
        border-bottom: 1px solid #dee2e6;
    }
    a {
        margin-top: 20px;
        color: #007bff;
        text-decoration: none;
    }
    a:hover {
        text-decoration: underline;
    }
</style>
</html>

三、效果展示

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

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

相关文章

AI图书推荐:用OpenAI API 开发AI应用详细指南

随着人工智能不断重塑行业&#xff0c;OpenAI 处于人工智能研究的前沿&#xff0c;了解如何创建聊天机器人、虚拟助手、内容生成器和生产力增强器等创新应用程序是一个游戏规则改变者。本书《用OpenAI API 开发AI应用详细指南》&#xff08;OpenAI API Cookbook&#xff09;&am…

Docker访问文件权限受限问题解决

问题描述 运行项目的docker环境&#xff0c;新添加了一个数据集&#xff0c;但是数据集的访问权限受限&#xff08;Permission dinied&#xff09;&#xff0c;运行的命令如图所示 问题解决 chmod 777 xxx YYDS&#xff01;&#xff01;&#xff01;但是单纯直接运行会因为权限…

LLaVA UHD:一种可感知任意纵横比和高分辨率图像的LMM

LLaVA-UHD: an LMM Perceiving Any Aspect Ratio and High-Resolution Images (2024-03-18) 文章概要作者: Ruyi Xu; Yuan Yao; Zonghao Guo; Junbo Cui; Zanlin Ni; Chunjiang Ge; Tat-Seng Chua; Zhiyuan Liu; Maosong Sun; Gao Huang期刊: arXiv 预印版DOI: 10.48550/arXiv…

Python 全栈体系【四阶】(五十二)

第五章 深度学习 十二、光学字符识别&#xff08;OCR&#xff09; 2. 文字检测技术 2.1 CTPN&#xff08;2016&#xff09; 2.1.1 概述 CTPN全称Detecting Text in Natural Image with Connectionist Text Proposal Network&#xff08;基于连接文本提议网络的自然图像文本…

uniappx 安卓保活(多种技术;UTS版) Ba-KeepAlive-U

简介&#xff08;下载地址&#xff09; Ba-KeepAlive-U 是一款android原生保活插件&#xff0c;UTS版本&#xff08;同时支持uniapp和uniappx&#xff09;&#xff0c;支持市面上大部分机型&#xff0c;Android4.4到Android14&#xff08;**注意&#xff1a;**不保证支持所有机…

Go-zero(api部分)

目录 api的语法&#xff1a; type&#xff1a;用于定义请求/响应体 service&#xff1a;定义HTTP服务 server&#xff1a;控制生成HTTP服务时候的meta信息 根据api文档生成最小HTTP服务 目录结构 api响应封装 api的语法&#xff1a; 首先定义一个api文档 type&#xff…

电磁兼容(EMC):时钟电路PCB设计

目录 1. 布局 2. 布线 时钟电路做为产品内部的强辐射源&#xff0c;在设计阶段已经选用展频或者分频方案后&#xff0c;见另外接下来就需要对PCB的耦合路径进行规划设计。时钟电路具体的PCB设计具体要求如下&#xff1a; 1. 布局 结构干涉&#xff1a;时钟电路的晶振和法拉电…

K8s之ku-be admin部署安装

目录 一、环境配置 1、机器部署 2、部署大致流程 二、实验环境配置 1、所有节点关闭防火墙核心防护以及关闭swap交换 2、所有节点安装docker 3、所有节点安装kubeadm&#xff0c;kubelet和kubectl 4、部署K8s集群 5、设定kubectl 6、所有节点部署网络插件flannel 7、…

身份证实名认证API接口对接流程

该接口传入姓名、身份证号&#xff0c;核验二要素是否一致&#xff0c;返回生日、性别、籍贯等信息。 应用于各类线上平台和服务的身份认证验证&#xff0c;以保障用户信息的真实性和交易的安全性。 首先找到提供接口的平台供应商&#xff0c;注册账号后获取免费套餐&#xff…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-16讲 EPIT定时器

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

Php composer 基础教程

一、什么是Composer&#xff1f; Composer 是 PHP 中的依赖管理工具。它允许声明项目所依赖的库&#xff0c;并且它将为您管理&#xff08;安装/更新&#xff09;它们。 二、如何安装&#xff1f; Linux 系统和 MacOS 系统 直接下载最新稳定版&#xff1a; 然后执行下列命令&…

nss刷题(关于ssti)

1、[HNCTF 2022 WEEK2]ez_SSTI 首先是注入${7*7}没有回显出49的情况&#xff0c;再次注入{{7*7}}如果还是没有回显49就代表这里没有模板注入&#xff1b;如果注入{{7&#xff0a;7}}回显了49代表执行成功&#xff0c;继续往下走注入{{7*7}}&#xff0c;如果执行成功回显7777777…

图生代码,从Hello Onion 代码开始

从Hello Onion 代码开始 1&#xff0c;从代码开始 原生语言采用java 作为载体。通过注解方式实现“UI可视化元素"与代码bean之间的映射. 转换示例 2&#xff0c;运行解析原理 在执行JAVA代码期间&#xff0c;通过读取注解信息&#xff0c;转换为前端的JSON交由前端JS框…

【linux性能分析】perf分析CPU占用详情

文章目录 1. 如何使用perf工具1.1 perf安装1.2 首次使用perf报错1.3 添加测试程序1.4 编译并执行指令生成perf.data文件1.5 添加-g选项能查看call graph调用信息1.6 查看perf.data1.7 perf工作流1.8 sudo perf record -F 99 -p 2512 -g -- sleep 60 2. 如何生成火焰图2.1 安装火…

技术前沿 |【自回归视觉模型ImageGPT】

自回归视觉模型ImageGPT 引言一、ImageGPT的基本原理与创新之处二、ImageGPT在图像生成、理解等视觉任务上的应用三、ImageGPT对后续视觉Transformer模型发展的影响四、ImageGPT的深入应用 引言 在人工智能的飞速发展中&#xff0c;视觉模型作为其中一个重要的分支&#xff0c…

Qt运行时,如何设置第一个聚焦的控件

问题&#xff1a;Qt第一个聚焦的控件&#xff0c;如何自行设置&#xff1f; 尝试&#xff1a; 1.在代码中设置 lineEdit->setFocus() 。无效&#xff01; 2.Qt Designer–打开form1.ui–菜单栏下一行–Edit Tab Order–按顺序点击–菜单栏下一行–Edit Widgets–退出。无效…

JDBC、datasource、数据库驱动、持久层框架之间的区别

1、jdbc Java Database Connectivity&#xff08;JDBC&#xff09;是Java平台下的一个标准API&#xff0c;它定义了一组用于连接各种数据库系统、执行SQL语句和处理结果集的接口和类。使用JDBC API&#xff0c;开发人员可以编写能够访问不同数据库系统的应用程序&#xff0c;而…

react组件传参 父传子可以传字符串,布尔值,数组,对象,jsx,

在react中&#xff0c;父传子组件 props的灵活性是很强大的&#xff0c;可以传字符串&#xff0c;布尔值&#xff0c;数组&#xff0c;对象&#xff0c;jsx&#xff0c; function Son(props) {console.log(props,"props的值")return(<div>这是儿子组件 {props.…

论文精读-SRFormer Permuted Self-Attention for Single Image Super-Resolution

论文精读-SRFormer: Permuted Self-Attention for Single Image Super-Resolution SRFormer:用于单图像超分辨率的排列自注意 Params&#xff1a;853K&#xff0c;MACs&#xff1a;236G 优点&#xff1a; 1、参考SwinIR的RSTB提出了新的网络块结构PAB&#xff08;排列自注意力…

非授权人员进入报警系统

非授权人员进入报警系统基于智能视频分析技术和深度学习技术&#xff0c;非授权人员进入报警系统通过现场已经装好的监控摄像头针对人体进行精准检测&#xff0c;并根据设置的禁入区范围进行判断。通过图像处理和人体识别算法&#xff0c;非授权人员进入报警系统可以在实时监测…