Springboot整合TextIn通用文字识别服务教程与心得
合合信息通用文字识别服务说明
合合信息是一家人工智能及大数据科技企业,基于自主研发的领先的智能文字识别及商业大数据核心技术,为全球C端用户和多元行业B端客户提供数字化、智能化的产品及服务。
合合信息通用文字识别服务:通过前沿的深度学习技术,对各种表格,图片,文档、证件、面单等多种通用场景进行快速、精准的检测和识别,支持简体中文/繁体中文/英文/数字/西欧主流语言/东欧主流语言等共52种语言,同时支持印刷体、手写体、倾斜、折叠、旋转等。
本文通过创建springboot web项目模拟实际工程项目,在工程中调用合合信息通用文字识别接口的方式,演示合合信息通用文字识别接口的使用。
整体流程
一、创建Springboot工程
在idea中新建一个maven项目,导入springboot相关依赖。
目录结构:
在pom文件中引入相关依赖:
二、开通合合信息服务,编写配置文件
合合信息通用文字识别开通:www.textin.com/market/deta…
开通后在控制台获取appId 和 secretCode:
后续发送通用文字识别请求需要带上上面的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;
}
}
}
六、启动项目进行测试
测试图片:
使用接口调试工具进行测试:
可以看到,合合信息的通用文字识别服务非常强大,就算文字是手写体也能够很精准地识别,在上面这个例子中文字的识别准确率更是达到了百分之百。
补充说明
本文展示的仅为合合信息通用文本识别接口的核心用法,在合合信息官网(www.textin.com/)上有关于该接口的详细…
总结与心得
和众多服务产品一样,合合信息也为用户提供了方便快捷的api接口,用户只需要携带着身份凭证就可以访问接口获取服务,因此集成到自己的应用中会非常方便。
令人感到意外的是,合合信息提供的通用文字识别服务的准确率也非常高,就算是手写体也能很准确地识别出来,具有了高的准确率,就可以将该服务集成到一些特定场景下的应用中了。