- 新增机器翻译模块:支持 200+ 种语言之间的相互翻译

- 人脸识别模块:修复批量删除人脸数据时的异常问题
- 人脸识别模块:修复人脸检索 Top大于 1 时报异常问题
This commit is contained in:
dengwenjie
2025-06-18 20:05:40 +08:00
parent f7a59cc3aa
commit a6b3655907
24 changed files with 90 additions and 31 deletions

View File

@@ -154,6 +154,19 @@ SmartJavaAI是专为JAVA 开发者打造的一个功能丰富、开箱即用的
</div>
</td>
</tr>
<tr>
<td>
<div align="left">
<p>机器翻译</p>
- 200多种语言互相翻译
</div>
</td>
<td>
<div align="center">
<img src="https://cdn.jsdelivr.net/gh/geekwenjie/SmartJavaAI-Site/images/translate/translate.png" width = "500px"/>
</div>
</td>
</tr>
</table>
</div>
@@ -196,6 +209,8 @@ SmartJavaAI是专为JAVA 开发者打造的一个功能丰富、开箱即用的
- 支持PaddleOCR 3.0模型集成最新PP-OCRv5模型
- 支持任意角度识别,方向校准
- 支持通用文字识别,通用手写字识别
- **机器翻译**
- 集成NLLB-200模型支持200+语言互相翻译
### ⌛ 规划中功能
@@ -241,6 +256,7 @@ SmartJavaAI是专为JAVA 开发者打造的一个功能丰富、开箱即用的
| smartjavaai-face | 人脸功能模块 |
| smartjavaai-objectdetection | 目标检测模块 |
| smartjavaai-ocr | OCR文字识别模块 |
| smartjavaai-translate | 机器翻译模块 |
可以根据需求对每个模块单独引入,也可以通过引入`smartjavaai-all`方式引入所有模块。
@@ -263,7 +279,7 @@ SmartJavaAI是专为JAVA 开发者打造的一个功能丰富、开箱即用的
<dependency>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-all</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
</dependency>
```
### 3、完整示例代码
@@ -274,6 +290,10 @@ SmartJavaAI是专为JAVA 开发者打造的一个功能丰富、开箱即用的
[开发文档](http://doc.smartjavaai.cn)
### 5、模型下载
[模型下载](https://pan.baidu.com/s/1F6QtGrakEgnD1-hkWBfsUg?pwd=1234)
## 🙏 鸣谢
@@ -298,6 +318,11 @@ SmartJavaAI是专为JAVA 开发者打造的一个功能丰富、开箱即用的
## 近期更新日志
## [v1.0.17] - 2025-06-18
- 新增机器翻译模块:支持 200+ 种语言之间的相互翻译
- 人脸识别模块:修复批量删除人脸数据时的异常问题
- 人脸识别模块:修复人脸检索 Top大于 1 时报异常问题
## [v1.0.16] - 2025-06-09
- 人脸模块:人脸查询支持 Milvus 和 SQLite
- 人脸模块FaceNet人脸模型也支持人脸注册查询等功能

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.16</smartjavaai.version>
<smartjavaai.version>1.0.17</smartjavaai.version>
<!--如果打包运行需要替换成你的main-->
<exec.mainClass>smartai.examples.face.facerec.RetinaFaceDemo</exec.mainClass>
@@ -109,6 +109,12 @@
<artifactId>smartjavaai-ocr</artifactId>
</dependency>
<!--翻译模块-->
<dependency>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-translate</artifactId>
</dependency>
<dependency>
<groupId>ai.djl.pytorch</groupId>

View File

@@ -28,6 +28,7 @@ import java.util.List;
/**
* 人脸属性检测demo
* 模型下载地址https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/5/1
*/

View File

@@ -34,6 +34,7 @@ import java.util.List;
* FaceNet人脸算法模型demo
* 支持系统windows 64位linux 64位macOS M系列芯片
* 支持功能人脸特征提取、人脸比对11、人脸比对1N、人脸注册
* 模型下载地址https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/4/11
*/

View File

@@ -12,6 +12,7 @@ import org.junit.Test;
/**
* GPU 人脸检测
* 模型下载地址https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/4/14
*/

View File

@@ -20,6 +20,7 @@ import java.nio.file.Paths;
/**
* UltraLightFastGenericFaceModel 轻量人脸算法模型demo
* 支持功能:人脸检测(不支持人脸特征提取)
* 模型下载地址https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/4/11
*/

View File

@@ -22,6 +22,7 @@ import java.nio.file.Paths;
/**
* RetinaFace人脸算法模型demo
* 支持功能:人脸检测(不支持人脸特征提取)
* 模型下载地址https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/4/11
*/

View File

@@ -35,6 +35,7 @@ import java.util.List;
* SeetaFace6人脸算法模型demo
* 支持系统windows 64位linux 64位
* 支持功能人脸检测、人脸特征提取、人脸比对11、人脸比对1N、人脸注册
* 模型下载地址https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/4/11
*/

View File

@@ -31,6 +31,7 @@ import java.util.List;
/**
* 静态活体检测demo
* 模型下载地址https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/5/1
*/

View File

@@ -40,6 +40,7 @@ import java.util.concurrent.Future;
/**
* 目标检测模型demo
* 支持功能:目标检测
* 模型下载地址https://pan.baidu.com/s/1MeQ0oHGl8hneicUIUVJjbg?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/4/11
*/

View File

@@ -20,6 +20,7 @@ import java.util.List;
/**
* OCR 文本检测 示例
* 模型下载地址https://pan.baidu.com/s/1MLfd73Vjdpnuls9-oqc9uw?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/5/25
*/
@@ -38,7 +39,7 @@ public class OcrDetectionDemo {
//指定检测模型
config.setModelEnum(CommonDetModelEnum.PADDLEOCR_V5_DET_MODEL);
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
config.setDetModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
config.setDetModelPath("/Users/xxx/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

@@ -17,6 +17,7 @@ import java.util.List;
/**
* OCR 文本方向检测 示例
* 模型下载地址https://pan.baidu.com/s/1MLfd73Vjdpnuls9-oqc9uw?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/5/25
*/
@@ -37,11 +38,11 @@ public class OcrDirectionDetDemo {
//指定检测模型
directionModelConfig.setDetModelEnum(CommonDetModelEnum.PADDLEOCR_V5_DET_MODEL);
//指定检测模型位置,需要更改为自己的模型路径(下载地址请查看文档)
directionModelConfig.setDetModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
directionModelConfig.setDetModelPath("/Users/xxx/Documents/develop/ocr模型/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
//指定文本方向检测模型
directionModelConfig.setModelEnum(DirectionModelEnum.CH_PPOCR_MOBILE_V2_CLS);
//指定文本方向检测模型路径,需要更改为自己的模型路径(下载地址请查看文档)
directionModelConfig.setModelPath("/Users/wenjie/Documents/develop/ocr模型/ch_ppocr_mobile_v2.0_cls.onnx");
directionModelConfig.setModelPath("/Users/xxx/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

@@ -18,6 +18,7 @@ import java.util.List;
/**
* OCR 文本识别 示例
* 模型下载地址https://pan.baidu.com/s/1MLfd73Vjdpnuls9-oqc9uw?pwd=1234 提取码: 1234
* @author dwj
* @date 2025/5/25
*/
@@ -37,11 +38,11 @@ public class OcrRecognizeDemo {
//指定检测模型
recModelConfig.setDetModelEnum(CommonDetModelEnum.PADDLEOCR_V5_DET_MODEL);
//指定检测模型位置,需要更改为自己的模型路径(下载地址请查看文档)
recModelConfig.setDetModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
recModelConfig.setDetModelPath("/Users/xxx/Documents/develop/ocr模型/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
//指定识别模型
recModelConfig.setRecModelEnum(CommonRecModelEnum.PADDLEOCR_V5_REC_MODEL);
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
recModelConfig.setRecModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx");
recModelConfig.setRecModelPath("/Users/xxx/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/ocr_1.jpg");
log.info("OCR识别结果{}", JSONObject.toJSONString(ocrInfo));
@@ -111,16 +112,16 @@ public class OcrRecognizeDemo {
//指定检测模型
recModelConfig.setDetModelEnum(CommonDetModelEnum.PADDLEOCR_V5_DET_MODEL);
//指定检测模型位置,需要更改为自己的模型路径(下载地址请查看文档)
recModelConfig.setDetModelPath("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
recModelConfig.setDetModelPath("/Users/xxx/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("/Users/wenjie/Documents/develop/ocr模型/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx");
recModelConfig.setRecModelPath("/Users/xxx/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");
recModelConfig.setDirectionModelPath("/Users/xxx/Documents/develop/ocr模型/ch_ppocr_mobile_v2.0_cls.onnx");
OcrCommonRecModel recModel = OcrModelFactory.getInstance().getRecModel(recModelConfig);
int fontSize = 25;
recModel.recognizeAndDraw("src/main/resources/ocr_4.jpg", "output/ocr_4_recognized.jpg", fontSize);

View File

@@ -7,7 +7,7 @@
<name>SmartJavaAI</name>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-parent</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
<packaging>pom</packaging>
<description>SmartJavaAI</description>
<modules>

View File

@@ -6,11 +6,11 @@
<parent>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-parent</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
</parent>
<artifactId>smartjavaai-all</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
<name>${project.artifactId}</name>
<description>SmartJavaAI</description>
<url>https://github.com/geekwenjie/SmartJavaAI</url>
@@ -49,6 +49,12 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-translate</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 引用所有平台包 -->
<!-- <dependency>-->
<!-- <groupId>org.bytedeco</groupId>-->

View File

@@ -6,10 +6,10 @@
<parent>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-parent</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
</parent>
<version>1.0.16</version>
<version>1.0.17</version>
<artifactId>smartjavaai-bom</artifactId>
<name>smartjavaai-bom</name>
<description>统一版本管理的 BOM 包,同时支持 import 和全量依赖</description>
@@ -38,6 +38,11 @@
<artifactId>smartjavaai-ocr</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-translate</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-parent</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
</parent>
<name>smartjavaai-common</name>

View File

@@ -6,11 +6,11 @@
<parent>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-parent</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
</parent>
<artifactId>smartjavaai-face</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
<name>smartjavaai-face</name>
<description>SmartJavaAI</description>
<url>https://github.com/geekwenjie/SmartJavaAI</url>

View File

@@ -397,11 +397,18 @@ public class MilvusClient implements VectorDBClient {
// 构建IN表达式: id in ["id1", "id2", ...]
StringBuilder expr = new StringBuilder(VectorDBConstants.FieldNames.ID_FIELD + " in [");
for (int i = 0; i < ids.size(); i++) {
expr.append(ids.get(i)); // 不加引号
if(config.getIdStrategy() == IdStrategy.AUTO){
expr.append(ids.get(i)); // 不加引号
}else{
expr.append("'" + ids.get(i) + "'"); // 不加引号
}
if (i < ids.size() - 1) {
expr.append(", ");
}
}
expr.append("]");
DeleteParam deleteParam = DeleteParam.newBuilder()
.withCollectionName(collectionName)
@@ -453,7 +460,6 @@ public class MilvusClient implements VectorDBClient {
// 3. 获取字段数据FieldData
List<SearchResultsWrapper.IDScore> scores = wrapper.getIDScore(0); // 默认只有一条 query 向量
List<FaceSearchResult> finalResults = new ArrayList<>();
for (int i = 0; i < scores.size(); i++) {
SearchResultsWrapper.IDScore score = scores.get(i);
@@ -464,9 +470,9 @@ public class MilvusClient implements VectorDBClient {
}
if (similarity >= faceSearchParams.getThreshold()) {
// 获取 Metadata
String metadata = wrapper.getFieldData(VectorDBConstants.FieldNames.METADATA_FIELD, i).get(0).toString();
String metadata = wrapper.getFieldData(VectorDBConstants.FieldNames.METADATA_FIELD, 0).get(i).toString();
// 获取 ID
String id = wrapper.getFieldData(VectorDBConstants.FieldNames.ID_FIELD, i).get(0).toString();
String id = wrapper.getFieldData(VectorDBConstants.FieldNames.ID_FIELD, 0).get(i).toString();
finalResults.add(new FaceSearchResult(id, similarity, metadata));
}
}

View File

@@ -6,11 +6,11 @@
<parent>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-parent</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
</parent>
<artifactId>smartjavaai-objectdetection</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
<name>smartjavaai-objectdetection</name>
<description>SmartJavaAI</description>
<url>https://github.com/geekwenjie/SmartJavaAI</url>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-parent</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
</parent>
<artifactId>smartjavaai-ocr</artifactId>
@@ -20,7 +20,7 @@
</dependency>
</dependencies>
<version>1.0.16</version>
<version>1.0.17</version>
<name>smartjavaai-ocr</name>
<description>SmartJavaAI</description>
<url>https://github.com/geekwenjie/SmartJavaAI</url>

View File

@@ -20,8 +20,8 @@
</dependency>
</dependencies>
<version>1.0.16</version>
<name>smartjavaai-ocr</name>
<version>1.0.17</version>
<name>smartjavaai-translate</name>
<description>SmartJavaAI</description>
<url>https://github.com/geekwenjie/SmartJavaAI</url>
<licenses>

View File

@@ -95,7 +95,7 @@ public class TranslationModelFactory {
// 初始化默认算法
static {
registerCommonDetModel("NLLB_MODEL", NllbModel.class);
log.info("缓存目录:{}", Config.getCachePath());
log.debug("缓存目录:{}", Config.getCachePath());
}
}

View File

@@ -91,8 +91,8 @@ public class NllbModel implements TranslationModel{
tokenizer = HuggingFaceTokenizer.newInstance(tokenizerPath);
//初始化searchConfig
this.searchConfig = new NllbSearchConfig();
log.info("当前设备: " + nllbModel.getNDManager().getDevice());
log.info("当前引擎: " + Engine.getInstance().getEngineName());
log.debug("当前设备: " + nllbModel.getNDManager().getDevice());
log.debug("当前引擎: " + Engine.getInstance().getEngineName());
} catch (IOException | ModelNotFoundException | MalformedModelException e) {
throw new TranslationException("模型加载失败", e);
}