# 人脸识别

# 简介

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 策略说明

  1. Milvus 模式:

    • IdStrategy = AUTO(默认)时,无需手动设置 ID,系统将自动生成唯一的随机 ID,并返回给用户。
    • IdStrategy = CUSTOM 时,用户必须手动指定 ID,且需确保 ID 在人脸库中全局唯一(支持数字或字符串格式)。
  2. SQLite 模式:

    • 若用户未设置 ID,系统将自动生成随机 ID 并返回。
    • 若用户手动设置了 ID,系统将使用该 ID 作为唯一标识。
  3. 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 //人脸相似度
}

# 相似度阈值参考说明

  1. Seetaface6 模型: 官方推荐相似度阈值(threshold)为 0.62,大于此值通常可认为是同一个人。实际阈值可根据业务场景适当调整。

  2. 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");

# 完整示例代码

示例代码 (opens new window)

# 离线使用

1、首次运行,会自动下载模型及底层依赖库到缓存目录中。缓存路径请看文档:离线使用

2、seetaface6需要手动下载模型,其他模型调用都会自动下载,如果因网络问题下载失败,请手动下载模型,并放置到缓存目录中

3、可以在联网环境中运行程序一次,确保所需的依赖库已下载。然后将缓存目录复制到离线环境中相同的路径下,即可实现离线使用