OCR系统集成
This commit is contained in:
parent
8c8798a7e2
commit
2123dcd347
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.bonus.web.controller.common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @className:UploadFileController
|
||||||
|
* @author:cwchen
|
||||||
|
* @date:2025-10-16-13:43
|
||||||
|
* @version:1.0
|
||||||
|
* @description:文件上传
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CommonUploadFileController {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.bonus.web.controller.ocr;
|
||||||
|
|
||||||
|
import com.bonus.common.core.domain.AjaxResult;
|
||||||
|
import com.bonus.common.domain.ocr.dto.OcrRequest;
|
||||||
|
import com.bonus.common.domain.ocr.vo.OcrResponse;
|
||||||
|
import com.bonus.ocr.service.OcrService;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @className:OcrController
|
||||||
|
* @author:cwchen
|
||||||
|
* @date:2025-10-16-13:55
|
||||||
|
* @version:1.0
|
||||||
|
* @description:ocr识别
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/ocr")
|
||||||
|
public class OcrController {
|
||||||
|
|
||||||
|
@Resource(name = "OcrService")
|
||||||
|
private OcrService ocrService;
|
||||||
|
|
||||||
|
@PostMapping(value = "ocrHandler")
|
||||||
|
private AjaxResult ocrHandler() throws IOException {
|
||||||
|
OcrRequest ocrRequest = new OcrRequest();
|
||||||
|
File file = new File("C:\\Users\\10488\\Desktop\\新建文件夹\\1955905740907290625.png");
|
||||||
|
ocrRequest.setFile(file);
|
||||||
|
ocrRequest.setType("image/png");
|
||||||
|
ocrRequest.setFields_json("[\"姓名\", \"公民身份号码\"]");
|
||||||
|
OcrResponse ocrResponse = ocrService.callOcrService(ocrRequest);
|
||||||
|
return AjaxResult.success(ocrResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
ocr:
|
ocr:
|
||||||
service:
|
service:
|
||||||
url: http://192.168.0.37:8000/ocr/ # ocr 请求地址
|
url: http://192.168.0.37:8000/extract/ # ocr 请求地址
|
||||||
healthUrl: http://192.168.0.37:8000/ # ocr 服务健康检查
|
healthUrl: http://192.168.0.37:8000/ # ocr 服务健康检查
|
||||||
timeout: 30000 # ocr 请求超时时间
|
timeout: 30000 # ocr 请求超时时间
|
||||||
max-connections: 100
|
max-connections: 100
|
||||||
|
|
@ -21,13 +21,13 @@ public class OcrRequest {
|
||||||
@JsonProperty("type")
|
@JsonProperty("type")
|
||||||
private String type; // 文件类型
|
private String type; // 文件类型
|
||||||
|
|
||||||
@JsonProperty("analysisContent")
|
@JsonProperty("fields_json")
|
||||||
private String analysisContent;
|
private String fields_json;
|
||||||
|
|
||||||
public OcrRequest(File file, String type, String analysisContent) {
|
public OcrRequest(File file, String type, String fields_json) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.analysisContent = analysisContent;
|
this.fields_json = fields_json;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OcrRequest() {
|
public OcrRequest() {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@ package com.bonus.common.domain.ocr.vo;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @className:OcrData
|
* @className:OcrData
|
||||||
|
|
@ -15,15 +17,24 @@ import java.util.List;
|
||||||
@Data
|
@Data
|
||||||
public class OcrData {
|
public class OcrData {
|
||||||
|
|
||||||
@JsonProperty("text")
|
@JsonProperty("chat_res")
|
||||||
private String text; // 识别出的文本
|
private Map<String, String> chatRes;
|
||||||
|
|
||||||
@JsonProperty("confidence")
|
/**
|
||||||
private Double confidence; // 置信度
|
* 获取识别文本
|
||||||
|
*/
|
||||||
@JsonProperty("words")
|
public String getText() {
|
||||||
private List<WordInfo> words; // 单词列表
|
if (chatRes == null) return null;
|
||||||
|
// 将所有字段值拼接成文本
|
||||||
@JsonProperty("processing_time")
|
return chatRes.values().stream()
|
||||||
private Double processingTime; // 处理时间
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.joining(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取特定字段值
|
||||||
|
*/
|
||||||
|
public String getFieldValue(String fieldName) {
|
||||||
|
return chatRes != null ? chatRes.get(fieldName) : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ import lombok.Data;
|
||||||
@Data
|
@Data
|
||||||
public class OcrResponse {
|
public class OcrResponse {
|
||||||
|
|
||||||
@JsonProperty("code")
|
@JsonProperty("status_code")
|
||||||
private Integer code; // 状态码
|
private Integer statusCode; // 状态码
|
||||||
|
|
||||||
@JsonProperty("message")
|
@JsonProperty("message")
|
||||||
private String message; // 消息
|
private String message; // 消息
|
||||||
|
|
@ -22,6 +22,7 @@ public class OcrResponse {
|
||||||
@JsonProperty("data")
|
@JsonProperty("data")
|
||||||
private OcrData data; // 识别数据
|
private OcrData data; // 识别数据
|
||||||
|
|
||||||
@JsonProperty("request_id")
|
public boolean isSuccess() {
|
||||||
private String requestId; // 请求ID
|
return statusCode != null && statusCode == 200;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package com.bonus.common.domain.ocr.vo;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @className:WordInfo
|
|
||||||
* @author:cwchen
|
|
||||||
* @date:2025-10-16-10:43
|
|
||||||
* @version:1.0
|
|
||||||
* @description: 单词信息DTO
|
|
||||||
*/
|
|
||||||
public class WordInfo {
|
|
||||||
|
|
||||||
@JsonProperty("text")
|
|
||||||
private String text; // 单词文本
|
|
||||||
|
|
||||||
@JsonProperty("confidence")
|
|
||||||
private Double confidence; // 单词置信度
|
|
||||||
|
|
||||||
@JsonProperty("bbox")
|
|
||||||
private List<Integer> bbox; // 边界框 [x1, y1, x2, y2, x3, y3, x4, y4]
|
|
||||||
}
|
|
||||||
|
|
@ -19,6 +19,7 @@ import org.apache.http.entity.mime.content.FileBody;
|
||||||
import org.apache.http.entity.ContentType;
|
import org.apache.http.entity.ContentType;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @className:OcrService
|
* @className:OcrService
|
||||||
|
|
@ -62,7 +63,7 @@ public class OcrService {
|
||||||
/**
|
/**
|
||||||
* 调用OCR服务
|
* 调用OCR服务
|
||||||
*/
|
*/
|
||||||
private OcrResponse callOcrService(OcrRequest ocrRequest) throws IOException {
|
public OcrResponse callOcrService(OcrRequest ocrRequest) throws IOException {
|
||||||
HttpPost httpPost = new HttpPost(ocrServiceUrl);
|
HttpPost httpPost = new HttpPost(ocrServiceUrl);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -78,29 +79,33 @@ public class OcrService {
|
||||||
builder.addTextBody("type", ocrRequest.getType(),
|
builder.addTextBody("type", ocrRequest.getType(),
|
||||||
ContentType.TEXT_PLAIN.withCharset("UTF-8"));
|
ContentType.TEXT_PLAIN.withCharset("UTF-8"));
|
||||||
// 添加解析内容字段
|
// 添加解析内容字段
|
||||||
builder.addTextBody("analysisContent", ocrRequest.getAnalysisContent(),
|
builder.addTextBody("fields_json", ocrRequest.getFields_json(),
|
||||||
ContentType.TEXT_PLAIN.withCharset("UTF-8"));
|
ContentType.TEXT_PLAIN.withCharset("UTF-8"));
|
||||||
|
|
||||||
// 设置请求实体 - 注意:这里会自动设置正确的 Content-Type 和 boundary
|
// 设置请求实体 - 注意:这里会自动设置正确的 Content-Type 和 boundary
|
||||||
httpPost.setEntity(builder.build());
|
httpPost.setEntity(builder.build());
|
||||||
// 设置 Accept 头
|
// 设置 Accept 头
|
||||||
httpPost.setHeader("Accept", "application/json");
|
httpPost.setHeader("Accept", "application/json");
|
||||||
log.debug("发送OCR请求到: {}", ocrServiceUrl);
|
|
||||||
|
|
||||||
// 执行请求
|
// 执行请求
|
||||||
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
|
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
|
||||||
HttpEntity entity = response.getEntity();
|
HttpEntity entity = response.getEntity();
|
||||||
String responseBody = EntityUtils.toString(entity, "UTF-8");
|
String responseBody = EntityUtils.toString(entity, "UTF-8");
|
||||||
log.debug("OCR服务响应状态: {}", response.getStatusLine().getStatusCode());
|
log.info("OCR服务响应状态: {}", response.getStatusLine().getStatusCode());
|
||||||
log.debug("OCR服务响应内容: {}", responseBody);
|
log.info("OCR服务响应内容: {}", responseBody);
|
||||||
|
|
||||||
// 解析响应
|
// 解析响应
|
||||||
OcrResponse ocrResponse = objectMapper.readValue(responseBody, OcrResponse.class);
|
OcrResponse ocrResponse = objectMapper.readValue(responseBody, OcrResponse.class);
|
||||||
|
|
||||||
if (ocrResponse.getCode() != null && ocrResponse.getCode() == 200) {
|
if (ocrResponse.isSuccess()) {
|
||||||
/*log.info("OCR识别成功,识别字符数: {}",
|
log.info("OCR识别成功");
|
||||||
ocrResponse.getData() != null && ocrResponse.getData().getText() != null ?
|
// 获取识别结果
|
||||||
ocrResponse.getData().getText().length() : 0);*/
|
if (ocrResponse.getData() != null && ocrResponse.getData().getChatRes() != null) {
|
||||||
|
Map<String, String> chatRes = ocrResponse.getData().getChatRes();
|
||||||
|
chatRes.forEach((k, v) -> {
|
||||||
|
log.info("识别结果 - key: {}, value: {}", k, v);
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("OCR识别失败: {}", ocrResponse.getMessage());
|
log.warn("OCR识别失败: {}", ocrResponse.getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue