故事开端
I need 人脸检活。
Tensflow.js
人脸特征点检测。
思路就是这位大佬的文章,我觉得写的很不错,虽然检测精度有待提高,但是我觉得做的已经很好了,膜拜,各位有兴趣的可以去看看。
「dlib + OpenCV」68 点人脸特征点检测
其实思路和tensflow.js是一样的,先通过模型将人脸特征点检测出来,然后通过计算眼部特征点的EAR和嘴部特征点的MAR来实现。
值域 ≈ 0.2 闭眼,≈ 0.4 完全睁开。根据捕捉到的视频帧判断是否有 睁开-》闭眼-》睁开的动作。
值域 ≈ 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知识 ❌ 需处理模型加载、预处理、后处理等复杂技术细节 |
| SmartJavaAI | Java深度学习工具包 | ✅ 支持主流深度学习框架 ✅ 提供丰富、开箱即用API ✅ 上手简单,单一Jar包集成 | 无 |
包含组件
| 模块 | 介绍 |
|---|---|
| common | 基础通用模块,封装了公共功能,供各算法模块共享使用 |
| bom | 依赖管理模块 |
| face | 人脸功能模块 |
| vision | 通用视觉模块(目标检测等功能) |
| ocr | OCR文字识别模块 |
| translate | 机器翻译模块 |
| speech | 语音功能模块,包含 ASR 和 TTS |
可以根据需求对每个模块单独引入,也可以通过引入
all方式引入所有模块。
架构图
开始测试
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工具,编写测试页面
第八步 报告领导,我要加鸡腿!!!
写在最后
我只是浅尝一下,但是已经基本满足我的要求了,并且精度相比之前的方案已经有了很大提升,还有视频检测,完美。但是我只是用到了他的冰山一角,看来他说自己是像Hutool一样简单易用的Java AI工具箱确实没有吹牛。
PS:模型在百度网盘,下载太慢,怎么办呢。可以试试关注下面的公众号,也许里面有好东西呢。