Springboot整合TextIn通用文字识别服务教程与心得

145 阅读5分钟

Springboot整合TextIn通用文字识别服务教程与心得

合合信息通用文字识别服务说明

合合信息是一家人工智能及大数据科技企业,基于自主研发的领先的智能文字识别及商业大数据核心技术,为全球C端用户和多元行业B端客户提供数字化、智能化的产品及服务。

合合信息通用文字识别服务:通过前沿的深度学习技术,对各种表格,图片,文档、证件、面单等多种通用场景进行快速、精准的检测和识别,支持简体中文/繁体中文/英文/数字/西欧主流语言/东欧主流语言等共52种语言,同时支持印刷体、手写体、倾斜、折叠、旋转等。

本文通过创建springboot web项目模拟实际工程项目,在工程中调用合合信息通用文字识别接口的方式,演示合合信息通用文字识别接口的使用。

整体流程

一、创建Springboot工程

在idea中新建一个maven项目,导入springboot相关依赖。

目录结构:

image-20240303171639864.png

在pom文件中引入相关依赖:

image-20240303220316236.png

二、开通合合信息服务,编写配置文件

合合信息通用文字识别开通:www.textin.com/market/deta…

开通后在控制台获取appId 和 secretCode:

image-20240303172224254.png

后续发送通用文字识别请求需要带上上面的appId和secretCode做认证,可以把这两个写在配置文件中,application.yml如下所示:

# 合合信息配置
hehe:
  appId: your_app_id
  secretCode: your_secret_code
  # 配置通用文字识别接口url
  ocr:
    serviceAddress: https://api.textin.com/ai/service/v2/recognize

# 日志
logging:
  config: classpath:logback-spring.xml
 
# 文件上传大小限制为10Mb
spring:
  servlet:
    multipart:
      max-file-size: 10MB

logback-spring.xml如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!-- 控制台输出配置 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 文件输出配置 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>app.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/app-%d{yyyy-MM-dd}.%i.log</fileNamePattern>

            <maxHistory>30</maxHistory>
            <totalSizeCap>1GB</totalSizeCap>

            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>

    <!--    默认对所有都生效-->
    <!--    <root level="INFO">-->
    <!--        <appender-ref ref="CONSOLE" />-->
    <!--    </root>-->

    <!--    指定com.gzx包下日志输出在文件和控制台上,文件和控制台配置如上所示 -->
    <logger name="com.gzx" level="DEBUG">
        <appender-ref ref="FILE" />
        <appender-ref ref="CONSOLE" />
    </logger>

</configuration>

编写启动类:

@SpringBootApplication
public class HeheDemoApplication {
    public static void main(String[] args) {
        try {
            SpringApplication.run(HeheDemoApplication.class, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // springboot自带的发送请求类
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

三、编写发送请求的通用工具类

在com.gzx包下创建子包和工具类utils.HttpUtil,用于封装发送http请求:

HttpUtil代码:

@Component
@Slf4j
public class HttpUtil {

    @Resource
    RestTemplate restTemplate;

    /**
     * 发送post请求,请求体格式为json
     * @param url 请求url
     * @param headers 请求头
     * @param body 请求体
     * @param responseClass 响应体类型
     * @return 
     * @throws RestClientException
     */
    public <T> ResponseEntity<T> sendJsonPost(String url, HttpHeaders headers, Object body, Class<T> responseClass) throws RestClientException {
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Object> requestEntity = new HttpEntity<>(body, headers);

        return restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseClass);
    }
}

四、编写调用接口的服务类

在com.gzx包下创建service子包,在service包下编写业务类接口和其实现类:

OcrService代码:

public interface OcrService {
    
    String getTextFromPic(MultipartFile picFile) throws IOException;
    
}

HhxxOCRService代码:

@Service
@Slf4j
@PropertySource("classpath:application.yml")
public class HhxxOCRService implements OCRService {


    @Value("${hehe.appId}")
    private String appId;

    @Value("${hehe.secretCode}")
    private String secretCode;

    @Value("${hehe.ocr.serviceAddress}")
    private String serviceUrl;

    @Resource
    HttpUtil httpUtil;

    @Override
    public String getTextFromPic(MultipartFile picFile) throws IOException, RestClientException {
        HttpHeaders headers = new HttpHeaders();
        headers.add("x-ti-app-id", appId);
        headers.add("x-ti-secret-code", secretCode);
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        // 发送POST请求 到ocr接口,参数为springmvc接口接收到的图片对应的字节数组
        ResponseEntity<String> response = httpUtil.sendJsonPost(serviceUrl, headers, picFile.getBytes(), String.class);

        return getCompleteString(response.getBody());
    }
    
	/**
     * 作用是将返回的识别结果按行进行拼接
     * @param responseBody 响应体对象
     * @return 识别的完整文本
     */
    private String getCompleteString(String responseBody) {
        // 创建ObjectMapper实例
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // 将JSON字符串解析为JsonNode
            JsonNode jsonNode = objectMapper.readTree(responseBody);

            // 获取"lines"节点
            JsonNode linesNode = jsonNode.path("result").path("lines");

            // 遍历"lines"节点中的每个Map
            Iterator<JsonNode> iterator = linesNode.elements();
            StringBuilder concatenatedText = new StringBuilder();

            while (iterator.hasNext()) {
                JsonNode lineNode = iterator.next();
                if (lineNode.isObject()) {
                    // 提取每个Map中的"text"字段
                    JsonNode textNode = lineNode.path("text");
                    if (textNode.isTextual()) {
                        // 拼接"text"字段的值
                        concatenatedText.append(textNode.asText()).append("\n");
                    }
                }
            }
            return concatenatedText.toString();
        } catch (Exception e) {
            log.error("调用jackson提取ocr结果失败,{}", e.getMessage());
            return null;
        }
    }
}

至此调用ocr的核心代码已完成

五、编写测试用的接口

为了测试文本识别的效果,我们编写一个对外开放的接口,然后使用接口调试工具访问我们写的接口,看看效果。

在com.gzx包下新建子包controller,在controller包中新建一个TestController类:

@RestController
@RequestMapping("/test")
public class TestController {
    
    // 注入ocr服务
    @Resource
    OCRService ocrService;
    
    @PostMapping("/ocr")
    public Map<String, String> testOcr(@RequestParam("img") MultipartFile img) {
        HashMap<String, String> res = new HashMap<>();
        try{
            String ocrText = ocrService.getTextFromPic(img);
            res.put("data", ocrText);
            return res;
        } catch (RestClientException e) {
            res.put("error", "识别病例失败");
            return res;
        } catch (IOException e) {
            res.put("error", "上传失败!");
            return res;
        }
    }
}

六、启动项目进行测试

测试图片:

测试图片.jpg

使用接口调试工具进行测试: image-20240303205049939.png

可以看到,合合信息的通用文字识别服务非常强大,就算文字是手写体也能够很精准地识别,在上面这个例子中文字的识别准确率更是达到了百分之百。

补充说明

本文展示的仅为合合信息通用文本识别接口的核心用法,在合合信息官网(www.textin.com/)上有关于该接口的详细… image-20240303205835898.png

总结与心得

和众多服务产品一样,合合信息也为用户提供了方便快捷的api接口,用户只需要携带着身份凭证就可以访问接口获取服务,因此集成到自己的应用中会非常方便。

令人感到意外的是,合合信息提供的通用文字识别服务的准确率也非常高,就算是手写体也能很准确地识别出来,具有了高的准确率,就可以将该服务集成到一些特定场景下的应用中了。