mirror of
https://github.com/geekwenjie/SmartJavaAI.git
synced 2026-09-12 12:48:57 +00:00
【人脸识别】 新增多种人脸识别模型
【底层优化】 支持自由选择 OpenCV 或 BufferedImage 作为图像引擎 【通用图像】 全部模型启用 Image 输入,支持各类图片格式与 Image 的互转 【模型管理】 优化模型生命周期,关闭后可重新创建 【人脸识别】 支持在人脸查询结果中绘制姓名标注 【人脸检测】 新增人脸裁剪功能 【修复】 修复若干已知问题,提升系统稳定性
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 682 KiB After Width: | Height: | Size: 674 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 273 KiB |
@@ -12,7 +12,7 @@
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<smartjavaai.version>1.0.24</smartjavaai.version>
|
||||
<smartjavaai.version>1.0.25</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.ocr.common.OcrRecognizeDemo</exec.mainClass>
|
||||
|
||||
@@ -219,39 +219,6 @@
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- linux aarch64 平台 (保留对应平台的配置,可以减小包大小)-->
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>${javacv.version}</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>ffmpeg</artifactId>
|
||||
<version>6.1.1-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>openblas</artifactId>
|
||||
<version>0.3.26-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>4.9.0-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -2,6 +2,7 @@ package smartai.examples.ocr.common;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
@@ -43,6 +44,7 @@ public class OcrDetectionDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -56,7 +58,7 @@ public class OcrDetectionDemo {
|
||||
//指定检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL);
|
||||
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
config.setDetModelPath("/Users/xxx/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
config.setDetModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
}
|
||||
@@ -73,7 +75,9 @@ public class OcrDetectionDemo {
|
||||
public void detect(){
|
||||
try {
|
||||
OcrCommonDetModel model = getDetectionModel();
|
||||
List<OcrBox> boxes = model.detect("src/main/resources/ocr_1.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_1.jpg");
|
||||
List<OcrBox> boxes = model.detect(image);
|
||||
log.info("OCR检测结果:{}", JSONObject.toJSONString(boxes));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -97,6 +101,26 @@ public class OcrDetectionDemo {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本检测并绘制结果
|
||||
* 检测图像中的文本区域,仅检测文本框位置,不识别文字内容
|
||||
* 注意事项:
|
||||
* 1、批量检测时,模型应统一放在外层 try 中使用,避免重复加载,自动释放资源更安全。
|
||||
* 2、模型文件需要放在单独文件夹
|
||||
*/
|
||||
@Test
|
||||
public void detectAndDraw2(){
|
||||
try {
|
||||
OcrCommonDetModel model = getDetectionModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_1.jpg");
|
||||
Image resultImage = model.detectAndDraw(image);
|
||||
ImageUtils.save(resultImage, "output/ocr_1_detected2.jpg");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量文本检测:批量检测要求图片宽高一致
|
||||
@@ -110,7 +134,7 @@ public class OcrDetectionDemo {
|
||||
try {
|
||||
OcrCommonDetModel model = getDetectionModel();
|
||||
//批量检测要求图片宽高一致
|
||||
String folderPath = "/Users/xxx/Downloads/testing33";
|
||||
String folderPath = "/Users/wenjie/Downloads/testing33";
|
||||
//读取文件夹中所有图片
|
||||
List<Image> images = ImageUtils.readImagesFromFolder(folderPath);
|
||||
List<List<OcrBox>> ocrResult = model.batchDetectDJLImage(images);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package smartai.examples.ocr.common;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
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.entity.OcrBox;
|
||||
@@ -46,7 +49,7 @@ public class OcrDirectionDetDemo {
|
||||
//指定行文本方向检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
directionModelConfig.setModelEnum(DirectionModelEnum.PP_LCNET_X0_25);
|
||||
//指定行文本方向检测模型路径,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
directionModelConfig.setModelPath("/Users/xxx/Documents/develop/model/ocr/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx");
|
||||
directionModelConfig.setModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx");
|
||||
directionModelConfig.setDevice(device);
|
||||
directionModelConfig.setTextDetModel(getDetectionModel());
|
||||
return OcrModelFactory.getInstance().getDirectionModel(directionModelConfig);
|
||||
@@ -61,7 +64,7 @@ public class OcrDirectionDetDemo {
|
||||
//指定检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL);
|
||||
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
config.setDetModelPath("/Users/xxx/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
config.setDetModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
}
|
||||
@@ -78,7 +81,9 @@ public class OcrDirectionDetDemo {
|
||||
public void detect(){
|
||||
try {
|
||||
OcrDirectionModel directionModel = getDirectionModel();
|
||||
List<OcrItem> itemList = directionModel.detect("src/main/resources/ocr_1.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_1.jpg");
|
||||
List<OcrItem> itemList = directionModel.detect(image);
|
||||
log.info("OCR方向检测结果1:{}", JSONObject.toJSONString(itemList));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -102,6 +107,25 @@ public class OcrDirectionDetDemo {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本检测并绘制结果
|
||||
* 流程:文本检测 -> 方向分类
|
||||
* 检测图像中的文本区域,仅检测文本框位置,不识别文字内容
|
||||
* 模型需要放在单独文件夹
|
||||
*/
|
||||
@Test
|
||||
public void detectAndDraw2(){
|
||||
try {
|
||||
OcrDirectionModel directionModel = getDirectionModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_1.jpg");
|
||||
Image resultImage = directionModel.detectAndDraw(image);
|
||||
ImageUtils.save(resultImage, "output/ocr_1_detected4.jpg");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import ai.djl.util.JsonUtils;
|
||||
import cn.hutool.core.img.ImgUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.utils.BufferedImageUtils;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
import cn.smartjavaai.ocr.config.DirectionModelConfig;
|
||||
import cn.smartjavaai.ocr.config.OcrDetModelConfig;
|
||||
@@ -48,34 +50,70 @@ public class OcrRecognizeDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
//Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通用识别模型(不带方向矫正)
|
||||
* 获取通用识别模型(高精确度模型)
|
||||
* 注意事项:高精度模型,识别准确度高,速度慢
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonRecModel getRecModel(){
|
||||
public OcrCommonRecModel getProRecModel(){
|
||||
OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
|
||||
//指定文本识别模型,切换模型需要同时修改modelEnum及modelPath
|
||||
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL);
|
||||
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_SERVER_REC_MODEL);
|
||||
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
recModelConfig.setRecModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx");
|
||||
recModelConfig.setDevice(device);
|
||||
recModelConfig.setTextDetModel(getDetectionModel());
|
||||
recModelConfig.setTextDetModel(getProDetectionModel());
|
||||
recModelConfig.setDirectionModel(getDirectionModel());
|
||||
return OcrModelFactory.getInstance().getRecModel(recModelConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文本检测模型
|
||||
* 获取通用识别模型(极速模型)
|
||||
* 注意事项:极速模型,识别准确度低,速度快
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonDetModel getDetectionModel() {
|
||||
public OcrCommonRecModel getFastRecModel(){
|
||||
OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
|
||||
//指定文本识别模型,切换模型需要同时修改modelEnum及modelPath
|
||||
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL);
|
||||
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
recModelConfig.setRecModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_mobile_rec_infer/PP-OCRv5_mobile_rec_infer.onnx");
|
||||
recModelConfig.setDevice(device);
|
||||
recModelConfig.setTextDetModel(getFastDetectionModel());
|
||||
return OcrModelFactory.getInstance().getRecModel(recModelConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取文本检测模型(极速模型)
|
||||
* 注意事项:极速模型,识别准确度低,速度快
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonDetModel getFastDetectionModel() {
|
||||
OcrDetModelConfig config = new OcrDetModelConfig();
|
||||
//指定检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL);
|
||||
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
config.setDetModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文本检测模型(高精确度模型)
|
||||
* 注意事项:高精度模型,识别准确度高,速度慢
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonDetModel getProDetectionModel() {
|
||||
OcrDetModelConfig config = new OcrDetModelConfig();
|
||||
//指定检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_SERVER_DET_MODEL);
|
||||
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
config.setDetModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
@@ -90,28 +128,12 @@ public class OcrRecognizeDemo {
|
||||
//指定行文本方向检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
directionModelConfig.setModelEnum(DirectionModelEnum.PP_LCNET_X0_25);
|
||||
//指定行文本方向检测模型路径,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
directionModelConfig.setModelPath("/Users/xxx/Documents/develop/model/ocr/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx");
|
||||
directionModelConfig.setModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx");
|
||||
directionModelConfig.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDirectionModel(directionModelConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取通用识别模型(带方向矫正)
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonRecModel getRecModelWithDirection() {
|
||||
OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
|
||||
//指定文本识别模型,切换模型需要同时修改modelEnum及modelPath
|
||||
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL);
|
||||
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
recModelConfig.setRecModelPath("/Users/xxx/Documents/develop/model/ocr/PP-OCRv5_mobile_rec_infer/PP-OCRv5_mobile_rec_infer.onnx");
|
||||
recModelConfig.setDevice(device);
|
||||
recModelConfig.setTextDetModel(getDetectionModel());
|
||||
recModelConfig.setDirectionModel(getDirectionModel());
|
||||
return OcrModelFactory.getInstance().getRecModel(recModelConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 文本识别
|
||||
@@ -124,10 +146,12 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void recognize(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
//不带方向矫正,分行返回文本
|
||||
OcrRecOptions options = new OcrRecOptions(false, true);
|
||||
OcrInfo ocrInfo = recModel.recognize("/Users/wenjie/Downloads/49421755855753_.pic_hd.jpg",options);
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_1.jpg");
|
||||
OcrInfo ocrInfo = recModel.recognize(image, options);
|
||||
log.info("OCR识别结果:{}", JSONObject.toJSONString(ocrInfo));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -146,8 +170,10 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void recognizeHandWriting(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
OcrInfo ocrInfo = recModel.recognize("src/main/resources/handwriting_1.jpg",new OcrRecOptions());
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/handwriting_1.jpg");
|
||||
OcrInfo ocrInfo = recModel.recognize(image, new OcrRecOptions());
|
||||
log.info("OCR识别结果:{}", JSONObject.toJSONString(ocrInfo));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -166,10 +192,12 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void recognize2(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModelWithDirection();
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
//带方向矫正,分行返回文本
|
||||
OcrRecOptions options = new OcrRecOptions(true, true);
|
||||
OcrInfo ocrInfo = recModel.recognize("src/main/resources/ocr_3.jpg",options);
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_3.jpg");
|
||||
OcrInfo ocrInfo = recModel.recognize(image, options);
|
||||
log.info("OCR识别结果:{}", JSONObject.toJSONString(ocrInfo));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -189,7 +217,7 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void recognizeAndDraw(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModelWithDirection();
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
int fontSize = 18;
|
||||
recModel.recognizeAndDraw("src/main/resources/general_ocr_002.png", "output/ocr_4_recognized.jpg", fontSize, new OcrRecOptions());
|
||||
} catch (Exception e) {
|
||||
@@ -200,55 +228,24 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void recognizeAndDraw2(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
int fontSize = 18;
|
||||
//创建保存路径
|
||||
Path inputImagePath = Paths.get("src/main/resources/general_ocr_002.png");
|
||||
Path imageOutputPath = Paths.get("output/ocr_4_recognized.jpg");
|
||||
BufferedImage image = null;
|
||||
image = ImageIO.read(new File(inputImagePath.toAbsolutePath().toString()));
|
||||
BufferedImage resultImage = recModel.recognizeAndDraw(image, fontSize, new OcrRecOptions());
|
||||
ImageUtils.saveImage(resultImage, imageOutputPath.toAbsolutePath().toString());
|
||||
Path imageOutputPath = Paths.get("output/ocr_5_recognized.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile(inputImagePath);
|
||||
OcrInfo ocrInfo = recModel.recognizeAndDraw(image, fontSize, new OcrRecOptions());
|
||||
log.info("OCR识别结果:{}", JSONObject.toJSONString(ocrInfo));
|
||||
//保存绘制结果
|
||||
if(ocrInfo != null && ocrInfo.getDrawnImage() != null){
|
||||
ImageUtils.save(ocrInfo.getDrawnImage(), imageOutputPath.toAbsolutePath().toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本识别并绘制结果(返回base64)
|
||||
*/
|
||||
@Test
|
||||
public void recognizeAndDrawToBase64(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
int fontSize = 18;
|
||||
//创建保存路径
|
||||
Path inputImagePath = Paths.get("src/main/resources/general_ocr_002.png");
|
||||
byte[] imageBytes = FileUtil.readBytes(inputImagePath);
|
||||
String base64 = recModel.recognizeAndDrawToBase64(imageBytes, fontSize, new OcrRecOptions());
|
||||
log.info("base64:{}", base64);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本识别并绘制结果(返回OcrInfo,OcrInfo中包含base64)
|
||||
*/
|
||||
@Test
|
||||
public void recognizeAndDraw3(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
int fontSize = 18;
|
||||
//创建保存路径
|
||||
Path inputImagePath = Paths.get("src/main/resources/general_ocr_002.png");
|
||||
byte[] imageBytes = FileUtil.readBytes(inputImagePath);
|
||||
OcrInfo ocrInfo = recModel.recognizeAndDraw(imageBytes, fontSize, new OcrRecOptions());
|
||||
log.info("ocrInfo:{}", JsonUtils.toJson(ocrInfo));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量识别
|
||||
@@ -259,7 +256,7 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void batchRecognize(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModelWithDirection();
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
//批量检测要求图片宽高一致
|
||||
String folderPath = "/Users/xxx/Downloads/testing33";
|
||||
//读取文件夹中所有图片
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package smartai.examples.ocr.plate;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.util.JsonUtils;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.R;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
@@ -38,6 +40,7 @@ public class PlateRecDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -68,6 +71,7 @@ public class PlateRecDemo {
|
||||
recModelConfig.setModelPath("/Users/wenjie/Documents/develop/model/plate/plate_rec_color.onnx");
|
||||
//指定车牌检测模型
|
||||
recModelConfig.setPlateDetModel(getPlateDetModel());
|
||||
recModelConfig.setDevice(device);
|
||||
return PlateModelFactory.getInstance().getRecModel(recModelConfig);
|
||||
}
|
||||
|
||||
@@ -75,10 +79,12 @@ public class PlateRecDemo {
|
||||
* 车牌识别
|
||||
*/
|
||||
@Test
|
||||
public void testDetect() {
|
||||
public void testDetect() throws IOException {
|
||||
PlateRecModel plateRecModel = getPlateRecModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/plate/Quicker_20220930_180856.png");
|
||||
//识别车号
|
||||
R<List<PlateInfo>> result = plateRecModel.recognize("src/main/resources/plate/Quicker_20220930_180856.png");
|
||||
R<List<PlateInfo>> result = plateRecModel.recognize(image);
|
||||
if(result.isSuccess()){
|
||||
log.info("车牌识别结果:{}", JsonUtils.toJson(result.getData()));
|
||||
}else{
|
||||
@@ -109,14 +115,14 @@ public class PlateRecDemo {
|
||||
public void recognizeAndDraw2() {
|
||||
try {
|
||||
PlateRecModel plateRecModel = getPlateRecModel();
|
||||
BufferedImage image = null;
|
||||
String imagePath = "src/main/resources/plate/Quicker_20220930_180856.png";
|
||||
image = ImageIO.read(new File(Paths.get(imagePath).toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile(imagePath);
|
||||
//可以根据后续业务场景使用detectedImage
|
||||
R<BufferedImage> detectedImage = plateRecModel.recognizeAndDraw(image);
|
||||
R<Image> detectedImage = plateRecModel.recognizeAndDraw(image);
|
||||
if(detectedImage.isSuccess()){
|
||||
log.info("车牌识别成功");
|
||||
ImageUtils.saveImage(detectedImage.getData(), "output/plate_recognized2.jpg");
|
||||
ImageUtils.save(detectedImage.getData(), "output/plate_recognized3.jpg");
|
||||
}else{
|
||||
log.error("车牌识别失败:{}", detectedImage.getMessage());
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package smartai.examples.ocr.table;
|
||||
import ai.djl.modality.cv.Image;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.R;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
@@ -47,6 +48,7 @@ public class TableRecDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -79,7 +81,6 @@ public class TableRecDemo {
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL);
|
||||
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
config.setDetModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
// config.setDetModelPath("/Users/xxx/Documents/develop/model/ocr/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
}
|
||||
@@ -115,45 +116,6 @@ public class TableRecDemo {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 表格识别
|
||||
* 仅支持简单表格
|
||||
* 流程:表格结构识别 -> 文本检测 -> 文本识别 -> 合成html table
|
||||
* 注意事项:
|
||||
* 1、批量检测时,模型应统一放在外层 try 中使用,避免重复加载,自动释放资源更安全。
|
||||
* 2、模型文件需要放在单独文件夹
|
||||
*/
|
||||
@Test
|
||||
public void recognize(){
|
||||
try {
|
||||
TableStructureModel tableStructureModel = getTableStructureModel();
|
||||
OcrCommonDetModel detModel = getDetectionModel();
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
OcrDirectionModel directionModel = getDirectionModel();
|
||||
//创建表格识别器
|
||||
TableRecognizer tableRecognizer = TableRecognizer.builder()
|
||||
.withStructureModel(tableStructureModel)
|
||||
.withTextDetModel(detModel)
|
||||
// .withDirectionModel(getDirectionModel()) //如果表格中存在旋转的文字,可以使用方向分类模型
|
||||
.withTextRecModel(recModel).build();
|
||||
String imagePath = "src/main/resources/table/table_ch1.png";
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get(imagePath).toAbsolutePath().toString()));
|
||||
R<TableStructureResult> result = tableRecognizer.recognize(image);
|
||||
if(result.isSuccess()){
|
||||
log.info("result: {}", result.getData().getHtml());
|
||||
//导出html内容到文件
|
||||
Path outputPath = Paths.get("output/table_ch2_result.html");
|
||||
FileUtil.writeUtf8String(result.getData().getHtml(), outputPath.toAbsolutePath().toString());
|
||||
//绘制表格结构
|
||||
tableRecognizer.drawTable(result.getData(), image, "output/table_ch2_result.jpg");
|
||||
//导出excel,如果导出失败,可能是因为表格结果识别的结果是错乱的
|
||||
tableRecognizer.exportExcel(result.getData().getHtml(), "output/table_ch2_result.xls");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 表格识别
|
||||
@@ -177,7 +139,8 @@ public class TableRecDemo {
|
||||
// .withDirectionModel(getDirectionModel()) //如果表格中存在旋转的文字,可以使用方向分类模型
|
||||
.withTextRecModel(recModel).build();
|
||||
String imagePath = "src/main/resources/table/table_ch1.png";
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get(imagePath).toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile(imagePath);
|
||||
R<TableStructureResult> result = tableRecognizer.recognize(image);
|
||||
if(result.isSuccess()){
|
||||
log.info("result: {}", result.getData().getHtml());
|
||||
@@ -185,8 +148,8 @@ public class TableRecDemo {
|
||||
Path outputPath = Paths.get("output/table_ch2_result.html");
|
||||
FileUtil.writeUtf8String(result.getData().getHtml(), outputPath.toAbsolutePath().toString());
|
||||
//绘制表格结构
|
||||
BufferedImage resultImage = tableRecognizer.drawTable(result.getData(), image);
|
||||
ImageUtils.saveImage(resultImage, "output/table_ch2_result.jpg");
|
||||
Image resultImage = tableRecognizer.drawTable(result.getData(), image);
|
||||
ImageUtils.save(resultImage, "output/table_ch2_result.jpg");
|
||||
//导出excel,如果导出失败,可能是因为表格结果识别的结果是错乱的
|
||||
try (OutputStream out = Files.newOutputStream(Paths.get("output/table_ch2_result2.xls"))) {
|
||||
tableRecognizer.exportExcel(result.getData().getHtml(), out);
|
||||
|
||||
Reference in New Issue
Block a user