# 人脸识别
# 简介
SmartJavaAI
人脸模块支持以下功能:
- 人脸检测
- 人脸特征提取(含人脸对齐)
- 1:1 人脸比对
- 1:N 人脸识别
- 人脸注册与查询(支持向量数据库milvus/sqlite)
- 5点人脸关键点定位
- 人脸属性检测(性别、年龄、口罩、眼睛状态、脸部姿态)
- 人脸活体检测:图片、视频活体检测
# 能力展示
人脸检测 - 5点人脸关键点定位 | ![]() |
人脸比对1:1 - 人脸对齐 | ![]() |
人证核验 | ![]() |
人脸比对1:N - 人脸对齐- 人脸注册 - 人脸库查询 - 人脸库删除 | ![]() |
人脸属性检测 - 性别检测- 年龄检测 - 口罩检测 - 眼睛状态检测 - 脸部姿态检测 | ![]() |
活体检测 - 图片和视频活体检测 | ![]() |
# 准备工作
# 1、Maven引入
在项目的 pom.xml 中添加以下依赖以及平台依赖库,详细引入方式参考 Maven 引入。如需引入全部功能,请使用 smartjavaai-all 模块。
<dependency>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-face</artifactId>
<version>1.0.16</version>
</dependency>
# 2、人脸模型下载
如果在有网环境下使用,不需要手动下载模型,程序将自动下载(SeetaFace6模型除外)
模型名称 | 下载地址 | 兼容系统 | 支持设备 | 文件大小 | 适用场景 |
---|---|---|---|---|---|
retinaface | 下载 (opens new window) | Windows Linux MacOS | CPU/GPU | 110MB | 高精度人脸检测 |
ultralightfastgenericface | 下载 (opens new window) | Windows Linux MacOS | CPU/GPU | 1.7MB | 高速人脸检测 |
seetaface6 | 下载 (opens new window) | Windows Linux | CPU/GPU | 288MB | 人脸检测、人脸特征提取、人脸比对、人脸库注册、人脸库查询等全功能模型 |
facenet | 下载 (opens new window) | Windows Linux MacOS | CPU/GPU | 104MB | 人脸特征提取、人脸比对、人脸库注册、人脸库查询 |
# 创建人脸模型
以下所有功能在使用前,需先创建模型实例,并通过该模型对象调用对应功能。
# 获取默认检测模型:
- 默认模型:retinaface,联网自动下载
FaceModel faceModel = FaceModelFactory.getInstance().getModel();
# 获取模型(使用自定义模型配置)
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.RETINA_FACE);//人脸模型
config.setConfidenceThreshold(FaceConfig.DEFAULT_CONFIDENCE_THRESHOLD);//置信度阈值
config.setNmsThresh(FaceConfig.NMS_THRESHOLD);//非极大抑制阈值
FaceModel faceModel = FaceModelFactory.getInstance().getModel(config);
# FaceModelConfig参数说明
字段名称 | 字段类型 | 默认值 | 说明 |
---|---|---|---|
modelEnum | FaceModelEnum | RETINA_FACE | 人脸模型枚举 |
confidenceThreshold | double | 0.85 | 置信度阈值,分数低于这个值的结果将被过滤掉。值越高越严格,越低越宽松。 |
nmsThresh | double | 0.45 | 非极大抑制阈值,用于去除重复的人脸框,当两个框的重叠度超过该值时,只保留一个,建议使用默认值 |
modelPath | String | NULL | 手动指定离线模型路径 |
device | DeviceEnum | CPU | 指定运行设备,支持 CPU/GPU |
extractConfig | FaceExtractConfig | 特征提取配置,支持是否裁剪人人脸,是否人脸对齐,自定义检测模型 | |
faceDbPath | String | NULL | 人脸库相关参数:SQLite人脸库路径(适用于注册/查询功能) |
vectorDBConfig | VectorDBConfig | 人脸库相关参数:人脸库配置 | |
isAutoLoadFace | boolean | true | 人脸库相关参数:是否自动加载人脸库(异步),设置vectorDBConfig后此参数才有效 |
注意事项:
1、当使用 SeetaFace6 模型时,必须手动设置 modelPath,modelPath 为模型目录路径,无需包含具体文件名。
2、seetaface6模型不支持自定义confidenceThreshold
# FaceModelEnum人脸模型枚举说明
枚举值 | 说明 |
---|---|
RETINA_FACE | 高精度人脸检测模型 |
ULTRA_LIGHT_FAST_GENERIC_FACE | 轻量人脸检测模型 |
FACENET_MODEL | 人脸特征提取模型 |
SEETA_FACE6_MODEL | seetaface6全功能人脸模型 |
# 人脸检测
# 人脸检测方法
DetectionResponse detect(String imagePath);
DetectionResponse detect(BufferedImage image);
DetectionResponse detect(byte[] imageData);
# DetectionResponse字段说明
- 返回并非json格式,仅用于字段讲解
{
"detectionInfoList": [ // 检测信息列表
{
"detectionRectangle": { //矩形框
"height": 174, // 矩形高度
"width": 147, // 矩形宽度
"x": 275, // 左上角横坐标
"y": 143 // 左上角纵坐标
},
"faceInfo": { // 人脸信息
"keyPoints": [ // 5个人脸关键点:循序依次为,左眼中心、右眼中心、鼻尖、左嘴角和右嘴角
{
"x": 339.5083751678467,
"y": 192.76402664184573
},
{
"x": 404.7374267578125,
"y": 197.89914321899414
},
{
"x": 388.9555263519287,
"y": 231.50675201416016
},
{
"x": 339.8661708831787,
"y": 265.51241302490234
},
{
"x": 397.7071800231933,
"y": 269.7657699584961
}
],
"livenessStatus": "LIVE"
},
"score": 0.9995993 // 置信度分值
}
]
}
# 检测并绘制人脸框
绘制人脸区域及5个人脸关键点:左眼中心、右眼中心、鼻尖、左嘴角和右嘴角
/**
* 检测并绘制人脸
* @param imagePath 图片输入路径(包含文件名称)
* @param outputPath 图片输出路径(包含文件名称)
*/
void detectAndDraw(String imagePath, String outputPath);
/**
* 检测并绘制人脸
* @param sourceImage
* @return
*/
BufferedImage detectAndDraw(BufferedImage sourceImage);
# 人脸特征提取
在创建人脸模型时,可以通过设置 extractConfig 参数来自定义人脸特征提取行为。如果未设置,系统会启用一套默认配置,满足大部分常见场景的需求。
默认设置如下:
FaceExtractConfig config = new FaceExtractConfig();
FaceModelConfig detectModelConfig = new FaceModelConfig();
detectModelConfig.setModelEnum(FaceModelEnum.ULTRA_LIGHT_FAST_GENERIC_FACE);
detectModelConfig.setConfidenceThreshold(0.98);
FaceModel detectModel = FaceModelFactory.getInstance().getModel(detectModelConfig);
config.setDetectModel(detectModel);
当然,用户也可以根据具体需求,手动配置提取参数。例如:
//人脸模型参数
FaceModelConfig config = new FaceModelConfig();
config.setModelEnum(FaceModelEnum.FACENET_MODEL);
//人脸特征提取参数
FaceExtractConfig extractConfig = new FaceExtractConfig();
extractConfig.setCropFace(true);
extractConfig.setAlign(true);
//人脸检测模型配置,指定人脸检测模型:ULTRA_LIGHT_FAST_GENERIC_FACE
FaceModelConfig detectModelConfig = new FaceModelConfig(FaceModelEnum.ULTRA_LIGHT_FAST_GENERIC_FACE);
extractConfig.setDetectModel(FaceModelFactory.getInstance().getModel(detectModelConfig));
config.setExtractConfig(extractConfig);
下面将讲解一下这些参数的含义:
# FaceExtractConfig参数说明
字段名称 | 字段类型 | 默认值 | 说明 |
---|---|---|---|
cropFace | boolean | true | 是否对输入图片中的人脸进行裁剪。推荐对原始图像开启此项,以提取更精确的特征。若图像已是标准人脸区域,可关闭以提升效率。 |
align | boolean | false | 是否进行人脸对齐。仅在 cropFace = true 时生效。若人脸角度较正,建议关闭可提升性能;若角度偏差大,建议开启提高准确性。 |
detectModelConfig | FaceModelConfig | 人脸检测模型配置,可自定义所用的检测模型。 |
注意事项:
1、当使用 FACENET_MODEL 模型时,默认启用 ULTRA_LIGHT_FAST_GENERIC_FACE 作为人脸检测模型,且置信度阈值默认为 0.98。
2、SEETAFACE6 模型 不支持自定义 FaceExtractConfig。该模型自带检测与对齐功能,因此会自动完成人脸检测、裁剪与对齐操作。
# 人脸特征提取(多人脸场景)
下面的方法将提取图片中所有人脸特征
R<DetectionResponse> extractFeatures(String imagePath);
R<DetectionResponse> extractFeatures(BufferedImage sourceImage);
R<DetectionResponse> extractFeatures(byte[] imageData);
DetectionResponse转为json格式,如下所示:
{
"detectionInfoList": [
{
"detectionRectangle": {
"height": 328,
"width": 307,
"x": 157,
"y": 288
},
"faceInfo": {
"feature": [ // 人脸特征向量:不同模型返回的特征向量数量不同,可能是 512 或 1024。
//此处内容较多,省略
],
"keyPoints": [
{
"x": 248.22177505493164,
"y": 384.6785583496094
},
{
"x": 374.57435607910156,
"y": 374.8636550903321
},
{
"x": 322.0528106689453,
"y": 442.43547058105474
},
{
"x": 267.237491607666,
"y": 514.3596992492676
},
{
"x": 380.99170684814453,
"y": 506.0889015197754
}
]
},
"score": 0.99999225
}
]
}
# 📦 返回结果说明:R<DetectionResponse>
R<T>
是一个统一的返回结果封装类(Response Wrapper),用于标准化接口返回结构,便于前端或调用方统一处理。
包含以下字段:
字段名 | 类型 | 说明 |
---|---|---|
code | Integer | 状态码,通常 0 表示成功,非 0 表示失败 |
message | String | 提示信息,例如 "ok" 、"image not found" |
data | T(此处是 DetectionResponse ) | 实际返回的数据内容 |
# 获取结果示例代码
R<DetectionResponse> faceResult = faceModel.extractFeatures("test.jpg");
if(faceResult.isSuccess()){
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(faceResult.getData()));
}else{
log.info("人脸特征提取失败:{}", faceResult.getMessage());
}
# 人脸特征提取(单人脸场景)
提取图像中分数最高的人脸特征,适用于仅包含单张人脸的图像,或存在主次明显的人脸场景。
R<float[]> extractTopFaceFeature(String imagePath);
R<float[]> extractTopFaceFeature(BufferedImage sourceImage);
R<float[]> extractTopFaceFeature(byte[] imageData);
# 人脸比对(相似度计算)
- 参数为extractFeatures或extractTopFaceFeature的返回结果
/**
* 计算相似度
* @param feature1 图1特征
* @param feature2 图2特征
* @return
*/
float calculSimilar(float[] feature1, float[] feature2);
# 人脸比对(1:1)
直接对两张图片进行比对。方法内部会自动提取每张图中分数最高的人脸特征,并进行相似度计算。
等价于先调用 extractTopFaceFeature
方法提取人脸特征,再使用 calculateSimilar
方法进行比对。
float featureComparison(String imagePath1, String imagePath2);
float featureComparison(BufferedImage sourceImage1, BufferedImage sourceImag2);
float featureComparison(byte[] imageData1, byte[] imageData2);
# 人脸库
人脸库相关功能(如人脸注册、人脸查询、人脸删除、清空人脸库等)都依赖于人脸库的支持。 SmartJavaAI 当前支持两种人脸库方案,分别适用于不同规模与性能需求的应用场景:
人脸库方案 | 应用场景说明 |
---|---|
SQLite + 内存轮询 | 适用于人脸数量 少于 1 万 的轻量级应用场景。 人脸特征与元信息保存在 SQLite 中,查询时将人脸特征加载至内存进行逐个比对。 部署简单、程序将自动创建 SQLite 数据库及相关数据表,无需用户手动配置。 缺点是查询性能有限,随着人脸数量增多,查询耗时显著增加。 |
Milvus 向量数据库 | 适用于人脸数量 大于 1 万 的中大型项目或高性能场景。 Milvus 是一款高性能、专为向量检索设计的开源数据库,支持百万级甚至亿级人脸特征的高效检索。 使用前需要单独部署 Milvus 服务,详细安装及配置请参考 Milvus 官网 (opens new window)。 |
# 如何选择?
如果你的人脸数据量较少、无需高并发查询,推荐使用 SQLite + 内存轮询 模式,部署简单,无需额外依赖。
如果你有较高的性能要求或数据规模较大(例如人脸库规模达数十万甚至百万级),推荐使用 Milvus 向量数据库,实现毫秒级检索能力。
# 人脸库配置
SmartJavaAI 支持两种人脸库方案:Milvus 和 SQLite。无论使用哪种方案,均需配置对应的人脸库参数。
MilvusConfig 和 SQLiteConfig 都继承自统一的父类:VectorDBConfig,在模型初始化阶段统一通过 FaceModelConfig 进行设置。
# Milvus 配置说明
MilvusConfig 的所有字段都有默认值,但如果不显式创建该对象,SmartJavaAI 会默认认为不使用 Milvus,因此不会初始化向量库。
创建MilvusConfig示例:
MilvusConfig vectorDBConfig = new MilvusConfig();
vectorDBConfig.setHost("127.0.0.1");
vectorDBConfig.setPort(19530);
vectorDBConfig.setIdStrategy(IdStrategy.AUTO);
vectorDBConfig.setMetricType(MetricType.IP);
faceModelConfig.setVectorDBConfig(vectorDBConfig);
MilvusConfig字段说明
字段名称 | 字段类型 | 默认值 | 说明 |
---|---|---|---|
host | String | localhost | Milvus服务地址 |
port | int | 19530 | Milvus服务端口 |
collectionName | String | face | Milvus数据集合名称 |
idStrategy | IdStrategy | AUTO | ID 生成策略,支持自动或自定义 |
metricType | MetricType | 相似度计算方式,不同模型有默认策略(如 IP / COSINE) | |
dimension | int | 特征向量维度 ,不同模型有不同的默认维度 | |
type | VectorDBType | 向量数据库类型,父类VectorDBConfig字段 | |
useMemoryCache | boolean | true | 是否使用内存缓存 |
nlist | int | 1024 | IVF 索引的聚类数,影响搜索性能 ,具体请参考Milvus官方文档了解 |
indexType | IndexType | IndexType.IVF_FLAT | Milvus索引类型,具体请参考Milvus官方文档了解 |
IdStrategy枚举说明
枚举值 | 说明 |
---|---|
AUTO | 自动生成ID(默认) |
CUSTOM | 用户自定义 ID(注册时由FaceRegisterInfo中id 指定) |
MetricType枚举说明:(来自 Milvus SDK)
枚举值 | 说明 |
---|---|
None | 无需指定 |
L2 | 欧氏距离 |
IP | 内积 |
COSINE | 余弦相似度 |
其他枚举值较少使用,可参考 Milvus 官方文档 了解。
VectorDBType枚举说明
枚举值 | 说明 |
---|---|
SQLITE | Sqlite,非专用向量库的备用方案 |
MILVUS | Milvus向量数据库 |
注意事项:
1、相似度计算方式:MetricType 影响相似度结果,不建议随意更改。
(1)FaceNet 默认使用 内积(IP)。
(2)SeetaFace6 默认使用 余弦相似度(COSINE)。
2、向量维度(dimension):不建议用户手动修改,应使用模型默认值,否则可能导致搜索失败或精度下降。
3、无需手动设置类型字段(type),SmartJavaAI 会根据传入的配置对象类型(MilvusConfig 或 SQLiteConfig)自动判断所使用的人脸库类型。
# SQLite数据库配置如下:
SQLiteConfig 的所有字段都有默认值,但如果不显式创建该对象,SmartJavaAI 会默认认为不使用 SQLite,因此不会初始化数据库。
创建SQLiteConfig示例:
SQLiteConfig vectorDBConfig = new SQLiteConfig();
vectorDBConfig.setDbPath("/Users/wenjie/Downloads/face.db");
vectorDBConfig.setSimilarityType(SimilarityType.IP);
config.setVectorDBConfig(vectorDBConfig);
SQLiteConfig字段说明
字段名称 | 字段类型 | 默认值 | 说明 |
---|---|---|---|
dbPath | String | 数据库路径(包含文件名称) | |
similarityType | SimilarityType | 相似度计算方式 | |
type | VectorDBType | 向量数据库类型,父类VectorDBConfig字段 |
SimilarityType枚举说明:
枚举值 | 说明 |
---|---|
L2 | 欧氏距离 |
IP | 内积 |
COSINE | 余弦相似度 |
注意事项:
1、相似度计算方式:SimilarityType 影响相似度结果,不建议随意更改。
(1)FaceNet 默认使用 内积(IP)。
(2)SeetaFace6 默认使用 余弦相似度(COSINE)。
2、SQLite数据库路径(dbPath),默认使用 SmartJavaAI 的缓存目录,文件名为 face.db
,缓存路径可参考:缓存使用。
如需自定义数据库路径,可通过如下方式手动设置:
vectorDBConfig.setDbPath("/Users/xxx/Downloads/face.db");
无需手动创建 face.db 文件,SmartJavaAI 会在首次使用时自动创建数据库并初始化所需表结构。
# 人脸库初始化
当FaceModelConfig中的 isAutoLoadFace = true
(默认值)时,系统会在模型创建时异步加载人脸库数据到内存。
你可以通过 faceModel.isLoadFaceCompleted()
方法判断加载是否完成,仅在加载完成后才能调用人脸库相关功能。
如果希望手动控制加载时机,也可以将 isAutoLoadFace
设置为 false
,然后通过显式调用 loadFaceFeatures()
方法将人脸库数据加载到内存。
当然也可以调用 releaseFaceFeatures()
方法来释放内存
⚠️ 注意事项:
- SQLite 模式:必须加载至内存后,才能使用注册、查询等人脸库相关功能。
- Milvus 模式:是否加载数据到内存,并不会影响人脸库相关功能的使用。
# 人脸注册
支持通过图片直接完成注册,内部流程为:人脸检测 → 提取分数最高人脸特征 → 注册到人脸库。
R<String> register(FaceRegisterInfo faceRegisterInfo, String imagePath);
R<String> register(FaceRegisterInfo faceRegisterInfo, BufferedImage sourceImage);
R<String> register(FaceRegisterInfo faceRegisterInfo, byte[] imageData);
也支持使用已提取的人脸特征进行注册:
R<String> register(FaceRegisterInfo faceRegisterInfo, float[] feature);
FaceRegisterInfo字段说明
字段名称 | 字段类型 | 默认值 | 说明 |
---|---|---|---|
id | String | null | 唯一标识 |
metadata | String | null | 人脸元数据 |
# 人脸注册 ID 策略说明
Milvus 模式:
- 当
IdStrategy = AUTO
(默认)时,无需手动设置 ID,系统将自动生成唯一的随机 ID,并返回给用户。 - 当
IdStrategy = CUSTOM
时,用户必须手动指定 ID,且需确保 ID 在人脸库中全局唯一(支持数字或字符串格式)。
- 当
SQLite 模式:
- 若用户未设置 ID,系统将自动生成随机 ID 并返回。
- 若用户手动设置了 ID,系统将使用该 ID 作为唯一标识。
metadata 建议:
建议将
metadata
字段设置为 JSON 格式的字符串,以便后续扩展或按需解析,例如:{ "name": "张三", "group": "员工", "remark": "门禁系统白名单" }
:::
# 人脸更新
支持通过图片直接完成更新,内部流程为:人脸检测 → 提取分数最高人脸特征 → 更新人脸库。
void upsertFace(FaceRegisterInfo faceRegisterInfo, String imagePath);
void upsertFace(FaceRegisterInfo faceRegisterInfo, BufferedImage sourceImage);
void upsertFace(FaceRegisterInfo faceRegisterInfo, byte[] imageData);
也支持使用已提取的人脸特征进行更新:
void upsertFace(FaceRegisterInfo faceRegisterInfo, float[] feature);
FaceRegisterInfo可以查看人脸注册中的字段说明
注意事项:
更新人脸时,FaceRegisterInfo 中的 id 不能为空,系统将根据该 id 查找已注册的人脸数据:
若该 id 已存在,则执行更新操作;
若该 id 不存在,则视为新注册,执行人脸注册流程。
⚠️ 请确保使用的 id 对应的人脸数据已注册,否则将不会进行更新,而是新增注册。
# 人脸查询(1:N)
# 多人脸场景
当图片中存在多个人脸,需要同时查询图片中所有人脸,可以使用如下API: 支持通过图片直接完成查询,内部流程为:人脸检测 → 提取分数最高人脸特征 → 查询人脸库。
R<DetectionResponse> search(String imagePath, FaceSearchParams params);
R<DetectionResponse> search(BufferedImage sourceImage, FaceSearchParams params);
R<DetectionResponse> search(byte[] imageData, FaceSearchParams params);
FaceSearchParams字段说明:
字段名称 | 字段类型 | 默认值 | 说明 |
---|---|---|---|
topK | Integer | 1 | 搜索结果数量 |
threshold | Float | null | 搜索阈值 |
normalizeSimilarity | Boolean | null | 是否对查询结果进行归一化 |
# DetectionResponse字段说明
- 返回并非json格式,仅用于字段讲解
{
"code": 0,
"data": {
"detectionInfoList": [
{
"detectionRectangle": {
"height": 290,
"width": 272,
"x": 299,
"y": 430
},
"faceInfo": {
"faceSearchResults": [ //查询结果
{
"id": "458520100632533898", //人脸ID
"metadata": "{\"name\":\"kana\",\"age\":\"25\"}", //人脸元数据
"similarity": 0.9391172 //人脸相似度
}
],
"feature": [
],
"keyPoints": [
{
"x": 398.610408782959,
"y": 522.2400588989259
},
{
"x": 504.46060943603516,
"y": 519.7643661499025
},
{
"x": 472.5443382263184,
"y": 579.8505973815918
},
{
"x": 412.2943332195282,
"y": 640.1959800720215
},
{
"x": 503.771484375,
"y": 633.2885837554933
}
]
},
"score": 0.9999331
}
]
},
"message": "成功",
"success": true
}
# 单人脸场景
当仅需查询一张图片分数最高人脸,可以使用如下API:
适用于仅包含单张人脸的图像,或存在主次明显的人脸场景。
支持通过图片直接完成查询,内部流程为:人脸检测 → 提取分数最高人脸特征 → 查询人脸库。
R<List<FaceSearchResult>> searchByTopFace(String imagePath, FaceSearchParams params);
R<List<FaceSearchResult>> searchByTopFace(BufferedImage sourceImage, FaceSearchParams params);
R<List<FaceSearchResult>> searchByTopFace(byte[] imageData, FaceSearchParams params);
也支持使用已提取的人脸特征进行查询:
List<FaceSearchResult> search(float[] feature, FaceSearchParams params);
# FaceSearchResult字段说明
- 返回并非json格式,仅用于字段讲解
{
"id": "86dc0262-ea4f-4bff-b00e-b7b608afeb32", //人脸ID
"metadata": "{\"name\":\"iu_update\",\"age\":\"25\"}", //人脸元数据
"similarity": 0.9396009 //人脸相似度
}
# 相似度阈值参考说明
Seetaface6 模型: 官方推荐相似度阈值(
threshold
)为 0.62,大于此值通常可认为是同一个人。实际阈值可根据业务场景适当调整。FaceNet 模型: 相似度一般会先归一化至 [0, 1] 区间,可参考以下经验值判断是否为同一个人:
相似度范围 是否为同一个人(建议参考) ≥ 0.85 几乎可以确定为同一个人 0.80 – 0.85 高度可能为同一个人 0.75 – 0.80 存在可能,建议结合其他因素人工判断 < 0.75 很可能不是同一个人
📌 实际使用中建议根据业务容错性、识别场景(如门禁、人脸检索)灵活设置阈值。
# 人脸删除
- 参数为调用register方法时的id
void removeRegister(String... keys);
# 清空人脸库
long clearFace();
# 活体检测
静默活体识别根据输入的图像数据、人脸位置和人脸特征点,对输入人脸进行活体的判断,并返回人脸活体的状态。
注意事项:
1、活体识别内容增加了对图像清晰度的判断,但是还是有对其他方面的质量要求,比如人脸分辨率128x128以上,光照均匀,自然表情等。其中主要影响识别精度的为光照环境
# 获取活体检测模型:
LivenessConfig config = new LivenessConfig();
config.setModelEnum(LivenessModelEnum.SEETA_FACE6_MODEL);
//需替换为实际模型存储路径
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
LivenessDetModel livenessDetModel = LivenessModelFactory.getInstance().getModel(config);
# LivenessConfig参数说明
字段名称 | 字段类型 | 默认值 | 说明 |
---|---|---|---|
modelEnum | LivenessModelEnum | SEETA_FACE6_MODEL | 模型枚举,目前支持活体检测的模型只有seetaface6模型 |
modelPath | String | NULL | 手动指定离线模型路径 |
faceClarityThreshold | float | 0.3 | 人脸清晰度阈值,可选 |
realityThreshold | float | 0.8 | 人脸活体阈值,可选 |
frameCount | int | 10 | 视频检测帧数,可选(检测视频时有效) |
device | DeviceEnum | CPU | 指定运行设备,支持 CPU/GPU |
注意事项:
1、活体识别时,如果清晰度低的话,就会直接返回:未知(UNKNOWN)。清晰度满足阈值,则判断真实度,超过阈值则认为是真人,低于阈值是非活体。
2、在视频识别模式下,会计算视频帧数内的平均值再跟帧数比较。两个阈值都符合,越高的话,越是严格。
# 图片活体检测(多人脸)
DetectionResponse detect(String imagePath)
DetectionResponse detect(BufferedImage image)
DetectionResponse detect(byte[] imageData)
# DetectionResponse字段说明
- 返回并非json格式,仅用于字段讲解
{
"detectionInfoList": [ // 检测信息列表
{
"detectionRectangle": { //矩形框
"height": 174, // 矩形高度
"width": 147, // 矩形宽度
"x": 275, // 左上角横坐标
"y": 143 // 左上角纵坐标
},
"faceInfo": { // 人脸信息
"keyPoints": [ // 5个人脸关键点:循序依次为,左眼中心、右眼中心、鼻尖、左嘴角和右嘴角
{
"x": 339.5083751678467,
"y": 192.76402664184573
},
{
"x": 404.7374267578125,
"y": 197.89914321899414
},
{
"x": 388.9555263519287,
"y": 231.50675201416016
},
{
"x": 339.8661708831787,
"y": 265.51241302490234
},
{
"x": 397.7071800231933,
"y": 269.7657699584961
}
],
"livenessStatus": "LIVE" //活体检测结果
}
}
]
}
# 图片活体检测(多人脸)- 基于已检测出的人脸区域和关键点
仅返回活体检测结果
List<LivenessStatus> detect(String imagePath, DetectionResponse faceDetectionResponse)
List<LivenessStatus> detect(BufferedImage image,DetectionResponse faceDetectionResponse)
List<LivenessStatus> detect(byte[] imageData,DetectionResponse faceDetectionResponse)
# 图片活体检测(单人脸)- 基于已检测出的人脸区域和关键点
- imagePath:图片路径
- faceDetectionRectangle:人脸检测框(人脸检测返回结果)
- keyPoints:5个人脸关键点(人脸检测返回结果)
LivenessStatus detect(String imagePath, DetectionRectangle faceDetectionRectangle, List<Point> keyPoints)
LivenessStatus detect(BufferedImage image, DetectionRectangle faceDetectionRectangle, List<Point> keyPoints)
LivenessStatus detect(byte[] imageData, DetectionRectangle faceDetectionRectangle, List<Point> keyPoints)
# 图片活体检测(分数最高人脸)
检测图片中分数最高的人脸
LivenessStatus detectTopFace(BufferedImage image)
LivenessStatus detectTopFace(String imagePath)
LivenessStatus detectTopFace(byte[] imageData)
# 视频活体检测
活体检测分为图片模式和视频模式,两种工作模式的区别在于前者属于一帧就是可以返回识别结果,而后者要输入多个视频帧然后返回识别结果。
LivenessStatus detectVideo(InputStream videoInputStream)
LivenessStatus detectVideo(String videoPath)
注意事项:
1、视频活体检测支持常见视频格式(推荐使用mp4),内部使用ffmpeg进行视频解析。
2、输入视频的有效帧数必须 > LivenessConfig 配置参数中 frameCount 的设定值(默认阈值:10帧)
3、若不满足帧数条件,接口将抛出异常
4、输入视频文件过大,会耗费内存,建议视频文件不要过大。
# 视频活体检测(逐帧检测)
LivenessStatus detectVideoByFrame(BufferedImage frameImageData)
LivenessStatus detectVideoByFrame(byte[] frameImageData)
# 视频活体检测(逐帧检测) - 基于已检测出的人脸区域和关键点
LivenessStatus detectVideoByFrame(BufferedImage frameImage, DetectionRectangle faceDetectionRectangle, List<Point> keyPoints)
LivenessStatus detectVideoByFrame(byte[] frameData, DetectionRectangle faceDetectionRectangle, List<Point> keyPoints)
注意事项:
1、在视频活体检测模式下,检测帧数超过frameCount之后,就可以输出识别结果。这个数量相当于多帧识别结果融合的融合的帧数。当检测的帧数超过设定帧数的时候,会采用滑动窗口的方式,返回融合的最近检测的帧融合的识别结果。一般来说,在10以内,帧数越多,结果越稳定,相对性能越好,但是得到结果的延时越高。
# LivenessStatus 活体检测返回结果枚举
枚举值 | 说明 |
---|---|
LIVE | 活体 |
NON_LIVE | 非活体 |
UNKNOWN | 未知,或者人脸清晰度低 |
DETECTING | 视频模式,检测中 |
# 人脸属性检测
人脸属性检测包含:性别、年龄、口罩、眼睛状态(开闭)、脸部姿态(俯仰角,偏航角,翻滚角)
# 获取人脸属性检测模型:
FaceAttributeConfig config = new FaceAttributeConfig();
config.setModelEnum(FaceAttributeModelEnum.SEETA_FACE6_MODEL);
//需替换为实际模型存储路径
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
FaceAttributeModel faceAttributeModel = FaceAttributeModelFactory.getInstance().getModel(config);
# FaceAttributeConfig参数说明
字段名称 | 字段类型 | 默认值 | 说明 |
---|---|---|---|
modelEnum | FaceAttributeModelEnum | SEETA_FACE6_MODEL | 模型枚举,目前支持人脸属性检测的模型只有seetaface6模型 |
modelPath | String | NULL | 手动指定离线模型路径 |
enableAge | boolean | true | 是否启用年龄检测,可选 |
enableGender | boolean | true | 是否启用性别检测,可选 |
enableHeadPose | boolean | true | 是否启用人脸姿态检测,可选 |
enableEyeStatus | boolean | true | 是否启用眼睛状态检测,可选 |
enableMask | boolean | true | 是否启用口罩检测,可选 |
device | DeviceEnum | CPU | 指定运行设备,支持 CPU/GPU |
# 人脸属性检测(多人脸)
返回人脸检测信息+人脸属性
DetectionResponse detect(String imagePath)
DetectionResponse detect(BufferedImage image)
DetectionResponse detect(byte[] imageData)
# DetectionResponse字段说明
- 返回并非json格式,仅用于字段讲解
{
"detectionInfoList": [ // 检测信息列表
{
"detectionRectangle": { //矩形框
"height": 174, // 矩形高度
"width": 147, // 矩形宽度
"x": 275, // 左上角横坐标
"y": 143 // 左上角纵坐标
},
"faceInfo": { // 人脸信息
"faceAttribute": { //人脸属性
"age": 44, //年龄
"genderType": "FEMALE", //性别
"headPose": { //脸部姿态
"pitch": 12.958274,
"roll": 0.19592644,
"yaw": -4.166052
},
"leftEyeStatus": "OPEN",// 左眼开闭
"rightEyeStatus": "OPEN",//右眼开闭
"wearingMask": false //是否戴口罩
},
"keyPoints": [ // 5个人脸关键点:循序依次为,左眼中心、右眼中心、鼻尖、左嘴角和右嘴角
{
"x": 339.5083751678467,
"y": 192.76402664184573
},
{
"x": 404.7374267578125,
"y": 197.89914321899414
},
{
"x": 388.9555263519287,
"y": 231.50675201416016
},
{
"x": 339.8661708831787,
"y": 265.51241302490234
},
{
"x": 397.7071800231933,
"y": 269.7657699584961
}
]
}
}
]
}
# 人脸属性检测(多人脸)- 基于已检测出的人脸区域和关键点
仅返回人脸属性
List<FaceAttribute> detect(String imagePath, DetectionResponse faceDetectionResponse)
List<FaceAttribute> detect(BufferedImage image,DetectionResponse faceDetectionResponse)
List<FaceAttribute> detect(byte[] imageData,DetectionResponse faceDetectionResponse)
# 人脸属性检测(单人脸)- 基于已检测出的人脸区域和关键点
- imagePath:图片路径
- faceDetectionRectangle:人脸检测框(人脸检测返回结果)
- keyPoints:5个人脸关键点(人脸检测返回结果)
FaceAttribute detect(String imagePath, DetectionRectangle faceDetectionRectangle, List<Point> keyPoints)
FaceAttribute detect(BufferedImage image, DetectionRectangle faceDetectionRectangle, List<Point> keyPoints)
FaceAttribute detect(byte[] imageData, DetectionRectangle faceDetectionRectangle, List<Point> keyPoints)
# 人脸属性检测(分数最高人脸)
检测图片中分数最高的人脸
LivenessStatus detectTopFace(BufferedImage image)
LivenessStatus detectTopFace(String imagePath)
LivenessStatus detectTopFace(byte[] imageData)
# FaceAttribute 字段讲解
字段名称 | 字段类型 | 说明 |
---|---|---|
genderType | GenderType | 性别枚举 |
age | Integer | 年龄 |
leftEyeStatus | EyeStatus | 左眼状态 |
rightEyeStatus | EyeStatus | 右眼状态 |
wearingMask | Boolean | 是否带口罩 |
headPose | HeadPose | 姿态 |
# GenderType 性别枚举
枚举值 | 说明 |
---|---|
MALE | 男 |
FEMALE | 女 |
UNKNOWN | 未知 |
# EyeStatus 眼睛状态枚举
枚举值 | 说明 |
---|---|
OPEN | 睁眼 |
CLOSED | 闭眼 |
NON_EYE_REGION | 非眼部区域 |
UNKNOWN | 未知 |
# HeadPose 姿态检测结果字段讲解
字段名称 | 字段类型 | 说明 |
---|---|---|
pitch | Float | 上下(俯仰角),正值抬头,负值低头 (-90°~+90°) |
yaw | Float | 左右(偏航角),正值右偏,负值左偏(-90°~+90°) |
roll | Float | 倾斜(翻滚角),正值右倾,负值左倾(-90°~+90°) |
# 绘制人脸属性检测结果并导出图片
通过 SmartJavaAI 提供的工具类 FaceUtils,你可以轻松地将检测到的人脸框和属性信息绘制到图片上,并导出保存。示例代码如下:
image:待处理的原始图像对象。
detectionResponse:人脸检测与属性识别的响应结果。
第三个参数为导出的目标文件路径(支持 PNG/JPG 格式)。
该方法将自动在图像上绘制人脸框、性别、年龄等属性信息,并将结果保存到指定路径。
FaceUtils.drawBoxesWithFaceAttribute(image, detectionResponse,"C:/Users/Administrator/Downloads/double_person_.png");
# 完整示例代码
# 离线使用
1、首次运行,会自动下载模型及底层依赖库到缓存目录中。缓存路径请看文档:离线使用
2、seetaface6需要手动下载模型,其他模型调用都会自动下载,如果因网络问题下载失败,请手动下载模型,并放置到缓存目录中
3、可以在联网环境中运行程序一次,确保所需的依赖库已下载。然后将缓存目录复制到离线环境中相同的路径下,即可实现离线使用