mirror of
https://github.com/geekwenjie/SmartJavaAI.git
synced 2026-09-09 19:18:52 +00:00
新增身份证识别能力
This commit is contained in:
@@ -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.1.1</smartjavaai.version>
|
||||
<smartjavaai.version>1.1.2</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.face.FaceDemo</exec.mainClass>
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
<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.1.1</smartjavaai.version>
|
||||
<smartjavaai.version>1.1.2</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.ocr.common.OcrRecognizeDemo</exec.mainClass>
|
||||
<exec.mainClass>smartai.examples.ocr.common.OcrDetectionDemo</exec.mainClass>
|
||||
|
||||
<javacv.version>1.5.10</javacv.version>
|
||||
|
||||
@@ -90,19 +90,33 @@
|
||||
<groupId>cn.smartjavaai</groupId>
|
||||
<artifactId>ocr</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.microsoft.onnxruntime</groupId>
|
||||
<artifactId>onnxruntime</artifactId>
|
||||
</exclusion>
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.openpnp</groupId>-->
|
||||
<!-- <artifactId>opencv</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>com.microsoft.onnxruntime</groupId>-->
|
||||
<!-- <artifactId>onnxruntime</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>javacv</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.microsoft.onnxruntime</groupId>
|
||||
<artifactId>onnxruntime</artifactId>
|
||||
<version>1.20.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.microsoft.onnxruntime</groupId>-->
|
||||
<!-- <artifactId>onnxruntime</artifactId>-->
|
||||
<!-- <version>1.16.3</version>-->
|
||||
<!-- <scope>compile</scope>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.openpnp</groupId>-->
|
||||
<!-- <artifactId>opencv</artifactId>-->
|
||||
<!-- <version>3.4.2-2</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
|
||||
<dependency>
|
||||
@@ -113,79 +127,10 @@
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- windows平台 (保留对应平台的配置,可以减小包大小)-->
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>${javacv.version}</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>
|
||||
|
||||
|
||||
|
||||
<!-- linux x86 平台 (保留对应平台的配置,可以减小包大小)-->
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>${javacv.version}</version>
|
||||
<classifier>${javacv.platform.linux-x86_64}</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>ffmpeg</artifactId>
|
||||
<version>6.1.1-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-x86_64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>openblas</artifactId>
|
||||
<version>0.3.26-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-x86_64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>4.9.0-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-x86_64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ai.djl.pytorch</groupId>
|
||||
<artifactId>pytorch-native-cpu</artifactId>
|
||||
<classifier>${djl.platform.linux-x86_64}</classifier>
|
||||
<version>2.7.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- linux aarch64 平台 (保留对应平台的配置,可以减小包大小)-->
|
||||
<dependency>
|
||||
@@ -223,42 +168,16 @@
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>ai.djl.pytorch</groupId>-->
|
||||
<!-- <artifactId>pytorch-native-cpu-precxx11</artifactId>-->
|
||||
<!-- <classifier>linux-aarch64</classifier>-->
|
||||
<!-- <version>2.5.1</version>-->
|
||||
<!-- <scope>runtime</scope>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- macOS M系列 平台 (保留对应平台的配置,可以减小包大小)-->
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>${javacv.version}</version>
|
||||
<classifier>${javacv.platform.macosx-arm64}</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>ffmpeg</artifactId>
|
||||
<version>6.1.1-1.5.10</version>
|
||||
<classifier>${javacv.platform.macosx-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>openblas</artifactId>
|
||||
<version>0.3.26-1.5.10</version>
|
||||
<classifier>${javacv.platform.macosx-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>4.9.0-1.5.10</version>
|
||||
<classifier>${javacv.platform.macosx-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ai.djl.pytorch</groupId>
|
||||
<artifactId>pytorch-native-cpu</artifactId>
|
||||
<classifier>${djl.platform.osx-aarch64}</classifier>
|
||||
<version>2.7.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
package smartai.examples.ocr.idcard;
|
||||
|
||||
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.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.IdCardBackInfo;
|
||||
import cn.smartjavaai.ocr.entity.IdCardFrontInfo;
|
||||
import cn.smartjavaai.ocr.entity.IdCardInfo;
|
||||
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.idcard.DefaultIdCardRecognizer;
|
||||
import cn.smartjavaai.ocr.idcard.IdCardPreprocessListener;
|
||||
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 lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* 身份证识别 demo
|
||||
* 使用说明:
|
||||
* 1、先下载 OCR 模型
|
||||
* 2、把下面的模型路径改成你自己的本地路径
|
||||
* 3、把身份证图片路径改成你自己的图片路径
|
||||
* 4、优先运行 recognizeFront() / recognizeBack() 查看结构化结果
|
||||
*
|
||||
* 模型下载地址:https://pan.baidu.com/s/1MLfd73Vjdpnuls9-oqc9uw?pwd=1234 提取码: 1234
|
||||
* 开发文档:http://doc.smartjavaai.cn/
|
||||
* @author dwj
|
||||
*/
|
||||
@Slf4j
|
||||
public class IdCardRecDemo {
|
||||
|
||||
// 设备类型
|
||||
public static DeviceEnum device = DeviceEnum.CPU;
|
||||
|
||||
// 下载模型后,请替换成你自己的模型路径
|
||||
private static final String DET_MODEL_PATH =
|
||||
"/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx";
|
||||
private static final String REC_MODEL_PATH =
|
||||
"/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx";
|
||||
private static final String DIRECTION_MODEL_PATH =
|
||||
"/Users/wenjie/Documents/develop/model/ocr/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx";
|
||||
|
||||
// 这里改成你自己的身份证图片路径
|
||||
private static final String FRONT_IMAGE_PATH = "src/main/resources/idcard/idcard_front1.png";
|
||||
private static final String BACK_IMAGE_PATH = "src/main/resources/idcard/idcard_back1.png";
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
// 修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文本检测模型
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonDetModel getDetectionModel() {
|
||||
OcrDetModelConfig config = new OcrDetModelConfig();
|
||||
// 文本检测模型,切换模型需要同时修改 modelEnum 及 modelPath
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V4_SERVER_DET_MODEL);
|
||||
// 下载模型并替换本地路径
|
||||
config.setDetModelPath(DET_MODEL_PATH);
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取方向检测模型
|
||||
* @return
|
||||
*/
|
||||
public OcrDirectionModel getDirectionModel() {
|
||||
DirectionModelConfig directionModelConfig = new DirectionModelConfig();
|
||||
// 行文本方向检测模型,切换模型需要同时修改 modelEnum 及 modelPath
|
||||
directionModelConfig.setModelEnum(DirectionModelEnum.PP_LCNET_X0_25);
|
||||
// 下载模型并替换本地路径
|
||||
directionModelConfig.setModelPath(DIRECTION_MODEL_PATH);
|
||||
directionModelConfig.setTextDetModel(getDetectionModel());
|
||||
directionModelConfig.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDirectionModel(directionModelConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 OCR 识别模型
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonRecModel getRecModel() {
|
||||
OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
|
||||
// 文本识别模型,切换模型需要同时修改 modelEnum 及 modelPath
|
||||
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL);
|
||||
// 下载模型并替换本地路径
|
||||
recModelConfig.setRecModelPath(REC_MODEL_PATH);
|
||||
recModelConfig.setTextDetModel(getDetectionModel());
|
||||
recModelConfig.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getRecModel(recModelConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建身份证识别器
|
||||
* @return
|
||||
*/
|
||||
public DefaultIdCardRecognizer getIdCardRecognizer() {
|
||||
return new DefaultIdCardRecognizer()
|
||||
.setRecModel(getRecModel())
|
||||
// 身份证识别建议按行返回,方向矫正交给预处理逻辑处理
|
||||
.setRecOptions(new OcrRecOptions(false, true))
|
||||
.setDirectionModel(getDirectionModel())
|
||||
.setEnablePreprocess(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 身份证正面识别
|
||||
* 可识别:姓名、性别、民族、出生日期、住址、身份证号
|
||||
*/
|
||||
@Test
|
||||
public void recognizeFront() {
|
||||
try {
|
||||
DefaultIdCardRecognizer recognizer = getIdCardRecognizer();
|
||||
Image image = SmartImageFactory.getInstance().fromFile(FRONT_IMAGE_PATH);
|
||||
IdCardFrontInfo result = recognizer.recognizeFront(image);
|
||||
log.info("身份证正面识别结果:{}", JsonUtils.toJson(result));
|
||||
} catch (Exception e) {
|
||||
log.error("身份证正面识别失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 身份证反面识别
|
||||
* 可识别:签发机关、有效期开始时间、有效期结束时间
|
||||
*/
|
||||
@Test
|
||||
public void recognizeBack() {
|
||||
try {
|
||||
DefaultIdCardRecognizer recognizer = getIdCardRecognizer();
|
||||
Image image = SmartImageFactory.getInstance().fromFile(BACK_IMAGE_PATH);
|
||||
IdCardBackInfo result = recognizer.recognizeBack(image);
|
||||
log.info("身份证反面识别结果:{}", JsonUtils.toJson(result));
|
||||
} catch (Exception e) {
|
||||
log.error("身份证反面识别失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同时识别身份证正反面
|
||||
*/
|
||||
@Test
|
||||
public void recognizeBoth() {
|
||||
try {
|
||||
DefaultIdCardRecognizer recognizer = getIdCardRecognizer();
|
||||
Image frontImage = SmartImageFactory.getInstance().fromFile(FRONT_IMAGE_PATH);
|
||||
Image backImage = SmartImageFactory.getInstance().fromFile(BACK_IMAGE_PATH);
|
||||
IdCardInfo result = recognizer.recognizeBoth(frontImage, backImage);
|
||||
log.info("身份证正反面识别结果:{}", JsonUtils.toJson(result));
|
||||
} catch (Exception e) {
|
||||
log.error("身份证正反面识别失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 身份证识别并输出调试图片
|
||||
* 适合排查“为什么没识别出来”,不适合生产环境使用
|
||||
*/
|
||||
@Test
|
||||
public void recognizeFrontWithDebugImages() {
|
||||
try {
|
||||
Path debugDir = Paths.get("output/idcard_debug");
|
||||
Files.createDirectories(debugDir);
|
||||
String filePrefix = "idcard_front";
|
||||
DefaultIdCardRecognizer recognizer = getIdCardRecognizer()
|
||||
// .setPreprocessListener(createDebugListener(debugDir, "idcard_front"));
|
||||
.setPreprocessListener(new IdCardPreprocessListener() {
|
||||
@Override
|
||||
public void onAfterDirection(Image image) {
|
||||
saveDebugImage(image, debugDir.resolve(filePrefix + "_step1_direction.png"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterRecognize(Image image, OcrInfo ocrInfo) {
|
||||
saveDebugImage(image, debugDir.resolve(filePrefix + "_step2_ocr_boxes.png"));
|
||||
}
|
||||
});
|
||||
|
||||
Image image = SmartImageFactory.getInstance().fromFile(FRONT_IMAGE_PATH);
|
||||
IdCardFrontInfo result = recognizer.recognizeFront(image);
|
||||
log.info("身份证正面识别结果:{}", JsonUtils.toJson(result));
|
||||
log.info("调试图片已输出到:{}", debugDir.toAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
log.error("身份证调试识别失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveDebugImage(Image image, Path outputPath) {
|
||||
try {
|
||||
ImageUtils.save(image, outputPath, "png");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
examples/ocr-examples/src/main/resources/idcard/idcard_back1.png
Normal file
BIN
examples/ocr-examples/src/main/resources/idcard/idcard_back1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 997 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 418 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.1.1</smartjavaai.version>
|
||||
<smartjavaai.version>1.1.2</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.speech.asr.common.OcrRecognizeDemo</exec.mainClass>
|
||||
|
||||
|
||||
@@ -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.1.1</smartjavaai.version>
|
||||
<smartjavaai.version>1.1.2</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.nlp.translation.TranslationDemo</exec.mainClass>
|
||||
|
||||
|
||||
@@ -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.1.1</smartjavaai.version>
|
||||
<smartjavaai.version>1.1.2</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.vision.ObjectDetectionDemo</exec.mainClass>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user