ocr识别,添加pom识别的依赖SmartJavaAl

This commit is contained in:
2026-01-15 12:31:09 +08:00
parent f6c0d66484
commit 1b24e93ae9
5 changed files with 416 additions and 1 deletions

View File

@@ -35,6 +35,7 @@
<logback.version>1.2.13</logback.version> <logback.version>1.2.13</logback.version>
<spring-security.version>5.7.12</spring-security.version> <spring-security.version>5.7.12</spring-security.version>
<spring-framework.version>5.3.39</spring-framework.version> <spring-framework.version>5.3.39</spring-framework.version>
</properties> </properties>
<!-- 依赖声明 --> <!-- 依赖声明 -->

View File

@@ -12,7 +12,135 @@
<artifactId>zhyc-module</artifactId> <artifactId>zhyc-module</artifactId>
<properties>
<javacv.platform.windows-x86_64>windows-x86_64</javacv.platform.windows-x86_64>
<djl.platform.windows-x86_64>win-x86_64</djl.platform.windows-x86_64>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.smartjavaai</groupId>
<artifactId>bom</artifactId>
<version>1.1.1</version>
<type>pom</type>
<!-- 注意这里是import -->
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies> <dependencies>
<dependency>
<groupId>cn.smartjavaai</groupId>
<artifactId>common</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<!--OCR检测模块-->
<dependency>
<groupId>cn.smartjavaai</groupId>
<artifactId>ocr</artifactId>
<exclusions>
<exclusion>
<groupId>com.microsoft.onnxruntime</groupId>
<artifactId>onnxruntime</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.microsoft.onnxruntime</groupId>
<artifactId>onnxruntime</artifactId>
<version>1.20.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>ai.djl.pytorch</groupId>
<artifactId>pytorch-jni</artifactId>
<version>2.7.1-0.34.0</version>
<scope>runtime</scope>
</dependency>
<!-- windows平台 (保留对应平台的配置,可以减小包大小)-->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.5.11</version>
<classifier>${javacv.platform.windows-x86_64}</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg</artifactId>
<version>6.1.1-1.5.10</version>
<classifier>${javacv.platform.windows-x86_64}</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>openblas</artifactId>
<version>0.3.26-1.5.10</version>
<classifier>${javacv.platform.windows-x86_64}</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>opencv</artifactId>
<version>4.9.0-1.5.10</version>
<classifier>${javacv.platform.windows-x86_64}</classifier>
</dependency>
<dependency>
<groupId>ai.djl.pytorch</groupId>
<artifactId>pytorch-native-cpu</artifactId>
<classifier>${djl.platform.windows-x86_64}</classifier>
<version>2.7.1</version>
<scope>runtime</scope>
</dependency>
<dependency> <dependency>
<groupId>zhyc</groupId> <groupId>zhyc</groupId>
<artifactId>zhyc-common</artifactId> <artifactId>zhyc-common</artifactId>

View File

@@ -0,0 +1,29 @@
package com.zhyc.module.app.controller;
import com.zhyc.common.config.RuoYiConfig;
import com.zhyc.common.core.domain.AjaxResult;
import com.zhyc.module.app.util.OcrRecognizeUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/ocr")
public class OrcController {
@PostMapping
public AjaxResult orcSheepNo(String path) {
// 添加空值检查
if (path == null || path.trim().isEmpty()) {
return AjaxResult.error("路径不能为空");
}
OcrRecognizeUtil ocrRecognizeUtil = new OcrRecognizeUtil();
// 移除 /profile
path = path.replace("/profile", "");
path = RuoYiConfig.getProfile() + path;
String recognize =ocrRecognizeUtil.recognizeTwo(path);
return AjaxResult.success(recognize);
}
}

View File

@@ -0,0 +1,257 @@
package com.zhyc.module.app.util;
import ai.djl.modality.cv.Image;
import cn.smartjavaai.common.cv.SmartImageFactory;
import cn.smartjavaai.common.enums.DeviceEnum;
import cn.smartjavaai.common.utils.ImageUtils;
import cn.smartjavaai.ocr.config.DirectionModelConfig;
import cn.smartjavaai.ocr.config.OcrDetModelConfig;
import cn.smartjavaai.ocr.config.OcrRecModelConfig;
import cn.smartjavaai.ocr.config.OcrRecOptions;
import cn.smartjavaai.ocr.entity.OcrInfo;
import cn.smartjavaai.ocr.enums.CommonDetModelEnum;
import cn.smartjavaai.ocr.enums.CommonRecModelEnum;
import cn.smartjavaai.ocr.enums.DirectionModelEnum;
import cn.smartjavaai.ocr.factory.OcrModelFactory;
import cn.smartjavaai.ocr.model.common.detect.OcrCommonDetModel;
import cn.smartjavaai.ocr.model.common.direction.OcrDirectionModel;
import cn.smartjavaai.ocr.model.common.recognize.OcrCommonRecModel;
import com.alibaba.fastjson.JSONObject;
import com.zhyc.common.config.RuoYiConfig;
import lombok.extern.slf4j.Slf4j;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
/**
* OCR 文本识别 示例
* 模型下载地址https://pan.baidu.com/s/1MLfd73Vjdpnuls9-oqc9uw?pwd=1234 提取码: 1234
* 开发文档http://doc.smartjavaai.cn/
*/
/**
* OCR识别工具类
* 提供文本识别相关的功能,包括获取不同类型的识别模型、文本检测模型、方向检测模型等
* 支持普通识别、手写识别、带方向矫正的识别以及批量识别等功能
*/
@Slf4j
public class OcrRecognizeUtil {
//设备类型
public static DeviceEnum device =DeviceEnum.CPU;
/**
* 测试初始化方法,在所有测试用例执行前调用一次
* 设置SmartImageFactory使用的引擎为OpenCV并可选配置缓存路径
*
* @throws IOException 当初始化过程中发生IO异常时抛出
*/
@BeforeClass
public static void beforeAll() throws IOException {
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
//修改缓存路径
//Config.setCachePath("/Users/xxx/smartjavaai_cache");
}
/**
* 获取通用识别模型(高精确度模型)
* 注意事项:高精度模型,识别准确度高,速度慢
*
* @return 返回高精度的OCR通用识别模型实例
*/
public OcrCommonRecModel getProRecModel(){
OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
//指定文本识别模型切换模型需要同时修改modelEnum及modelPath
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_SERVER_REC_MODEL);
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
recModelConfig.setRecModelPath("C:/wwwroot/ocr/rec/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx");
recModelConfig.setDevice(device);
recModelConfig.setTextDetModel(getProDetectionModel());
recModelConfig.setDirectionModel(getDirectionModel());
return OcrModelFactory.getInstance().getRecModel(recModelConfig);
}
/**
* 获取通用识别模型(极速模型)
* 注意事项:极速模型,识别准确度低,速度快
*
* @return 返回极速的OCR通用识别模型实例
*/
public OcrCommonRecModel getFastRecModel(){
OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
//指定文本识别模型切换模型需要同时修改modelEnum及modelPath
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL);
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
recModelConfig.setRecModelPath("C:/wwwroot/ocr/rec/PP-OCRv5_mobile_rec_infer/PP-OCRv5_mobile_rec_infer.onnx");
recModelConfig.setDevice(device);
recModelConfig.setTextDetModel(getFastDetectionModel());
recModelConfig.setDirectionModel(getDirectionModel()); // 添加方向模型配置
return OcrModelFactory.getInstance().getRecModel(recModelConfig);
}
/**
* 获取文本检测模型(极速模型)
* 注意事项:极速模型,识别准确度低,速度快
*
* @return 返回极速的OCR通用检测模型实例
*/
public OcrCommonDetModel getFastDetectionModel() {
OcrDetModelConfig config = new OcrDetModelConfig();
//指定检测模型切换模型需要同时修改modelEnum及modelPath
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL);
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
config.setDetModelPath("C:/wwwroot/ocr/det/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
config.setDevice(device);
return OcrModelFactory.getInstance().getDetModel(config);
}
/**
* 获取文本检测模型(高精确度模型)
* 注意事项:高精度模型,识别准确度高,速度慢
*
* @return 返回高精度的OCR通用检测模型实例
*/
public OcrCommonDetModel getProDetectionModel() {
OcrDetModelConfig config = new OcrDetModelConfig();
//指定检测模型切换模型需要同时修改modelEnum及modelPath
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_SERVER_DET_MODEL);
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
config.setDetModelPath("C:/wwwroot/ocr/det/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
config.setDevice(device);
return OcrModelFactory.getInstance().getDetModel(config);
}
/**
* 获取方向检测模型
*
* @return 返回OCR方向检测模型实例
*/
public OcrDirectionModel getDirectionModel(){
DirectionModelConfig directionModelConfig = new DirectionModelConfig();
//指定行文本方向检测模型切换模型需要同时修改modelEnum及modelPath
directionModelConfig.setModelEnum(DirectionModelEnum.PP_LCNET_X0_25);
//指定行文本方向检测模型路径,需要更改为自己的模型路径(下载地址请查看文档)
directionModelConfig.setModelPath("C:/wwwroot/ocr/ori/PP-LCNet_x0_25_textline_ori_infer.onnx");
directionModelConfig.setDevice(device);
return OcrModelFactory.getInstance().getDirectionModel(directionModelConfig);
}
/**
* 文本识别
* 支持简体中文、繁体中文、英文、日文四种主要语言,以及手写、竖版、拼音、生僻字
* 流程:文本检测 -> 文本识别
* 注意事项:
* 1、批量检测时模型应统一放在外层 try 中使用,避免重复加载,自动释放资源更安全。
* 2、模型文件需要放在单独文件夹
*/
public String recognize(String path){
try {
OcrCommonRecModel recModel = getFastRecModel();
//不带方向矫正,分行返回文本
OcrRecOptions options = new OcrRecOptions(false, true);
//创建Image对象可以从文件、url、InputStream创建、BufferedImage、Base64创建具体使用方法可以查看文档
Image image = SmartImageFactory.getInstance().fromFile(path);
OcrInfo ocrInfo = recModel.recognize(image, options);
log.info("OCR识别结果{}", JSONObject.toJSONString(ocrInfo.getFullText()));
// 识别成功后删除原图片
deleteFile(path);
return ocrInfo.getFullText();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 文本识别(手写字)
* 支持简体中文、繁体中文、英文、日文四种主要语言,以及手写、竖版、拼音、生僻字
* 流程:文本检测 -> 文本识别
* 注意事项:
* 1、批量检测时模型应统一放在外层 try 中使用,避免重复加载,自动释放资源更安全。
* 2、模型文件需要放在单独文件夹
* 3、识别完成后会删除原图片文件
*/
public void recognizeHandWriting(String path){
try {
OcrCommonRecModel recModel = getFastRecModel();
//创建Image对象可以从文件、url、InputStream创建、BufferedImage、Base64创建具体使用方法可以查看文档
Image image = SmartImageFactory.getInstance().fromFile(path);
OcrInfo ocrInfo = recModel.recognize(image, new OcrRecOptions());
log.info("OCR识别结果{}", JSONObject.toJSONString(ocrInfo));
// 识别成功后删除原图片
deleteFile(path);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 文本识别(带方向矫正)
* 支持简体中文、繁体中文、英文、日文四种主要语言,以及手写、竖版、拼音、生僻字
* 本方法支持多角度文字识别
* 流程:文本检测 -> 方向检测 -> 方向矫正 -> 文本识别
* 注意事项:
* 1、批量检测时模型应统一放在外层 try 中使用,避免重复加载,自动释放资源更安全。
* 2、模型文件需要放在单独文件夹
* 3、识别完成后会删除原图片文件
*/
public String recognizeTwo(String path){
try {
OcrCommonRecModel recModel = getFastRecModel();
//带方向矫正,分行返回文本
OcrRecOptions options = new OcrRecOptions(true, true);
//创建Image对象可以从文件、url、InputStream创建、BufferedImage、Base64创建具体使用方法可以查看文档
Image image = SmartImageFactory.getInstance().fromFile(path);
OcrInfo ocrInfo = recModel.recognize(image, options);
log.info("OCR识别结果{}", JSONObject.toJSONString(ocrInfo));
// 识别成功后删除原图片
deleteFile(path);
return ocrInfo.getFullText();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 删除指定路径的文件
*
* @param filePath 要删除的文件路径
* @return 删除是否成功
*/
private boolean deleteFile(String filePath) {
try {
File file = new File(filePath);
if (file.exists()) {
boolean deleted = file.delete();
if (deleted) {
log.info("已删除文件: {}", filePath);
} else {
log.warn("删除文件失败: {}", filePath);
}
return deleted;
} else {
log.warn("文件不存在: {}", filePath);
return false;
}
} catch (Exception e) {
log.error("删除文件时发生异常: {}", filePath, e);
return false;
}
}
}

View File

@@ -46,7 +46,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="orderNo != null and orderNo != ''"> and order_no like concat('%', #{orderNo}, '%')</if> <if test="orderNo != null and orderNo != ''"> and order_no like concat('%', #{orderNo}, '%')</if>
<if test="planId != null "> and plan_id = #{planId}</if> <if test="planId != null "> and plan_id = #{planId}</if>
<!-- 业务类型批量查询 --> <!-- 业务类型批量查询 -->
<if test="bizTypeArray != null and bizTypesArray.length > 0"> <if test="bizTypeArray != null and bizTypeArray.length > 0">
and biz_type in and biz_type in
<foreach collection="bizTypeArray" item="item" open="(" separator="," close=")"> <foreach collection="bizTypeArray" item="item" open="(" separator="," close=")">
#{item} #{item}