模型调用也可以这么优雅-SmartJavaAI

57 阅读5分钟

故事开端

I need 人脸检活。

Tensflow.js

人脸特征点检测。

思路就是这位大佬的文章,我觉得写的很不错,虽然检测精度有待提高,但是我觉得做的已经很好了,膜拜,各位有兴趣的可以去看看。

前端实现活体人脸检测

image.png

「dlib + OpenCV」68 点人脸特征点检测

其实思路和tensflow.js是一样的,先通过模型将人脸特征点检测出来,然后通过计算眼部特征点的EAR和嘴部特征点的MAR来实现。

EAR=p2p6+p3p52p1p4EAR = \frac{\\|p_2 - p_6\\| + \\|p_3 - p_5\\|}{2 \\|p_1 - p_4\\|}

值域 ≈ 0.2 闭眼,≈ 0.4 完全睁开。根据捕捉到的视频帧判断是否有 睁开-》闭眼-》睁开的动作。

MAR=p51p59+p53p572p49p55MAR = \frac{\\|p_{51} - p_{59}\\| + \\|p_{53} - p_{57}\\|}{2 \\|p_{49} - p_{55}\\|}

值域 ≈ 0.6 以上视为张嘴。

同样的问题,检测精度不高。

主角登场 SmartJavaAI

正当我在茫茫文章中寻找更好的解决方案时,他出现了,上来就是像Hutool一样简单易用的Java AI工具箱。虽然我是个切图仔,但是对于Hutool还是有所耳闻的,敢于对标这个大佬,我倒要看看怎么个回事,是不是和前端届的下一代XXX一样。 打开官网,好好鉴赏,这一鉴赏真是让我爱不释手了。以下是官方的介绍。

集成功能

人脸识别

  • 人脸检测:人脸区域检测、5点人脸关键点定位
  • 人脸识别:512维特征提取、人脸对齐、1:1比对、1:N识别
  • 人脸库:注册、更新、查询、删除(支持 Milvus / SQLite 向量数据库)
  • 人脸属性:性别、年龄、口罩、眼睛状态、脸部姿态
  • 静默活体检测:图片 / 视频活体检测
  • 人脸表情识别:7 种表情识别
  • 人脸质量评估:亮度、清晰度、完整度、姿态、遮挡评估

目标检测

  • 集成 YOLOv5 / v8 / v11 / v12、TensorFlow Object Detection 等主流模型
  • 支持自定义模型无缝加载
  • 内置行人检测模型

语义分割

  • 集成 DeepLabV3 模型

实例分割

  • 集成 YOLOv8-seg、YOLOv11-seg、Mask R-CNN 等模型

OBB 旋转框目标检测

  • 集成 YOLOv11-obb 模型

动作识别

  • 支持 Kinetics-400 数据集中 400 类人类动作识别

姿态估计

  • 集成 YOLOv8-pose、YOLOv11-pose 等模型

OCR 文字识别

  • 集成 PaddleOCR 3.0:PP-OCRv5、PP-OCRv4、SLANet_plus 表格结构识别、文本行方向分类
  • 任意角度识别 + 方向校准
  • 通用印刷 / 手写字识别、表格识别
  • 中文车牌识别:单/双层检测、颜色识别,支持 12 种车牌

机器翻译

  • 集成 NLLB-200 模型,支持 200+ 语言互译

语音识别

  • 集成 OpenAI Whisper:支持 100 种语言
  • 集成 Vosk 语音识别

方案对比

方案技术特点优点缺点
OpenCV传统图像处理方案✅ 提供Java接口
✅ 轻量级部署
✅ 社区资源丰富
❌ 基于传统算法精度低 (60%-75%)
❌ 需本地安装环境
商业闭源SDK(如虹软等)商业级闭源解决方案✅ 开箱即用
✅ 提供完整文档和SDK
✅ 支持离线活体检测
❌ 免费版需年度授权更新
❌ 商业授权费用高
❌ 代码不可控
云API(阿里云)SaaS化云端服务✅ 零部署成本
✅ 支持高并发
✅ 自带模型迭代
❌ 网络延迟风险(200-800ms)
❌ 按调用量计费
❌ 有数据安全风险
Python混合调用跨语言调用方案✅ 可集成PyTorch/TF等框架
✅ 支持自定义算法
✅ 识别精度高
❌ 需维护双语言环境
❌ 进程通信性能损耗(30%+)
❌ 异常处理复杂度翻倍
JNI/JNA跨语言底层调用方案✅ 直接调用 C/C++ 高性能算法库
✅ 支持调用各种原生成熟库
✅ 可封装成通用工具Jar
❌ 开发成本高,JNI更复杂
❌ 跨平台兼容性差
DIL框架深度学习框架✅ 纯Java实现
✅ 支持主流深度学习框架
✅ 可加载预训练模型(99%+)
❌ 需掌握DL知识
❌ 需处理模型加载、预处理、后处理等复杂技术细节
SmartJavaAIJava深度学习工具包✅ 支持主流深度学习框架
✅ 提供丰富、开箱即用API
✅ 上手简单,单一Jar包集成

包含组件

模块介绍
common基础通用模块,封装了公共功能,供各算法模块共享使用
bom依赖管理模块
face人脸功能模块
vision通用视觉模块(目标检测等功能)
ocrOCR文字识别模块
translate机器翻译模块
speech语音功能模块,包含 ASR 和 TTS

可以根据需求对每个模块单独引入,也可以通过引入 all 方式引入所有模块。

架构图

image.png

开始测试

idea启动,虽然vscode很优秀,但是对于java我还是选择idea。

第一步,新建一个spring boot项目。

第二步,pom.xml文件改一改

<properties>
    <javacv.version>1.5.10</javacv.version>
    <javacv.platform.macosx-arm64>macosx-arm64</javacv.platform.macosx-arm64>
    <javacv.platform.linux-x86_64>linux-x86_64</javacv.platform.linux-x86_64>
    <javacv.platform.linux-arm64>linux-arm64</javacv.platform.linux-arm64>
    <javacv.platform.windows-x86_64>windows-x86_64</javacv.platform.windows-x86_64>
    <djl.platform.windows-x86_64>win-x86_64</djl.platform.windows-x86_64>
    <djl.platform.linux-x86_64>linux-x86_64</djl.platform.linux-x86_64>
    <djl.platform.linux-aarch64>linux-aarch64</djl.platform.linux-aarch64>
    <djl.platform.osx-aarch64>osx-aarch64</djl.platform.osx-aarch64>
</properties>
<dependencies>
    <dependency>
        <groupId>cn.smartjavaai</groupId>
        <artifactId>face</artifactId>
        <version>1.1.0</version>
    </dependency>
    <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>
    <dependency>
        <groupId>ai.djl.pytorch</groupId>
        <artifactId>pytorch-jni</artifactId>
        <version>2.7.1-0.34.0</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>

第三步,新建一个FaceController.java 类,新增/checkImgLive, /checkVideoLive 两个接口。

第四步,下载所需模型,竟然是百度网盘,差评。

第五步,加载模型。

@PostConstruct
public void start() {
    log.info("开始加载人脸模型");
    FaceDetConfig config = new FaceDetConfig();
    config.setModelEnum(FaceDetModelEnum.MTCNN);
    config.setModelPath("人脸特征点识别模型路径");
    config.setConfidenceThreshold("置信度阈值");
    faceDetModel = FaceDetModelFactory.getInstance().getModel(config);
    LivenessConfig LiveConfig = new LivenessConfig();
    LiveConfig.setModelEnum(LivenessModelEnum.MINI_VISION_MODEL);
    LiveConfig.setModelPath("活检模型路径");
    LiveConfig.putCustomParam("seModelPath", faceLiveSeModelPath);
    LiveConfig.setRealityThreshold("人脸活体阈值");
    LiveConfig.setDetectModel(faceDetModel);
    livenessDetModel = LivenessModelFactory.getInstance().getModel(LiveConfig);
    log.info("人脸模型加载完成");
}

第六步,实现活检

@PostMapping("/checkImgLive")
public AjaxResult checkImgLive(@RequestParam("file") MultipartFile file) throws IOException {
    try{
        @Cleanup
        InputStream inputStream = file.getInputStream();
        BufferedImage bufferedImage = ImageIO.read(inputStream);
        Image image = SmartImageFactory.getInstance().fromBufferedImage(bufferedImage);
        R<DetectionResponse> response = livenessDetModel.detect(image);
        return AjaxResult.success(response);
    }catch (Exception e){
        return AjaxResult.error("检测异常");
    }
}

@PostMapping("/checkVideoLive")
public AjaxResult checkVideoLive(@RequestParam("file") MultipartFile file) throws IOException {
    try {
        @Cleanup
        InputStream inputStream = file.getInputStream();
        R<LivenessResult> livenessStatus = livenessDetModel.detectVideo(inputStream);
        LivenessResult livenessResult = livenessStatus.getData();
        if(livenessResult == null){
            return AjaxResult.error("检测异常");
        }else{
            return AjaxResult.success(livenessResult);
        }
    } catch (Exception e) {
        return AjaxResult.error("检测异常");
    }
}

第七步 打开AI工具,编写测试页面

image.png

第八步 报告领导,我要加鸡腿!!!

写在最后

我只是浅尝一下,但是已经基本满足我的要求了,并且精度相比之前的方案已经有了很大提升,还有视频检测,完美。但是我只是用到了他的冰山一角,看来他说自己是像Hutool一样简单易用的Java AI工具箱确实没有吹牛。

PS:模型在百度网盘,下载太慢,怎么办呢。可以试试关注下面的公众号,也许里面有好东西呢。

image.png