diff --git a/README.md b/README.md
index 8694a68..dd3d11a 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,22 @@
SmartJavaAI是专为JAVA 开发者打造的一个功能丰富、开箱即用的 JAVA AI算法工具包,致力于帮助JAVA开发者零门槛使用各种AI算法模型,开发者无需深入了解底层实现,即可轻松在 Java 代码中调用人脸识别、目标检测、OCR 等功能。底层支持包括基于 DJL (Deep Java Library) 封装的深度学习模型,以及通过 JNI 接入的 C++/Python 算法,兼容多种主流深度学习框架如 PyTorch、TensorFlow、ONNX、Paddle 等,屏蔽复杂的模型部署与调用细节,开发者无需了解 AI 底层实现即可直接在 Java 项目中集成使用,后续将持续扩展更多算法,目标是构建一个“像 Hutool 一样简单易用”的 JAVA AI 通用工具箱
+
+## 📱 SmartJavaAI Android 商业版
+
+**SmartJavaAI 现已支持 Android 移动端!**
+
+如果您有移动端离线人脸识别的需求,我们推出了基于 SmartJavaAI 的 Android SDK 及演示 APP。
+
+* 🚀 **核心能力**:毫秒级离线人脸检测、比对、注册与 1:N 搜索。
+* 📦 **开箱即用**:提供标准 SDK 接口与完整 Demo APK。
+* 💼 **商业授权**:Android 版本为商业授权版本。
+
+👉 **[点击查看 Android 版演示截图、APK 下载及获取方式](./android.md)**
+
+
+
+
## 🚀 能力展示
@@ -498,7 +514,7 @@ SmartJavaAI是专为JAVA 开发者打造的一个功能丰富、开箱即用的
cn.smartjavaai
all
- 1.1.0
+ 1.1.1
```
diff --git a/all/pom.xml b/all/pom.xml
index 63c7d14..bb154f0 100644
--- a/all/pom.xml
+++ b/all/pom.xml
@@ -6,11 +6,11 @@
cn.smartjavaai
smartjavaai-parent
- 1.1.0
+ 1.1.1
all
-
1.1.0
+
1.1.1
${project.artifactId}
SmartJavaAI
https://github.com/geekwenjie/SmartJavaAI
diff --git a/android.md b/android.md
new file mode 100644
index 0000000..d978646
--- /dev/null
+++ b/android.md
@@ -0,0 +1,68 @@
+# SmartJavaAI Android 商业版 (SDK & App)
+
+欢迎关注 SmartJavaAI Android 版本。这是专为移动设备打造的高性能、离线人脸识别解决方案。
+
+## ✨ 核心功能
+
+Android 版本包含以下四大核心模块,支持完全**离线运行**,无需联网:
+
+1. **人脸检测 (Face Detection)**
+2. **人脸注册 (Face Registration)**
+3. **人脸比对 (Face Comparison 1:1)**
+4. **人脸查询 (Face Search 1:N)**
+
+---
+
+## 📸 效果演示
+
+所见即所得,以下是 Demo App 在真机上的运行实拍:
+
+| **人脸检测** | **人脸比对** |
+|:----------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------:|
+|

|

|
+
+---
+
+## 🚀 免费试用申请 (Free Trial)
+
+我们为开发者提供 **3天全功能免费试用 License**,以便您充分评估 SDK 的性能与效果。请按照以下步骤获取试用:
+
+### 第一步:下载演示 APK
+* **文件名**:SmartJavaAI_Face_Demo_v1.0.apk
+* **下载地址**:[点击这里下载 APK](https://pan.baidu.com/s/1cJhY9q6HcRiLX7orv6CoXQ?pwd=1234)
+
+### 第二步:邮件申请 License
+请发送邮件至 **775747758@qq.com** 申请试用授权License。
+
+* **邮件标题**:SmartJavaAI Android 试用申请
+* **邮件内容**:
+ * **申请类型**:企业 / 个人
+ * **公司名称/个人姓名**:
+ * **联系电话**:(选填)
+ * **用途简述**:(例如:门禁项目测试)
+
+> 💡 **小贴士**:您可以直接复制上方内容。收到邮件后,我们通常会在 24 小时内将 License 文件回复给您。
+
+### 第三步:激活使用
+下载 APK 并安装后,将邮件附件中的 `秘钥` 粘贴到 App中,即可开启 3 天免费试用。
+
+---
+
+## 🤝 正式商业授权与咨询
+
+试用满意后,如需购买正式商业授权,请联系我们:
+
+* **SDK 形式**:提供标准 AAR/Jar 包,方便集成。
+* **源码支持**:提供完整的 Demo 工程源码。
+
+---
+
+
+
+**咨询微信 (WeChat):[deng775747758]**
+
+*(添加时请备注:android)*
+
+---
+
+[🔙 返回项目主页](./README.md)
diff --git a/bom/pom.xml b/bom/pom.xml
index 815bba0..d4af111 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -6,10 +6,10 @@
cn.smartjavaai
smartjavaai-parent
- 1.1.0
+ 1.1.1
-
1.1.0
+
1.1.1
bom
bom
统一版本管理的 BOM 包,同时支持 import 和全量依赖
diff --git a/common/pom.xml b/common/pom.xml
index e8d4e2c..80a80fd 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -6,7 +6,7 @@
cn.smartjavaai
smartjavaai-parent
- 1.1.0
+ 1.1.1
common
diff --git a/common/src/main/java/cn/smartjavaai/common/cv/SmartImageFactory.java b/common/src/main/java/cn/smartjavaai/common/cv/SmartImageFactory.java
index 2d0a184..6cc513f 100644
--- a/common/src/main/java/cn/smartjavaai/common/cv/SmartImageFactory.java
+++ b/common/src/main/java/cn/smartjavaai/common/cv/SmartImageFactory.java
@@ -24,6 +24,7 @@ import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.file.Path;
@@ -147,6 +148,19 @@ public class SmartImageFactory {
return ImageFactory.getInstance().fromInputStream(inputStream);
}
+ public Image fromUrl(URL url) throws IOException {
+ if (url == null) {
+ throw new IllegalArgumentException("URL 不能为空");
+ }
+ try (InputStream inputStream = url.openStream()) {
+ return ImageFactory.getInstance().fromInputStream(inputStream);
+ }
+ }
+
+ public Image fromUrl(String urlString) throws IOException {
+ return this.fromUrl(new URL(urlString));
+ }
+
}
diff --git a/examples/face-example/Dockerfile b/examples/face-example/Dockerfile
new file mode 100644
index 0000000..45829d4
--- /dev/null
+++ b/examples/face-example/Dockerfile
@@ -0,0 +1,35 @@
+# 使用官方 Ubuntu 22.04 作为基础
+FROM ubuntu:22.04
+
+# 设置工作目录(可选,但推荐)
+WORKDIR /app
+
+# 更新 apt 仓库并安装 OpenJDK 11
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends openjdk-11-jdk && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+
+# (可选) 验证 Java 安装 (可以选择添加你的应用程序,并编译运行,或者只是执行 java -version)
+RUN java -version
+
+# 设置默认的模型路径环境变量
+ENV SMART_MODEL_PATH=/app/models
+
+# 创建该目录
+RUN mkdir -p /app/models
+
+# 挂载
+VOLUME ["/app/models"]
+
+# UTF-8
+ENV LANG=zh_CN.UTF-8
+ENV LC_ALL=zh_CN.UTF-8
+
+
+# 声明服务运行在8080端口
+EXPOSE 8080
+
+# 指定docker容器启动时运行jar包
+ENTRYPOINT ["java", "-Dfile.encoding=UTF-8", "-jar", "app.jar"]
diff --git a/examples/face-example/pom.xml b/examples/face-example/pom.xml
index 78c8918..bb240c3 100644
--- a/examples/face-example/pom.xml
+++ b/examples/face-example/pom.xml
@@ -12,9 +12,9 @@
11
11
UTF-8
-
1.1.0
+
1.1.1
-
smartai.examples.face.facedet.FaceDetDemo
+
smartai.examples.face.FaceDemo
1.5.10
@@ -86,8 +86,22 @@
cn.smartjavaai
face
+
+
+ com.microsoft.onnxruntime
+ onnxruntime
+
+
+
+ com.microsoft.onnxruntime
+ onnxruntime
+ 1.20.0
+ runtime
+
+
+
ai.djl.pytorch
pytorch-jni
diff --git a/examples/face-example/src/main/java/smartai/examples/face/FaceDemo.java b/examples/face-example/src/main/java/smartai/examples/face/FaceDemo.java
new file mode 100644
index 0000000..e3f6e1d
--- /dev/null
+++ b/examples/face-example/src/main/java/smartai/examples/face/FaceDemo.java
@@ -0,0 +1,73 @@
+package smartai.examples.face;
+
+import ai.djl.modality.cv.Image;
+import cn.smartjavaai.common.config.Config;
+import cn.smartjavaai.common.cv.SmartImageFactory;
+import cn.smartjavaai.common.entity.DetectionInfo;
+import cn.smartjavaai.common.entity.DetectionResponse;
+import cn.smartjavaai.common.entity.R;
+import cn.smartjavaai.common.utils.ImageUtils;
+import cn.smartjavaai.face.config.FaceDetConfig;
+import cn.smartjavaai.face.constant.FaceDetectConstant;
+import cn.smartjavaai.face.enums.FaceDetModelEnum;
+import cn.smartjavaai.face.factory.FaceDetModelFactory;
+import cn.smartjavaai.face.model.facedect.FaceDetModel;
+import cn.smartjavaai.face.utils.FaceUtils;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.InputStream;
+
+/**
+ * @author dwj
+ * @date 2025/12/23
+ */
+@Slf4j
+public class FaceDemo {
+
+ public static String MODEL_PATH = "";
+
+ /**
+ * 获取人脸检测模型
+ * 注意事项:极速模型,识别准确度低,速度快
+ * @return
+ */
+ public static FaceDetModel getFaceDetModel(){
+ FaceDetConfig config = new FaceDetConfig();
+ //人脸检测模型,SmartJavaAI提供了多种模型选择(更多模型,请查看文档),切换模型需要同时修改modelEnum及modelPath
+ config.setModelEnum(FaceDetModelEnum.YOLOV5_FACE_320);
+ //下载模型并替换本地路径,下载地址:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
+ config.setModelPath(MODEL_PATH + "/face_model/yolo-face/yolov5face-n-0.5-320x320.onnx");
+ //只返回相似度大于该值的人脸,需要根据实际情况调整,分值越大越严格容易漏检,分值越小越宽松容易误识别
+ config.setConfidenceThreshold(0.5f);
+ //用于去除重复的人脸框,当两个框的重叠度超过该值时,只保留一个
+ config.setNmsThresh(FaceDetectConstant.NMS_THRESHOLD);
+ return FaceDetModelFactory.getInstance().getModel(config);
+ }
+
+
+ public static void main(String[] args) {
+ try {
+ MODEL_PATH = System.getenv("SMART_MODEL_PATH");
+ log.info("MODEL_PATH:" + MODEL_PATH);
+ Config.setCachePath("/app/smartjavaai_cache");
+
+ FaceDetModel faceModel = getFaceDetModel();
+ InputStream is = FaceDemo.class
+ .getClassLoader()
+ .getResourceAsStream("iu_1.jpg");
+ //创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
+ Image image = SmartImageFactory.getInstance().fromInputStream(is);
+ R detectedResult = faceModel.detect(image);
+ if(detectedResult.isSuccess()){
+ log.info("人脸检测结果:{}", JSONObject.toJSONString(detectedResult.getData()));
+ }else{
+ log.info("人脸检测失败:{}", detectedResult.getMessage());
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+}
diff --git a/examples/face-example/src/main/java/smartai/examples/face/liveness/LivenessDetDemo.java b/examples/face-example/src/main/java/smartai/examples/face/liveness/LivenessDetDemo.java
index e6854e2..9366930 100644
--- a/examples/face-example/src/main/java/smartai/examples/face/liveness/LivenessDetDemo.java
+++ b/examples/face-example/src/main/java/smartai/examples/face/liveness/LivenessDetDemo.java
@@ -31,9 +31,6 @@ import cn.smartjavaai.face.utils.FaceUtils;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import nu.pattern.OpenCV;
-import org.bytedeco.javacv.FFmpegFrameGrabber;
-import org.bytedeco.javacv.Frame;
-import org.bytedeco.javacv.Java2DFrameUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import org.opencv.core.Mat;
diff --git a/examples/ocr-examples/Dockerfile b/examples/ocr-examples/Dockerfile
new file mode 100644
index 0000000..45829d4
--- /dev/null
+++ b/examples/ocr-examples/Dockerfile
@@ -0,0 +1,35 @@
+# 使用官方 Ubuntu 22.04 作为基础
+FROM ubuntu:22.04
+
+# 设置工作目录(可选,但推荐)
+WORKDIR /app
+
+# 更新 apt 仓库并安装 OpenJDK 11
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends openjdk-11-jdk && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+
+# (可选) 验证 Java 安装 (可以选择添加你的应用程序,并编译运行,或者只是执行 java -version)
+RUN java -version
+
+# 设置默认的模型路径环境变量
+ENV SMART_MODEL_PATH=/app/models
+
+# 创建该目录
+RUN mkdir -p /app/models
+
+# 挂载
+VOLUME ["/app/models"]
+
+# UTF-8
+ENV LANG=zh_CN.UTF-8
+ENV LC_ALL=zh_CN.UTF-8
+
+
+# 声明服务运行在8080端口
+EXPOSE 8080
+
+# 指定docker容器启动时运行jar包
+ENTRYPOINT ["java", "-Dfile.encoding=UTF-8", "-jar", "app.jar"]
diff --git a/examples/ocr-examples/pom.xml b/examples/ocr-examples/pom.xml
index b444855..f2ee663 100644
--- a/examples/ocr-examples/pom.xml
+++ b/examples/ocr-examples/pom.xml
@@ -12,7 +12,7 @@
11
11
UTF-8
- 1.1.0
+ 1.1.1
smartai.examples.ocr.common.OcrRecognizeDemo
@@ -89,6 +89,19 @@
cn.smartjavaai
ocr
+
+
+ com.microsoft.onnxruntime
+ onnxruntime
+
+
+
+
+
+ com.microsoft.onnxruntime
+ onnxruntime
+ 1.20.0
+ runtime
diff --git a/examples/speech-examples/Dockerfile b/examples/speech-examples/Dockerfile
new file mode 100644
index 0000000..45829d4
--- /dev/null
+++ b/examples/speech-examples/Dockerfile
@@ -0,0 +1,35 @@
+# 使用官方 Ubuntu 22.04 作为基础
+FROM ubuntu:22.04
+
+# 设置工作目录(可选,但推荐)
+WORKDIR /app
+
+# 更新 apt 仓库并安装 OpenJDK 11
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends openjdk-11-jdk && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+
+# (可选) 验证 Java 安装 (可以选择添加你的应用程序,并编译运行,或者只是执行 java -version)
+RUN java -version
+
+# 设置默认的模型路径环境变量
+ENV SMART_MODEL_PATH=/app/models
+
+# 创建该目录
+RUN mkdir -p /app/models
+
+# 挂载
+VOLUME ["/app/models"]
+
+# UTF-8
+ENV LANG=zh_CN.UTF-8
+ENV LC_ALL=zh_CN.UTF-8
+
+
+# 声明服务运行在8080端口
+EXPOSE 8080
+
+# 指定docker容器启动时运行jar包
+ENTRYPOINT ["java", "-Dfile.encoding=UTF-8", "-jar", "app.jar"]
diff --git a/examples/speech-examples/pom.xml b/examples/speech-examples/pom.xml
index cc0c81c..8407683 100644
--- a/examples/speech-examples/pom.xml
+++ b/examples/speech-examples/pom.xml
@@ -12,7 +12,7 @@
11
11
UTF-8
- 1.1.0
+ 1.1.1
smartai.examples.speech.asr.common.OcrRecognizeDemo
diff --git a/examples/speech-examples/src/main/java/smartai/examples/speech/asr/SpeechRecognizeDemo.java b/examples/speech-examples/src/main/java/smartai/examples/speech/asr/SpeechRecognizeDemo.java
index 23795d8..7b544a6 100644
--- a/examples/speech-examples/src/main/java/smartai/examples/speech/asr/SpeechRecognizeDemo.java
+++ b/examples/speech-examples/src/main/java/smartai/examples/speech/asr/SpeechRecognizeDemo.java
@@ -234,6 +234,8 @@ public class SpeechRecognizeDemo {
@Test
public void testVosk() {
try {
+ //解决中文乱码问题
+ System.setProperty("jna.encoding","utf-8");
SpeechRecognizer recognizer = geVoskRecognizer();
//建议上传 WAV 格式音频。其他格式将自动转换为 WAV,可能影响处理速度
R result = recognizer.recognize("src/main/resources/lff_zh.mp3");
@@ -289,6 +291,8 @@ public class SpeechRecognizeDemo {
@Test
public void testVoskAdvanced() {
try {
+ //解决中文乱码问题
+ System.setProperty("jna.encoding","utf-8");
VoskRecognizer recognizer = (VoskRecognizer)geVoskRecognizer();
//使用vosk内部接口,需要指定识别音频的采样率
Recognizer voskRecognizer = recognizer.createAdvancedRecognizer(16000);
@@ -318,6 +322,8 @@ public class SpeechRecognizeDemo {
@Test
public void testVoskRealTime() {
try {
+ //解决中文乱码问题
+ System.setProperty("jna.encoding","utf-8");
VoskRecognizer recognizer = (VoskRecognizer)geVoskRecognizer();
//使用vosk内部接口,需要指定识别音频的采样率
Recognizer voskRecognizer = recognizer.createAdvancedRecognizer(16000);
diff --git a/examples/translation-example/Dockerfile b/examples/translation-example/Dockerfile
new file mode 100644
index 0000000..45829d4
--- /dev/null
+++ b/examples/translation-example/Dockerfile
@@ -0,0 +1,35 @@
+# 使用官方 Ubuntu 22.04 作为基础
+FROM ubuntu:22.04
+
+# 设置工作目录(可选,但推荐)
+WORKDIR /app
+
+# 更新 apt 仓库并安装 OpenJDK 11
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends openjdk-11-jdk && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+
+# (可选) 验证 Java 安装 (可以选择添加你的应用程序,并编译运行,或者只是执行 java -version)
+RUN java -version
+
+# 设置默认的模型路径环境变量
+ENV SMART_MODEL_PATH=/app/models
+
+# 创建该目录
+RUN mkdir -p /app/models
+
+# 挂载
+VOLUME ["/app/models"]
+
+# UTF-8
+ENV LANG=zh_CN.UTF-8
+ENV LC_ALL=zh_CN.UTF-8
+
+
+# 声明服务运行在8080端口
+EXPOSE 8080
+
+# 指定docker容器启动时运行jar包
+ENTRYPOINT ["java", "-Dfile.encoding=UTF-8", "-jar", "app.jar"]
diff --git a/examples/translation-example/pom.xml b/examples/translation-example/pom.xml
index b4f85e4..52610c8 100644
--- a/examples/translation-example/pom.xml
+++ b/examples/translation-example/pom.xml
@@ -12,7 +12,7 @@
11
11
UTF-8
- 1.1.0
+ 1.1.1
smartai.examples.nlp.translation.TranslationDemo
diff --git a/examples/vision-example/Dockerfile b/examples/vision-example/Dockerfile
new file mode 100644
index 0000000..45829d4
--- /dev/null
+++ b/examples/vision-example/Dockerfile
@@ -0,0 +1,35 @@
+# 使用官方 Ubuntu 22.04 作为基础
+FROM ubuntu:22.04
+
+# 设置工作目录(可选,但推荐)
+WORKDIR /app
+
+# 更新 apt 仓库并安装 OpenJDK 11
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends openjdk-11-jdk && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+
+# (可选) 验证 Java 安装 (可以选择添加你的应用程序,并编译运行,或者只是执行 java -version)
+RUN java -version
+
+# 设置默认的模型路径环境变量
+ENV SMART_MODEL_PATH=/app/models
+
+# 创建该目录
+RUN mkdir -p /app/models
+
+# 挂载
+VOLUME ["/app/models"]
+
+# UTF-8
+ENV LANG=zh_CN.UTF-8
+ENV LC_ALL=zh_CN.UTF-8
+
+
+# 声明服务运行在8080端口
+EXPOSE 8080
+
+# 指定docker容器启动时运行jar包
+ENTRYPOINT ["java", "-Dfile.encoding=UTF-8", "-jar", "app.jar"]
diff --git a/examples/vision-example/pom.xml b/examples/vision-example/pom.xml
index db39394..81a5277 100644
--- a/examples/vision-example/pom.xml
+++ b/examples/vision-example/pom.xml
@@ -12,7 +12,7 @@
11
11
UTF-8
- 1.1.0
+ 1.1.1
smartai.examples.vision.ObjectDetectionDemo
@@ -86,6 +86,19 @@
cn.smartjavaai
vision
+
+
+ com.microsoft.onnxruntime
+ onnxruntime
+
+
+
+
+
+ com.microsoft.onnxruntime
+ onnxruntime
+ 1.20.0
+ runtime
@@ -241,17 +254,10 @@
ai.djl.tensorflow
tensorflow-native-cpu
- ${javacv.platform.linux-arm64}
+ ${djl.platform.linux-aarch64}
runtime
2.16.1
-
- ai.djl.mxnet
- mxnet-native-mkl
- ${javacv.platform.linux-arm64}
- runtime
- 1.9.1
-
diff --git a/examples/vision-example/src/main/java/smartai/examples/vision/ObjectDetectionDemo.java b/examples/vision-example/src/main/java/smartai/examples/vision/ObjectDetectionDemo.java
index 50fd93c..af6972b 100644
--- a/examples/vision-example/src/main/java/smartai/examples/vision/ObjectDetectionDemo.java
+++ b/examples/vision-example/src/main/java/smartai/examples/vision/ObjectDetectionDemo.java
@@ -205,13 +205,16 @@ public class ObjectDetectionDemo {
*/
@Test
public void testStream(){
+
StreamDetector detector = new StreamDetector.Builder()
//视频源类型:支持视频流、本地摄像头、视频文件
.sourceType(VideoSourceType.STREAM)
//视频流地址,支持rtsp、rtmp、http等常见视频流
- .streamUrl("rtsp://username:password@ip:port/Streaming/Channels/101")
+ .streamUrl("rtsp://127.0.0.1:8554/stream")
//每隔多少帧检测一次(需要根据模型检测速度决定)
.frameDetectionInterval(10)
+ //是否打印调试日志
+ .enableDebugLog(false)
//目标检测模型
.detectorModel(getModel())
//回调函数:检测到指定目标时触发(getModel中可指定模型检测的物体)
@@ -246,6 +249,7 @@ public class ObjectDetectionDemo {
}
}).build();
detector.startDetection();
+
//阻塞主线程
CountDownLatch latch = new CountDownLatch(1);
try {
@@ -319,8 +323,6 @@ public class ObjectDetectionDemo {
.frameDetectionInterval(5)
//目标检测模型
.detectorModel(getModel())
- //同物体重复检测时间间隔,单位s
- .repeatGap(5)
//回调函数:检测到指定目标时触发(getModel中可指定模型检测的物体)
.listener(new StreamDetectionListener() {
@Override
diff --git a/face/pom.xml b/face/pom.xml
index e5ea7ce..56f3654 100644
--- a/face/pom.xml
+++ b/face/pom.xml
@@ -6,11 +6,11 @@
cn.smartjavaai
smartjavaai-parent
- 1.1.0
+ 1.1.1
face
- 1.1.0
+ 1.1.1
face
SmartJavaAI
https://github.com/geekwenjie/SmartJavaAI
diff --git a/ocr/pom.xml b/ocr/pom.xml
index 67ad098..32df199 100644
--- a/ocr/pom.xml
+++ b/ocr/pom.xml
@@ -6,7 +6,7 @@
cn.smartjavaai
smartjavaai-parent
- 1.1.0
+ 1.1.1
ocr
@@ -42,7 +42,7 @@
-
1.1.0
+
1.1.1
ocr
SmartJavaAI
https://github.com/geekwenjie/SmartJavaAI
diff --git a/pom.xml b/pom.xml
index c07ea22..1104534 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
SmartJavaAI
cn.smartjavaai
smartjavaai-parent
-
1.1.0
+
1.1.1
pom
SmartJavaAI
@@ -109,7 +109,7 @@
org.projectlombok
lombok
- 1.18.4
+ 1.18.34
diff --git a/speech/pom.xml b/speech/pom.xml
index bfaf7c7..fdc832f 100644
--- a/speech/pom.xml
+++ b/speech/pom.xml
@@ -6,7 +6,7 @@
cn.smartjavaai
smartjavaai-parent
- 1.1.0
+ 1.1.1
speech
@@ -57,7 +57,7 @@
- 1.1.0
+ 1.1.1
speech
SmartJavaAI
https://github.com/geekwenjie/SmartJavaAI
diff --git a/speech/src/main/java/cn/smartjavaai/speech/asr/model/VoskRecognizer.java b/speech/src/main/java/cn/smartjavaai/speech/asr/model/VoskRecognizer.java
index cbb4fcc..31693de 100644
--- a/speech/src/main/java/cn/smartjavaai/speech/asr/model/VoskRecognizer.java
+++ b/speech/src/main/java/cn/smartjavaai/speech/asr/model/VoskRecognizer.java
@@ -56,6 +56,8 @@ public class VoskRecognizer implements SpeechRecognizer{
@Override
public void loadModel(AsrModelConfig config) {
this.config = config;
+ //防止中文乱码
+ System.setProperty("jna.encoding","utf-8");
if(StringUtils.isBlank(config.getModelPath())){
throw new AsrException("modelPath is null");
}
diff --git a/translate/pom.xml b/translate/pom.xml
index 2469f02..b476a82 100644
--- a/translate/pom.xml
+++ b/translate/pom.xml
@@ -25,7 +25,7 @@
- 1.1.0
+ 1.1.1
translate
SmartJavaAI
https://github.com/geekwenjie/SmartJavaAI
diff --git a/vision/pom.xml b/vision/pom.xml
index ed6baf0..225de2f 100644
--- a/vision/pom.xml
+++ b/vision/pom.xml
@@ -6,11 +6,11 @@
cn.smartjavaai
smartjavaai-parent
- 1.1.0
+ 1.1.1
vision
- 1.1.0
+ 1.1.1
vision
SmartJavaAI
https://github.com/geekwenjie/SmartJavaAI
diff --git a/vision/src/main/java/cn/smartjavaai/objectdetection/criteria/CriteriaBuilderFactory.java b/vision/src/main/java/cn/smartjavaai/objectdetection/criteria/CriteriaBuilderFactory.java
index 10a70ab..753b402 100644
--- a/vision/src/main/java/cn/smartjavaai/objectdetection/criteria/CriteriaBuilderFactory.java
+++ b/vision/src/main/java/cn/smartjavaai/objectdetection/criteria/CriteriaBuilderFactory.java
@@ -29,10 +29,14 @@ public class CriteriaBuilderFactory {
switch (config.getModelEnum()) {
case YOLOV8_OFFICIAL_ONNX:
return new YoloCriteriaBuilder().buildCriteria(config);
+ case YOLOV11_OFFICIAL_ONNX:
+ return new YoloCriteriaBuilder().buildCriteria(config);
case YOLOV12_OFFICIAL_ONNX:
return new YoloCriteriaBuilder().buildCriteria(config);
case YOLOV8_CUSTOM_ONNX:
return new YoloCriteriaBuilder().buildCriteria(config);
+ case YOLOV11_CUSTOM_ONNX:
+ return new YoloCriteriaBuilder().buildCriteria(config);
case YOLOV12_CUSTOM_ONNX:
return new YoloCriteriaBuilder().buildCriteria(config);
case TENSORFLOW2_OFFICIAL:
diff --git a/vision/src/main/java/cn/smartjavaai/objectdetection/stream/StreamDetector.java b/vision/src/main/java/cn/smartjavaai/objectdetection/stream/StreamDetector.java
index 9269bd9..f8ce7f2 100644
--- a/vision/src/main/java/cn/smartjavaai/objectdetection/stream/StreamDetector.java
+++ b/vision/src/main/java/cn/smartjavaai/objectdetection/stream/StreamDetector.java
@@ -49,7 +49,6 @@ public class StreamDetector implements AutoCloseable{
//回调线程池
ExecutorService callbackExecutor;
private int frameDetectionInterval = 1;
- private long repeatGap = 5; // 秒
private volatile boolean isRunning;
private FrameGrabber grabber;
private StreamDetectionListener listener;
@@ -57,6 +56,8 @@ public class StreamDetector implements AutoCloseable{
private VideoSourceType sourceType = VideoSourceType.STREAM; // 默认流
private int cameraIndex = 0; // 默认第一个摄像头
+ private boolean enableDebugLog; //是否开启debug log
+
private Map lastDetectTime = new ConcurrentHashMap<>();
private BlockingQueue frameQueue = new LinkedBlockingQueue<>(100);
@@ -84,7 +85,8 @@ public class StreamDetector implements AutoCloseable{
this.listener = builder.listener;
this.sourceType = builder.sourceType;
this.cameraIndex = builder.cameraIndex;
- this.repeatGap = builder.repeatGap;
+// this.repeatGap = builder.repeatGap;
+ this.enableDebugLog = builder.enableDebugLog;
this.converterToMat = new OpenCVFrameConverter.ToOrgOpenCvCoreMat();
}
@@ -160,7 +162,7 @@ public class StreamDetector implements AutoCloseable{
* 负责抓取视频帧到队列
*/
private void processFrames() {
- long frameCount = 0;
+ long detectCounter = 0;
while (!grabberFinished && isRunning) {
try {
Frame frame = grabber.grabFrame();
@@ -192,11 +194,16 @@ public class StreamDetector implements AutoCloseable{
continue;
}
}
- frameCount++;
- if (frameCount % frameDetectionInterval != 0) continue;
+ detectCounter++;
+ if (detectCounter < frameDetectionInterval) {
+ continue;
+ }
+ detectCounter = 0;
Frame currentFrame = frame.clone();
frameQueue.offer(currentFrame);
-// log.debug("正在抓取第{}帧,当前帧数:{}", frameCount, frameQueue.size());
+ if (enableDebugLog){
+ log.debug("当前未处理帧数:{}", frameQueue.size());
+ }
} catch (Exception e) {
log.error("抓取视频帧异常", e);
}
@@ -242,16 +249,15 @@ public class StreamDetector implements AutoCloseable{
Image image = SmartImageFactory.getInstance().fromMat(mat);
DetectedObjects detectedObjects = predictor.predict(image);
-// log.info("内部检测结果:{}", detectedObjects.toString());
+ if (enableDebugLog){
+ log.debug("帧检测结果:{}", detectedObjects.toString());
+ }
DetectionResponse detectionResponse = DetectorUtils.convertToDetectionResponse(detectedObjects, image);
if(Objects.isNull(detectionResponse)){
return;
}
- List filtered = filterRepeatedObjects(detectionResponse);
- if (!filtered.isEmpty() && listener != null) {
- Image copyImage = image.duplicate();
- callbackExecutor.submit(() -> listener.onObjectDetected(filtered, copyImage));
- }
+ Image copyImage = image.duplicate();
+ callbackExecutor.submit(() -> listener.onObjectDetected(detectionResponse.getDetectionInfoList(), copyImage));
} catch (Throwable e) {
e.printStackTrace();
log.error("单帧处理异常", e);
@@ -260,21 +266,6 @@ public class StreamDetector implements AutoCloseable{
}
}
- private List filterRepeatedObjects(DetectionResponse response) {
- List result = new ArrayList<>();
- long now = System.currentTimeMillis();
- for (DetectionInfo info : response.getDetectionInfoList()) {
- String name = info.getObjectDetInfo().getClassName();
- Long last = lastDetectTime.get(name);
- if (last == null || (now - last) > repeatGap * 1000) {
- lastDetectTime.put(name, now);
- result.add(info);
- }
- }
- return result;
- }
-
-
/**
* 开始检测下一个视频文件
*/
@@ -322,10 +313,6 @@ public class StreamDetector implements AutoCloseable{
@Override
public void close() {
-// if(isRunning){
-// System.out.println("--isRunning:" + isRunning);
-// stopDetection();
-// }
if (grabberExecutor != null){
grabberExecutor.shutdownNow();
}
@@ -345,15 +332,11 @@ public class StreamDetector implements AutoCloseable{
private VideoSourceType sourceType = VideoSourceType.STREAM; // 默认流
private int cameraIndex = 0; // 默认第一个摄像头
- private long repeatGap = 5;//同物体重复检测间隔
+ private boolean enableDebugLog; //是否开启debug log
public Builder detectorModel(DetectorModel m) { this.detectorModel = m; return this; }
public Builder streamUrl(String url) { this.streamUrl = url; return this; }
public Builder listener(StreamDetectionListener listener) { this.listener = listener; return this; }
- public Builder repeatGap(long repeatGap) {
- this.repeatGap = repeatGap;
- return this;
- }
public Builder sourceType(VideoSourceType sourceType) {
this.sourceType = sourceType;
return this;
@@ -368,6 +351,11 @@ public class StreamDetector implements AutoCloseable{
return this;
}
+ public Builder enableDebugLog(boolean enableDebugLog) {
+ this.enableDebugLog = enableDebugLog;
+ return this;
+ }
+
public StreamDetector build() {
if (detectorModel == null) {
throw new DetectionException("detectorModel 不能为空");