1、人脸模块:人脸查询支持 向量数据库Milvus 和 SQLite

2、人脸模块:FaceNet人脸模型也支持人脸注册,查询等功能
3、人脸模块:Seetaface6 自动下载人脸库
4、人脸模块:Seetaface6解决依赖库重复下载问题
5、人脸模块:支持手动加载人脸库
6、人脸模块:人脸识别相关功能支持更多参数
This commit is contained in:
dengwenjie
2025-06-09 12:12:10 +08:00
parent ad6706f559
commit bca9462331
67 changed files with 4170 additions and 1438 deletions

View File

@@ -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.15</smartjavaai.version>
<smartjavaai.version>1.0.16</smartjavaai.version>
<!--如果打包运行需要替换成你的main-->
<exec.mainClass>smartai.examples.face.facerec.RetinaFaceDemo</exec.mainClass>

View File

@@ -1,12 +1,23 @@
package smartai.examples.face.facerec;
import cn.smartjavaai.common.entity.DetectionResponse;
import cn.smartjavaai.common.entity.FaceSearchResult;
import cn.smartjavaai.common.entity.R;
import cn.smartjavaai.face.config.FaceExtractConfig;
import cn.smartjavaai.face.config.FaceModelConfig;
import cn.smartjavaai.face.entity.FaceRegisterInfo;
import cn.smartjavaai.face.entity.FaceResult;
import cn.smartjavaai.face.entity.FaceSearchParams;
import cn.smartjavaai.face.enums.FaceModelEnum;
import cn.smartjavaai.face.enums.IdStrategy;
import cn.smartjavaai.face.enums.SimilarityType;
import cn.smartjavaai.face.factory.FaceModelFactory;
import cn.smartjavaai.face.model.facerec.FaceModel;
import cn.smartjavaai.face.vector.config.MilvusConfig;
import cn.smartjavaai.face.vector.config.SQLiteConfig;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.milvus.param.MetricType;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;
@@ -21,7 +32,8 @@ import java.util.List;
/**
* FaceNet人脸算法模型demo
* 支持功能人脸特征提取、人脸比对11
* 支持系统windows 64位linux 64位macOS M系列芯片
* 支持功能人脸特征提取、人脸比对11、人脸比对1N、人脸注册
* @author dwj
* @date 2025/4/11
*/
@@ -29,106 +41,90 @@ import java.util.List;
public class FaceNetDemo {
/**
* 提取人脸特征(支持多人脸)
* 默认使用检测模型:FACENET_FEATURE_EXTRACTION
* 自动裁剪人脸 + 人脸对齐
* 提取人脸特征(多人脸场景)
* 默认使用检测模型:ULTRA_LIGHT_FAST_GENERIC_FACE
* 自动裁剪人脸(处理耗时略有增加)
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
* 2、若人脸朝向不正可开启人脸对齐以提升特征提取准确度。方法参考自定义配置人脸特征提取
*/
@Test
public void testExtractFeatures(){
try {
//人脸特征提取模型
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.FACENET_FEATURE_EXTRACTION);
config.setModelEnum(FaceModelEnum.FACENET_MODEL);
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
List<float[]> faceResult = faceModel.extractFeatures("src/main/resources/kana1.jpg");
log.info("人脸特征提取结果:{}", JSONObject.toJSONString(faceResult));
log.info("人脸特征提取模型加载成功");
//提取图片中所有人脸特征
R<DetectionResponse> faceResult = faceModel.extractFeatures("src/main/resources/face/iu_1.jpg");
if(faceResult.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(faceResult.getData()));
}else{
log.info("人脸特征提取失败:{}", faceResult.getMessage());
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 提取人脸特征(支持多人脸,自定义配置)
* 自动裁剪人脸 + 人脸对齐
* 提取人脸特征(自定义配置)
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
* 2、若人脸朝向不正可开启人脸对齐以提升特征提取准确度。方法参考自定义配置人脸特征提取
*/
@Test
public void testExtractFeaturesWithCustomConfig(){
try {
//人脸模型参数
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.FACENET_FEATURE_EXTRACTION);
config.setModelEnum(FaceModelEnum.FACENET_MODEL);
//人脸特征提取参数
FaceExtractConfig extractConfig = new FaceExtractConfig();
//人脸检测模型配置
extractConfig.setDetectModel(FaceModelFactory.getInstance().getModel(new FaceModelConfig(FaceModelEnum.ULTRA_LIGHT_FAST_GENERIC_FACE)));
//当关闭人脸裁剪时,程序将跳过人脸检测与裁剪流程,直接进行特征提取,适用于输入已为标准人脸区域的图像,有助于提升处理效率。
extractConfig.setCropFace(true);
//开启人脸对齐:适用于人脸不正的场景,开启将提升人脸特征准确度,关闭可以提升性能
extractConfig.setAlign(true);
//人脸检测模型配置指定人脸检测模型ULTRA_LIGHT_FAST_GENERIC_FACE
FaceModelConfig detectModelConfig = new FaceModelConfig(FaceModelEnum.ULTRA_LIGHT_FAST_GENERIC_FACE);
//设置人脸检测置信度阈值
detectModelConfig.setConfidenceThreshold(0.98);
extractConfig.setDetectModel(FaceModelFactory.getInstance().getModel(detectModelConfig));
config.setExtractConfig(extractConfig);
//人脸特征提取模型
//获取人脸模型
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
List<float[]> faceResult = faceModel.extractFeatures("src/main/resources/kana1.jpg");
log.info("人脸特征提取结果:{}", JSONObject.toJSONString(faceResult));
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 提取人脸特征(分数最高人脸)
* 默认使用检测模型FACENET_FEATURE_EXTRACTION
* 自动裁剪人脸 + 人脸对齐
*/
@Test
public void testExtractTopFaceFeature(){
try {
//人脸特征提取模型
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.FACENET_FEATURE_EXTRACTION);
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
float[] faceResult = faceModel.extractTopFaceFeature("src/main/resources/kana1.jpg");
log.info("人脸特征提取结果:{}", JSONObject.toJSONString(faceResult));
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 提取人脸特征(分数最高人脸,自定义配置)
* 自动裁剪人脸 + 人脸对齐
*/
@Test
public void testExtractTopFaceFeatureWithCustomConfig(){
try {
//人脸模型参数
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.FACENET_FEATURE_EXTRACTION);
//人脸特征提取参数
FaceExtractConfig extractConfig = new FaceExtractConfig();
//人脸检测模型配置
extractConfig.setDetectModel(FaceModelFactory.getInstance().getModel(new FaceModelConfig(FaceModelEnum.ULTRA_LIGHT_FAST_GENERIC_FACE)));
config.setExtractConfig(extractConfig);
//人脸特征提取模型
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
float[] faceResult = faceModel.extractTopFaceFeature("src/main/resources/kana1.jpg");
log.info("人脸特征提取结果:{}", JSONObject.toJSONString(faceResult));
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult = faceModel.extractTopFaceFeature("src/main/resources/face/iu_1.jpg");
if(featureResult.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult.getData()));
}else{
log.info("人脸特征提取失败:{}", featureResult.getMessage());
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 人脸比对11-在线模型
* 图片参数:图片路径
* 人脸比对11(基于图像直接比对
* 流程:从输入图像中裁剪分数最高的人脸 → 提取其人脸特征 → 比对两张图片中提取的人脸特征。(接口内自动完成)
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
* 2、若人脸朝向不正可开启人脸对齐以提升特征提取准确度。方法参考自定义配置人脸特征提取
* @throws Exception
*/
@Test
public void featureComparison(){
try {
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.FACENET_FEATURE_EXTRACTION);//人脸模型
config.setModelPath("/Users/wenjie/Documents/develop/face_model/face_feature.pt");
//人脸模型
config.setModelEnum(FaceModelEnum.FACENET_MODEL);
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//自动裁剪人脸并比对人脸特征
float similar = faceModel.featureComparison("src/main/resources/kana1.jpg","src/main/resources/kana2.jpg");
//基于图像直接比对人脸特征
float similar = faceModel.featureComparison("src/main/resources/face/iu_1.jpg","src/main/resources/face/iu_2.jpg");
log.info("相似度:{}", similar);
}
catch (Exception e){
@@ -137,27 +133,239 @@ public class FaceNetDemo {
}
/**
* 人脸比对11- 使用离线模型
* 图片参数:图片路径
* 人脸比对11(基于特征值比对)
* 流程:从输入图像中裁剪分数最高的人脸 → 提取其人脸特征 → 比对两张图片中提取的人脸特征。
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
* 2、若人脸朝向不正可开启人脸对齐以提升特征提取准确度。方法参考自定义配置人脸特征提取
* @throws Exception
*/
@Test
public void featureComparison2(){
try {
FaceModelConfig config = new FaceModelConfig();
//人脸模型
config.setModelEnum(FaceModelEnum.FACENET_MODEL);
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult1 = faceModel.extractTopFaceFeature("src/main/resources/face/iu_1.jpg");
if(featureResult1.isSuccess()){
log.info("图片1人脸特征提取成功{}", JSONObject.toJSONString(featureResult1.getData()));
}else{
log.info("图片1人脸特征提取失败{}", featureResult1.getMessage());
return;
}
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult2 = faceModel.extractTopFaceFeature("src/main/resources/face/iu_2.jpg");
if(featureResult2.isSuccess()){
log.info("图片2人脸特征提取成功{}", JSONObject.toJSONString(featureResult2.getData()));
}else{
log.info("图片2人脸特征提取失败{}", featureResult2.getMessage());
return;
}
//计算相似度
float similar = faceModel.calculSimilar(featureResult1.getData(), featureResult2.getData());
log.info("相似度:{}", similar);
}
catch (Exception e){
e.printStackTrace();
}
}
/**
* 人脸注册 + 人脸更新 + 人脸查询 + 人脸删除使用向量数据库Milvus
* 流程:从输入图像中裁剪分数最高的人脸 → 提取其人脸特征 → 注册人脸
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
* 2、若人脸朝向不正可开启人脸对齐以提升特征提取准确度。方法参考自定义配置人脸特征提取
* @throws Exception
*/
@Test
public void searchFace(){
try {
FaceModelConfig config = new FaceModelConfig();
//人脸模型
config.setModelEnum(FaceModelEnum.FACENET_MODEL);
//初始化向量数据库Milvus数据库配置
MilvusConfig vectorDBConfig = new MilvusConfig();
vectorDBConfig.setHost("127.0.0.1");
vectorDBConfig.setPort(19530);
//vectorDBConfig.setCollectionName("face5");
//ID策略自动生成
vectorDBConfig.setIdStrategy(IdStrategy.AUTO);
//索引类型:内积 (Inner Product) 不建议修改
//vectorDBConfig.setMetricType(MetricType.IP);
config.setVectorDBConfig(vectorDBConfig);
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//等待加载人脸库结束
while (!faceModel.isLoadFaceCompleted()){
Thread.sleep(100);
}
log.info("====================人脸注册==========================");
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult = faceModel.extractTopFaceFeature("src/main/resources/face/iu_1.jpg");
if(featureResult.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult.getData()));
}else{
log.info("人脸特征提取失败:{}", featureResult.getMessage());
return;
}
//人脸注册信息
FaceRegisterInfo faceRegisterInfo = new FaceRegisterInfo();
//设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
JSONObject metadataJson = new JSONObject();
metadataJson.put("name", "iu");
metadataJson.put("age", "25");
faceRegisterInfo.setMetadata(metadataJson.toJSONString());
//人脸注册返回人脸库ID
R<String> registerResult = faceModel.register(faceRegisterInfo, featureResult.getData());
if(registerResult.isSuccess()){
log.info("注册成功ID-{}", registerResult.getData());
}else{
log.info("注册失败:{}", registerResult.getMessage());
}
/*log.info("====================人脸更新==========================");
//更新人脸 只支持自定义IDvectorDBConfig.setIdStrategy(IdStrategy.CUSTOM);
FaceRegisterInfo updateInfo = new FaceRegisterInfo();
//设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
JSONObject metadataJsonUpdate = new JSONObject();
metadataJsonUpdate.put("name", "iu_update");
metadataJsonUpdate.put("age", "25");
updateInfo.setMetadata(metadataJsonUpdate.toJSONString());
//更新必须设置ID,只有
updateInfo.setId(registerResult.getData());
faceModel.upsertFace(updateInfo, "src/main/resources/face/iu_2.jpg");
log.info("更新人脸成功");*/
log.info("====================人脸查询==========================");
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult2 = faceModel.extractTopFaceFeature("src/main/resources/face/iu_3.jpg");
if(featureResult2.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult2.getData()));
}else{
log.info("人脸特征提取失败:{}", featureResult2.getMessage());
return;
}
FaceSearchParams faceSearchParams = new FaceSearchParams();
faceSearchParams.setTopK(1);
faceSearchParams.setThreshold(0.8f);
List<FaceSearchResult> faceSearchResults = faceModel.search(featureResult2.getData(), faceSearchParams);
// R<DetectionResponse> faceSearchResults = faceModel.search("src/main/resources/face/iu_3.jpg", faceSearchParams);
log.info("人脸查询结果:{}", JSONArray.toJSONString(faceSearchResults));
log.info("====================人脸删除==========================");
faceModel.removeRegister(registerResult.getData());
log.info("人脸删除成功");
}
catch (Exception e){
e.printStackTrace();
}
}
/**
* 人脸注册 + 人脸更新 + 人脸查询 + 人脸删除使用轻量数据库SQLite
* 流程:从输入图像中裁剪分数最高的人脸 → 提取其人脸特征 → 注册人脸
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
* 2、若人脸朝向不正可开启人脸对齐以提升特征提取准确度。方法参考自定义配置人脸特征提取
* @throws Exception
*/
@Test
public void searchFace2(){
try {
FaceModelConfig config = new FaceModelConfig();
//人脸模型
config.setModelEnum(FaceModelEnum.FACENET_MODEL);
//初始化向量数据库Milvus数据库配置
SQLiteConfig vectorDBConfig = new SQLiteConfig();
vectorDBConfig.setDbPath("/Users/wenjie/Downloads/face.db");
vectorDBConfig.setSimilarityType(SimilarityType.IP);
config.setVectorDBConfig(vectorDBConfig);
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//等待加载人脸库结束
while (!faceModel.isLoadFaceCompleted()){
Thread.sleep(100);
}
log.info("====================人脸注册==========================");
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult = faceModel.extractTopFaceFeature("src/main/resources/face/iu_1.jpg");
if(featureResult.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult.getData()));
}else{
log.info("人脸特征提取失败:{}", featureResult.getMessage());
return;
}
//人脸注册信息
FaceRegisterInfo faceRegisterInfo = new FaceRegisterInfo();
//设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
JSONObject metadataJson = new JSONObject();
metadataJson.put("name", "iu");
metadataJson.put("age", "25");
faceRegisterInfo.setMetadata(metadataJson.toJSONString());
//可自定义 ID若未设置则自动生成。
//faceRegisterInfo.setId("00001");
//人脸注册返回人脸库ID
R<String> registerResult = faceModel.register(faceRegisterInfo, featureResult.getData());
if(registerResult.isSuccess()){
log.info("注册成功ID-{}", registerResult.getData());
}else{
log.info("注册失败:{}", registerResult.getMessage());
}
log.info("====================人脸更新==========================");
FaceRegisterInfo updateInfo = new FaceRegisterInfo();
//设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
JSONObject metadataJsonUpdate = new JSONObject();
metadataJsonUpdate.put("name", "iu_update");
metadataJsonUpdate.put("age", "25");
updateInfo.setMetadata(metadataJsonUpdate.toJSONString());
//更新必须设置ID,只有
updateInfo.setId(registerResult.getData());
faceModel.upsertFace(updateInfo, "src/main/resources/face/iu_2.jpg");
log.info("更新人脸成功");
log.info("====================人脸查询==========================");
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult2 = faceModel.extractTopFaceFeature("src/main/resources/face/iu_3.jpg");
if(featureResult2.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult2.getData()));
}else{
log.info("人脸特征提取失败:{}", featureResult2.getMessage());
return;
}
FaceSearchParams faceSearchParams = new FaceSearchParams();
faceSearchParams.setTopK(1);
faceSearchParams.setThreshold(0.8f);
List<FaceSearchResult> faceSearchResults = faceModel.search(featureResult2.getData(), faceSearchParams);
log.info("人脸查询结果:{}", JSONArray.toJSONString(faceSearchResults));
log.info("====================人脸删除==========================");
faceModel.removeRegister(registerResult.getData());
log.info("人脸删除成功");
}
catch (Exception e){
e.printStackTrace();
}
}
/**
* 使用离线模型
* @throws Exception
*/
@Test
public void featureComparisonOffline(){
try {
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.FACENET_FEATURE_EXTRACTION);//人脸模型
config.setModelEnum(FaceModelEnum.FACENET_MODEL);//人脸模型
//设置人脸识别模型文件路径,请根据实际情况替换为本地模型文件的绝对路径
config.setModelPath("/Users/xxx/Documents/develop/face_model/face_feature.pt");
//人脸特征提取参数
FaceExtractConfig extractConfig = new FaceExtractConfig();
FaceModelConfig detectModelConfig = new FaceModelConfig(FaceModelEnum.ULTRA_LIGHT_FAST_GENERIC_FACE);
//设置人脸检测模型文件路径,请根据实际情况替换为本地模型文件的绝对路径
detectModelConfig.setModelPath("/Users/xxx/Documents/develop/face_model/ultranet.pt");
//人脸检测模型配置
extractConfig.setDetectModel(FaceModelFactory.getInstance().getModel(detectModelConfig));
config.setExtractConfig(extractConfig);
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//自动裁剪人脸并比对人脸特征
float similar = faceModel.featureComparison("src/main/resources/kana1.jpg","src/main/resources/kana2.jpg");
log.info("相似度:{}", similar);
}
catch (Exception e){
e.printStackTrace();

View File

@@ -1,12 +1,24 @@
package smartai.examples.face.facerec;
import cn.smartjavaai.common.entity.DetectionResponse;
import cn.smartjavaai.common.entity.FaceSearchResult;
import cn.smartjavaai.common.entity.R;
import cn.smartjavaai.face.config.FaceExtractConfig;
import cn.smartjavaai.face.config.FaceModelConfig;
import cn.smartjavaai.face.entity.FaceRegisterInfo;
import cn.smartjavaai.face.entity.FaceResult;
import cn.smartjavaai.face.entity.FaceSearchParams;
import cn.smartjavaai.face.enums.FaceModelEnum;
import cn.smartjavaai.face.enums.IdStrategy;
import cn.smartjavaai.face.enums.SimilarityType;
import cn.smartjavaai.face.factory.FaceModelFactory;
import cn.smartjavaai.face.model.facerec.FaceModel;
import cn.smartjavaai.face.utils.SimilarityUtil;
import cn.smartjavaai.face.vector.config.MilvusConfig;
import cn.smartjavaai.face.vector.config.SQLiteConfig;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.milvus.param.MetricType;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;
@@ -21,7 +33,7 @@ import java.util.List;
/**
* SeetaFace6人脸算法模型demo
* 支持系统windows 64位
* 支持系统windows 64位linux 64位
* 支持功能人脸检测、人脸特征提取、人脸比对11、人脸比对1N、人脸注册
* @author dwj
* @date 2025/4/11
@@ -31,84 +43,56 @@ public class SeetaFace6Demo {
/**
* 人脸检测(自定义模型参数)
* 图片参数:图片路径
*/
@Test
public void testFaceDetectCustomConfig(){
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);//人脸模型
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
DetectionResponse detectedResult = faceModel.detect("src/main/resources/largest_selfie.jpg");
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectedResult));
}
/**
* 人脸检测并绘制人脸框
*/
@Test
public void testFaceDetectAndDraw(){
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);//人脸模型
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
faceModel.detectAndDraw("src/main/resources/largest_selfie.jpg","output/largest_selfie_detected.png");
}
/**
* 人脸检测并绘制人脸框,返回BufferedImage
*
*/
@Test
public void testFaceDetectAndDraw2(){
try {
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);//人脸模型
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
BufferedImage image = null;
String imagePath = "src/main/resources/largest_selfie.jpg";
image = ImageIO.read(new File(Paths.get(imagePath).toAbsolutePath().toString()));
//可以根据后续业务场景使用detectedImage
BufferedImage detectedImage = faceModel.detectAndDraw(image);
Assert.assertNotNull("detectedImage null", detectedImage);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 提取人脸特征(支持多人脸)
* 自动裁剪人脸 + 人脸对齐
* 提取人脸特征(多人脸场景)
* 默认使用SEETA_FACE6_MODEL自己的检测模型
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
*/
@Test
public void testExtractFeatures(){
try {
FaceModel faceModel = FaceModelFactory.getInstance().getModel(new FaceModelConfig(FaceModelEnum.SEETA_FACE6_MODEL,
"C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models"));
List<float[]> faceResult = faceModel.extractFeatures("src/main/resources/kana1.jpg");
log.info("人脸特征提取结果:{}", JSONObject.toJSONString(faceResult));
//人脸特征提取模型
FaceModelConfig config = new FaceModelConfig();
//指定模型
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);
//指定模型路径:请根据实际情况替换为本地模型文件的绝对路径(模型下载地址请查看文档)
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//提取图片中所有人脸特征
R<DetectionResponse> faceResult = faceModel.extractFeatures("src/main/resources/face/iu_1.jpg");
if(faceResult.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(faceResult.getData()));
}else{
log.info("人脸特征提取失败:{}", faceResult.getMessage());
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 提取人脸特征(分数最高人脸)
* 自动裁剪人脸 + 人脸对齐
* 提取人脸特征(只提取图片中分数最高人脸特征)
* 默认使用SEETA_FACE6_MODEL自己的检测模型
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
*/
@Test
public void testExtractTopFaceFeature(){
public void testExtractFeatures2(){
try {
FaceModel faceModel = FaceModelFactory.getInstance().getModel(new FaceModelConfig(FaceModelEnum.SEETA_FACE6_MODEL,
"C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models"));
float[] faceResult = faceModel.extractTopFaceFeature("src/main/resources/kana1.jpg");
log.info("人脸特征提取结果:{}", JSONObject.toJSONString(faceResult));
//人脸特征提取模型
FaceModelConfig config = new FaceModelConfig();
//指定模型
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);
//指定模型路径:请根据实际情况替换为本地模型文件的绝对路径(模型下载地址请查看文档)
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//提取图片中检测分数最高人脸特征
R<float[]> faceResult = faceModel.extractTopFaceFeature("src/main/resources/face/iu_1.jpg");
if(faceResult.isSuccess()){
log.info("人脸特征提取成功:{}", faceResult.getData());
}else{
log.info("人脸特征提取失败:{}", faceResult.getMessage());
}
}catch (Exception e){
e.printStackTrace();
}
@@ -117,20 +101,66 @@ public class SeetaFace6Demo {
/**
* 人脸比对11
* 图片参数:图片路径
* 人脸比对11(基于图像直接比对
* 流程:从输入图像中裁剪分数最高的人脸 → 提取其人脸特征 → 比对两张图片中提取的人脸特征。(接口内自动完成)
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
* @throws Exception
*/
@Test
public void featureComparison(){
try {
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);//人脸模型
//指定模型
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);
//指定模型路径:请根据实际情况替换为本地模型文件的绝对路径(模型下载地址请查看文档)
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//自动裁剪人脸并比对人脸特征
float similar = faceModel.featureComparison("src/main/resources/kana1.jpg","src/main/resources/kana2.jpg");
//基于图像直接比对人脸特征
float similar = faceModel.featureComparison("src/main/resources/face/iu_1.jpg","src/main/resources/face/iu_2.jpg");
log.info("相似度:{}", similar);
}
catch (Exception e){
e.printStackTrace();
}
}
/**
* 人脸比对11基于特征值比对
* 流程:从输入图像中裁剪分数最高的人脸 → 提取其人脸特征 → 比对两张图片中提取的人脸特征。
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
* @throws Exception
*/
@Test
public void featureComparison2(){
try {
FaceModelConfig config = new FaceModelConfig();
//指定模型
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);
//指定模型路径:请根据实际情况替换为本地模型文件的绝对路径(模型下载地址请查看文档)
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult1 = faceModel.extractTopFaceFeature("src/main/resources/face/iu_1.jpg");
if(featureResult1.isSuccess()){
log.info("图片1人脸特征提取成功{}", JSONObject.toJSONString(featureResult1.getData()));
}else{
log.info("图片1人脸特征提取失败{}", featureResult1.getMessage());
return;
}
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult2 = faceModel.extractTopFaceFeature("src/main/resources/face/iu_2.jpg");
if(featureResult2.isSuccess()){
log.info("图片2人脸特征提取成功{}", JSONObject.toJSONString(featureResult2.getData()));
}else{
log.info("图片2人脸特征提取失败{}", featureResult2.getMessage());
return;
}
//计算相似度
float similar = faceModel.calculSimilar(featureResult1.getData(), featureResult2.getData());
log.info("相似度:{}", similar);
}
catch (Exception e){
@@ -140,81 +170,90 @@ public class SeetaFace6Demo {
/**
* 人脸比对11
* 先特征提取,后比对人脸特征
* 提取人脸特征图片参数:图片路径
*/
@Test
public void featureExtractionAndCompare(){
try {
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);//人脸模型
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//提取图像中最大人脸的特征
float[] feature1 = faceModel.extractTopFaceFeature("src/main/resources/kana1.jpg");
float[] feature2 = faceModel.extractTopFaceFeature("src/main/resources/kana2.jpg");
if(feature1 != null && feature2 != null){
float similar = faceModel.calculSimilar(feature1, feature2);
log.info("相似度:{}", similar);
}else{
log.warn("人脸特征提取失败");
}
}
catch (Exception e){
e.printStackTrace();
}
}
/**
* 注册人脸
* 图片参数:图片路径
*/
@Test
public void registerFace(){
try {
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);//人脸模型
//人脸库路径,从项目中 db/faces-data.db下载到本地
config.setFaceDbPath("C:/Users/Administrator/Downloads/faces-data.db");
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//等待人脸库加载完毕
Thread.sleep(1000);
//注册kana1人脸参数key建议设置为人名
boolean isSuccss = faceModel.register("kana1","src/main/resources/kana1.jpg");
log.info("注册结果:{}", isSuccss);
}
catch (Exception e){
e.printStackTrace();
}
}
/**
* 搜索人脸1N
* 图片参数:图片路径
* 注意事项:请先注册人脸
* 人脸注册 + 人脸更新 + 人脸查询 + 人脸删除使用向量数据库Milvus
* 流程:从输入图像中裁剪分数最高的人脸 → 提取其人脸特征 → 注册人脸
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
* 2、若人脸朝向较正可关闭人脸对齐以提升性能。方法参考自定义配置人脸特征提取
* @throws Exception
*/
@Test
public void searchFace(){
try {
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);//人脸模型
//人脸库路径,从项目中 db/faces-data.db下载到本地
config.setFaceDbPath("C:/Users/Administrator/Downloads/faces-data.db");
//人脸模型
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
//初始化向量数据库Milvus数据库配置
MilvusConfig vectorDBConfig = new MilvusConfig();
vectorDBConfig.setHost("127.0.0.1");
vectorDBConfig.setPort(19530);
//vectorDBConfig.setCollectionName("face10");
//ID策略自动生成
vectorDBConfig.setIdStrategy(IdStrategy.AUTO);
//索引类型:内积 (Inner Product) 不建议修改
vectorDBConfig.setMetricType(MetricType.COSINE);
config.setVectorDBConfig(vectorDBConfig);
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//等待人脸库加载完毕
Thread.sleep(1000);
FaceResult faceResult = faceModel.search("src/main/resources/kana1.jpg");
if(faceResult != null){
log.info("查询到人脸:{}", faceResult.toString());
}else{
log.info("未查询到人脸");
//等待加载人脸库结束
while (!faceModel.isLoadFaceCompleted()) {
Thread.sleep(50); // 避免 CPU 占用过高
}
log.info("====================人脸注册==========================");
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult = faceModel.extractTopFaceFeature("src/main/resources/face/iu_1.jpg");
if(featureResult.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult.getData()));
}else{
log.info("人脸特征提取失败:{}", featureResult.getMessage());
return;
}
//人脸注册信息
FaceRegisterInfo faceRegisterInfo = new FaceRegisterInfo();
//设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
JSONObject metadataJson = new JSONObject();
metadataJson.put("name", "iu");
metadataJson.put("age", "25");
faceRegisterInfo.setMetadata(metadataJson.toJSONString());
//人脸注册返回人脸库ID
R<String> registerResult = faceModel.register(faceRegisterInfo, featureResult.getData());
if(registerResult.isSuccess()){
log.info("注册成功ID-{}", registerResult.getData());
}else{
log.info("注册失败:{}", registerResult.getMessage());
}
/*log.info("====================人脸更新==========================");
//更新人脸 只支持自定义IDvectorDBConfig.setIdStrategy(IdStrategy.CUSTOM);
FaceRegisterInfo updateInfo = new FaceRegisterInfo();
//设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
JSONObject metadataJsonUpdate = new JSONObject();
metadataJsonUpdate.put("name", "iu_update");
metadataJsonUpdate.put("age", "25");
updateInfo.setMetadata(metadataJsonUpdate.toJSONString());
//更新必须设置ID,只有
updateInfo.setId(registerResult.getData());
faceModel.upsertFace(updateInfo, "src/main/resources/face/iu_2.jpg");
log.info("更新人脸成功");*/
log.info("====================人脸查询==========================");
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult2 = faceModel.extractTopFaceFeature("src/main/resources/face/iu_2.jpg");
if(featureResult2.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult2.getData()));
}else{
log.info("人脸特征提取失败:{}", featureResult2.getMessage());
return;
}
FaceSearchParams faceSearchParams = new FaceSearchParams();
faceSearchParams.setTopK(1);
faceSearchParams.setThreshold(0.8f);
List<FaceSearchResult> faceSearchResults = faceModel.search(featureResult2.getData(), faceSearchParams);
log.info("人脸查询结果:{}", JSONArray.toJSONString(faceSearchResults));
log.info("====================人脸删除==========================");
faceModel.removeRegister(registerResult.getData());
log.info("人脸删除成功");
}
catch (Exception e){
e.printStackTrace();
@@ -222,25 +261,80 @@ public class SeetaFace6Demo {
}
/**
* 删除已注册人脸
* 注意事项:请先注册人脸
* 人脸注册 + 人脸更新 + 人脸查询 + 人脸删除使用轻量数据库SQLite
* 流程:从输入图像中裁剪分数最高的人脸 → 提取其人脸特征 → 注册人脸
* 注意事项:
* 1、首次调用接口可能会较慢。只要不关闭程序后续调用会明显加快。若每次重启程序则每次首次调用都将重新加载仍会较慢。
* 2、若人脸朝向较正可关闭人脸对齐以提升性能。方法参考自定义配置人脸特征提取
* @throws Exception
*/
@Test
public void removeRegisterFace(){
public void searchFace2(){
try {
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);//人脸模型
//人脸库路径,从项目中 db/faces-data.db下载到本地
config.setFaceDbPath("C:/Users/Administrator/Downloads/faces-data.db");
//人脸模型
config.setModelEnum(FaceModelEnum.SEETA_FACE6_MODEL);
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
//使用轻量数据库SQLite
config.setVectorDBConfig(new SQLiteConfig());
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
//等待人脸库加载完毕
Thread.sleep(1000);
//使用注册人脸时的key值删除可一次性删除单个
long num = faceModel.removeRegister("kana1");
//删除全部人脸
//long num = currentAlgorithm.clearFace();
log.info("删除成功数量:" + num);
log.info("====================人脸注册==========================");
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult = faceModel.extractTopFaceFeature("src/main/resources/face/iu_1.jpg");
if(featureResult.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult.getData()));
}else{
log.info("人脸特征提取失败:{}", featureResult.getMessage());
return;
}
//人脸注册信息
FaceRegisterInfo faceRegisterInfo = new FaceRegisterInfo();
//设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
JSONObject metadataJson = new JSONObject();
metadataJson.put("name", "iu");
metadataJson.put("age", "25");
faceRegisterInfo.setMetadata(metadataJson.toJSONString());
//可自定义 ID若未设置则自动生成。
//faceRegisterInfo.setId("00001");
//人脸注册返回人脸库ID
R<String> registerResult = faceModel.register(faceRegisterInfo, featureResult.getData());
if(registerResult.isSuccess()){
log.info("注册成功ID-{}", registerResult.getData());
}else{
log.info("注册失败:{}", registerResult.getMessage());
}
log.info("====================人脸更新==========================");
FaceRegisterInfo updateInfo = new FaceRegisterInfo();
//设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
JSONObject metadataJsonUpdate = new JSONObject();
metadataJsonUpdate.put("name", "iu_update");
metadataJsonUpdate.put("age", "25");
updateInfo.setMetadata(metadataJsonUpdate.toJSONString());
//更新必须设置ID,只有
updateInfo.setId(registerResult.getData());
faceModel.upsertFace(updateInfo, "src/main/resources/face/iu_2.jpg");
log.info("更新人脸成功");
log.info("====================人脸查询==========================");
//特征提取(提取分数最高人脸特征),适用于单人脸场景
R<float[]> featureResult2 = faceModel.extractTopFaceFeature("src/main/resources/face/iu_3.jpg");
if(featureResult2.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult2.getData()));
}else{
log.info("人脸特征提取失败:{}", featureResult2.getMessage());
return;
}
FaceSearchParams faceSearchParams = new FaceSearchParams();
faceSearchParams.setTopK(1);
faceSearchParams.setThreshold(0.62f);
//等待加载人脸库结束
while (!faceModel.isLoadFaceCompleted()) {
Thread.sleep(50); // 避免 CPU 占用过高
}
List<FaceSearchResult> faceSearchResults = faceModel.search(featureResult2.getData(), faceSearchParams);
log.info("人脸查询结果:{}", JSONArray.toJSONString(faceSearchResults));
log.info("====================人脸删除==========================");
faceModel.removeRegister(registerResult.getData());
log.info("人脸删除成功");
}
catch (Exception e){
e.printStackTrace();
@@ -248,4 +342,5 @@ public class SeetaFace6Demo {
}
}

View File

@@ -38,7 +38,7 @@ public class OcrDetectionDemo {
//指定检测模型
config.setModelEnum(CommonDetModelEnum.PADDLEOCR_V5_DET_MODEL);
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
config.setDetModelPath("/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
config.setDetModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
OcrCommonDetModel model = OcrModelFactory.getInstance().getDetModel(config);
List<OcrBox> boxes = model.detect("src/main/resources/ocr_1.jpg");
log.info("OCR检测结果{}", JSONObject.toJSONString(boxes));

View File

@@ -37,11 +37,11 @@ public class OcrDirectionDetDemo {
//指定检测模型
directionModelConfig.setDetModelEnum(CommonDetModelEnum.PADDLEOCR_V5_DET_MODEL);
//指定检测模型位置,需要更改为自己的模型路径(下载地址请查看文档)
directionModelConfig.setDetModelPath("/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
directionModelConfig.setDetModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
//指定文本方向检测模型
directionModelConfig.setModelEnum(DirectionModelEnum.CH_PPOCR_MOBILE_V2_CLS);
//指定文本方向检测模型路径,需要更改为自己的模型路径(下载地址请查看文档)
directionModelConfig.setModelPath("/cls/ch_ppocr_mobile_v2.0_cls.onnx");
directionModelConfig.setModelPath("/Users/wenjie/Documents/develop/ocr模型/ch_ppocr_mobile_v2.0_cls.onnx");
OcrDirectionModel directionModel = OcrModelFactory.getInstance().getDirectionModel(directionModelConfig);
List<OcrItem> itemList = directionModel.detect("src/main/resources/ocr_3.jpg");
log.info("OCR方向检测结果{}", JSONObject.toJSONString(itemList));

View File

@@ -27,8 +27,7 @@ public class OcrRecognizeDemo {
/**
* 文本识别
* 本方法支持旋转角度范围为 -90 到 90 度的文
* 同时兼容印刷体和手写体文字。
* 支持简体中文、繁体中文、英文、日文四种主要语言,以及手写、竖版、拼音、生僻
* 流程:文本检测 -> 文本识别
* 模型需要放在单独文件夹
*/
@@ -38,21 +37,20 @@ public class OcrRecognizeDemo {
//指定检测模型
recModelConfig.setDetModelEnum(CommonDetModelEnum.PADDLEOCR_V5_DET_MODEL);
//指定检测模型位置,需要更改为自己的模型路径(下载地址请查看文档)
recModelConfig.setDetModelPath("/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
recModelConfig.setDetModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
//指定识别模型
recModelConfig.setRecModelEnum(CommonRecModelEnum.PADDLEOCR_V5_REC_MODEL);
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
recModelConfig.setRecModelPath("/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx");
recModelConfig.setRecModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx");
OcrCommonRecModel recModel = OcrModelFactory.getInstance().getRecModel(recModelConfig);
OcrInfo ocrInfo = recModel.recognize("src/main/resources/general_ocr_002.png");
OcrInfo ocrInfo = recModel.recognize("src/main/resources/ocr_1.jpg");
log.info("OCR识别结果{}", JSONObject.toJSONString(ocrInfo));
}
/**
* 文本识别(手写字)
* 本方法支持旋转角度范围为 -90 到 90 度的文
* 同时兼容印刷体和手写体文字。
* 支持简体中文、繁体中文、英文、日文四种主要语言,以及手写、竖版、拼音、生僻
* 流程:文本检测 -> 文本识别
* 模型需要放在单独文件夹
*/
@@ -74,8 +72,8 @@ public class OcrRecognizeDemo {
/**
* 文本识别(带方向矫正)
* 本方法支持任意角度文字识别
* 同时兼容印刷体和手写体文字。
* 支持简体中文、繁体中文、英文、日文四种主要语言,以及手写、竖版、拼音、生僻字
* 本方法支持多角度文字识别
* 流程:文本检测 -> 方向检测 -> 方向矫正 -> 文本识别
* 模型需要放在单独文件夹
*/
@@ -103,8 +101,7 @@ public class OcrRecognizeDemo {
/**
* 文本识别并绘制结果
* 本方法支持旋转角度范围为 -90 到 90 度的文
* 同时兼容印刷体和手写体文字。
* 支持简体中文、繁体中文、英文、日文四种主要语言,以及手写、竖版、拼音、生僻
* 流程:文本检测 -> 文本识别
* 模型需要放在单独文件夹
*/
@@ -114,16 +111,19 @@ public class OcrRecognizeDemo {
//指定检测模型
recModelConfig.setDetModelEnum(CommonDetModelEnum.PADDLEOCR_V5_DET_MODEL);
//指定检测模型位置,需要更改为自己的模型路径(下载地址请查看文档)
recModelConfig.setDetModelPath("/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
recModelConfig.setDetModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
//指定识别模型
recModelConfig.setRecModelEnum(CommonRecModelEnum.PADDLEOCR_V5_REC_MODEL);
//directionModelConfig.setDirectionModelEnum(DirectionModelEnum.CH_PPOCR_MOBILE_V2_CLS);
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
recModelConfig.setRecModelPath("/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx");
//directionModelConfig.setDirectionModelPath("/Users/wenjie/Documents/develop/ocr模型/ch_ppocr_mobile_v2.0_cls.onnx");
recModelConfig.setRecModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx");
//指定方向检测模型
recModelConfig.setDirectionModelEnum(DirectionModelEnum.CH_PPOCR_MOBILE_V2_CLS);
//指定方向模型位置,需要更改为自己的模型路径(下载地址请查看文档)
recModelConfig.setDirectionModelPath("/Users/wenjie/Documents/develop/ocr模型/ch_ppocr_mobile_v2.0_cls.onnx");
OcrCommonRecModel recModel = OcrModelFactory.getInstance().getRecModel(recModelConfig);
int fontSize = 20;
recModel.recognizeAndDraw("src/main/resources/general_ocr_002.png", "output/general_ocr_002_recognized.png", fontSize);
int fontSize = 25;
recModel.recognizeAndDraw("src/main/resources/ocr_4.jpg", "output/ocr_4_recognized.jpg", fontSize);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB