人脸识别

  • 一、相关概念
    • 人脸
    • 人脸库
    • 人脸特征标识(face_token)
    • 并发 (QPS)
    • API Key
    • API Secret
    • confidence
    • thresholds
    • 人脸比对/人脸搜索(控制台分析)
      • 人脸检测
      • 人脸搜索
      • 人脸对比
  • 二、Web API
    • face++里注册账号
      • 创建API Key
    • postman调用API接口
      • 人脸检测
      • 人脸对比
        • 使用face_token参数进行对比
      • 人脸搜索
      • 创建人脸库
      • 添加人脸
      • 获取人脸信息:
      • 删除人脸
  • 三、刷脸登录
    • 代码

一、相关概念

人脸

人脸(Face)在人脸识别技术中特指图像中发现的人脸,当对一张图片进行人脸检测时,会将检测到的人脸记录下来,包括人脸在图片中的位置,用一个系统标识 face_token 来表示。注意:对同一张图片进行多次人脸检测,对同一个人脸会得到不同的 face_token。

人脸库

人脸库(FaceSet)是用来存储检测到人脸的存储对象。一个 FaceSet 内的 face_token 是不重复的。

人脸特征标识(face_token)

  • Face_token 是系统为人脸分配的唯一标识。当对一张图片进行人脸检测后,检测到的人脸以及人脸在图片中的位置会用一个用一个人脸特征标识 face_token 来表示。在进行人脸比对或人脸关键点检测时必须指定 face_token。
  • 针对同一张图片进行多次人脸检测,同一个人脸会得到不同的人脸特征标识 (face_token) 。

并发 (QPS)

并发 (QPS) 指每秒可以发起的 API 请求次数。调用同一个功能模块下的各个 API ,会统一计算 QPS。例如人脸识别并发 (QPS) 为 10 个,人脸识别包括人脸检测 API、人脸比对 API、人脸搜索API、人脸库管理 API 组、获取人脸信息 API 和自定义人脸信息 API,则每秒可以发起 10 次 API 调用请求,不限制具体调用了哪一个 API。超过 10 次请求,将返回 403 并发超限错误码 (CONCURRENCY_LIMIT_EXCEEDED)。

API Key

  • API Key 是使用公有云 API 和联网授权 SDK 服务的凭证。注册账号后,需要先创建一个 API Key,才能进行接口调用服务。
  • API Key 分为试用(免费)与正式(服务)两种类型,试用 API Key 在创建数量、使用的服务类型和并发 (QPS) 保障上均有限制。

API Secret

API Secret 是在创建 API Key 时随机生成的一串密钥,需要和 API Key 搭配,获取使用 API 的权限,请您妥善保管记录。

confidence

比对结果置信度,范围 [0,100],小数点后3位有效数字,数字越大表示两个人脸越可能是同一个人

thresholds

  • 一组用于参考的置信度阈值,包含以下三个字段。每个字段的值为一个 [0,100] 的浮点数,小数点后 3 位有效数字。

    • 1e-3:误识率为千分之一的置信度阈值;
    • 1e-4:误识率为万分之一的置信度阈值;
    • 1e-5:误识率为十万分之一的置信度阈值;
  • 如果置信值低于“千分之一”阈值则不建议认为是同一个人;如果置信值超过“十万分之一”阈值,则是同一个人的几率非常高。

  • 阈值不是静态的,每次比对返回的阈值不保证相同,所以没有持久化保存阈值的必要,更不要将当前调用返回的 confidence 与之前调用返回的阈值比较。

  • 如果传入图片但图片中未检测到人脸,则无法进行比对,本字段不返回。

人脸比对/人脸搜索(控制台分析)

  • 计算机检测到图片中一个人脸之后,通过人脸判断人身份的过程被称为人脸比对/人脸搜索。

  • 人脸比对指采集新的人脸,与一个已知身份用户的人脸进行比对,判断新的人脸是否属于该已知身份用户。人脸比对需要调用人脸比对 API。

  • 人脸搜索是指采集用户新的人脸,在多个已知身份用户的人脸集合中进行搜索,找出新的人脸属于哪一个已知身份用户。人脸搜索需要调用人脸搜索API。

人脸检测

检测到了人脸会产生一个"face_token"

并且产生"face_num",这里有两个人脸,因此为2

如图:人脸数为3,小狗不会被识别到

人脸搜索


搜索结果:

人脸对比

如图:

产生了"confidence"和"le-5"
因为此时"confidence"的值大于"le-5"的值,所以分析结果如下图:

再比如:

因为此时"confidence"的值小于"le-5"的值,所以分析结果如下图:

二、Web API

face++里注册账号

  • 首先:搜索face++
  • 官网: face++
  • 登录或注册
  • 点击进入控制台

    如图:

创建API Key

  • 要调用 API,需要先创建一个 API Key(API 密钥),它是使用 API 和 SDK 的凭证注册验证成功后,可以在欢迎页面点击“创建我的第一个应用”,一个免费API Key会被自动生成,可以直接使用
  • 免费API key 可依据免费规则调用API,如果希望使用付费版服务,需创建正式API Key

  • 如图:创建完成
  • 后续代码要用到这两个值

postman调用API接口

人脸检测

  • 概述:
    传入图片进行人脸检测和人脸分析。
    可以检测图片内的所有人脸,对于每个检测出的人脸,会给出其唯一标识 face_token,可用于后续的人脸分析、人脸比对等操作。对于正式 API Key,支持指定图片的某一区域进行人脸检测。

  • 本 API 支持对检测到的人脸直接进行分析,获得人脸的关键点和各类属性信息。对于试用 API Key,最多只对人脸框面积最大的 5 个人脸进行分析,其他检测到的人脸可以使用 Face Analyze API 进行分析。对于正式 API Key,支持分析所有检测到的人脸。

  • 关于 face_token
    如果需要将检测出的人脸用于后续的分析、比对等操作,建议将对应的 face_token 添加到 FaceSet 中。如果一个 face_token 在 72 小时内没有存放在任一 FaceSet 中,则该 face_token 将会失效。如果对同一张图片进行多次人脸检测,同一个人脸得到的 face_token 是不同的。

  • 调用URL
    https://api-cn.faceplusplus.com/facepp/v3/detect

  • 调用方法
    POST

  • 请求体格式
    multipart/form-data

请求参数(必选):

参数名 参数说明
api_key 调用此API的API Key
api_secret 调用此API的API Secret

以下参数三选一(必选):

参数名 参数说明
image_url 图片的 URL
image_file 一个图片,二进制文件,需要用post multipart/form-data的方式上传
image_base64 base64 编码的二进制图片数据如果同时传入了 image_url、image_file 和 image_base64 参数,本API使用顺序为 image_file 优先,image_url 最低

如下图:

选择的参数为:
api_key
api_secret
image_file产生了face_token,face_num等..

选择的图片参数为:

结果:
检测到一张人脸

再换张图:


结果检测到3张脸:

返回值说明

字段 说明
request_id 用于区分每一次请求的唯一的字符串。
faces 被检测出的人脸数组
image_id 被检测的图片在系统中的标识。
time_used 整个请求所花费的时间,单位为毫秒。
error_message 当请求失败时才会返回此字符串,具体返回内容见后续错误信息章节。否则此字段不存在
face_num 检测出的人脸个数

faces 数组中单个元素的结构

字段 说明
face_token 人脸的标识
face_rectangle 人脸矩形框的位置,包括以下属性。每个属性的值都是整数:1.top:矩形框左上角像素点的纵坐标 2.left:矩形框左上角像素点的横坐标 3.width:矩形框的宽度 4.height:矩形框的高度
landmark 人脸的关键点坐标数组。当传入的 landmark 参数值为 1 时,返回 83 个关键点坐标数组。当传入的 landmark 参数值为 2 时,返回 106 个关键点坐标数组。

人脸对比

  • 描述:
    将两个人脸进行比对,来判断是否为同一个人,返回比对结果置信度和不同误识率下的阈值。

  • 支持传入图片或 face_token 进行比对。使用图片时会自动选取图片中检测到人脸尺寸最大的一个人脸。

  • 调用 URL
    https://api-cn.faceplusplus.com/facepp/v3/compare

  • 调用方法
    POST

  • 请求体格式
    multipart/form-data

请求参数(必选):

参数名 参数说明
api_key 调用此API的API Key
api_secret 调用此API的API Secret

以下参数四选一(必选):

参数名 参数说明
face_token1 第一个人脸标识 face_token,优先使用该参数
image_url1 第一张图片的 URL
image_file1 第一张图片,二进制文件,需要用 post multipart/form-data 的方式上传。
image_base64_1 base64 编码的二进制图片数据如果同时传入了 image_url1、image_file1 和 image_base64_1 参数,本 API 使用顺序为image_file1 优先,image_url1 最低。

以下参数四选一(必选):

参数名 参数说明
face_token2 第二个人脸标识 face_token,优先使用该参数
image_url2 第二张图片的 URL
image_file2 第二张图片,二进制文件,需要用 post multipart/form-data 的方式上传。
image_base64_2 base64 编码的二进制图片数据如果同时传入了 image_url2、image_file2 和 image_base64_2 参数,本API 使用顺序为 image_file2优先,image_url2 最低。

如图:对比这两张图:

选择的参数为:
api_key
api_secret
image_file1
image_file2产生了confidence,thresholds等..

结果:
因为此时"confidence"的值小于"le-5"的值,所以分析结果很大概率为不是同一个人:

再比如这两张图:


结果:
因为此时"confidence"的值大于"le-5"的值,所以分析结果很大概率为同一个人:

使用face_token参数进行对比

  • 对比上两张人脸
    先检索需对比的第一张人脸得到face_token:

  • 再检索需对比的第二张人脸得到face_token:

  • 结果:
    因为此时"confidence"的值大于"le-5"的值,所以分析结果很大概率为同一个人:

返回值说明

字段 说明
request_id 用于区分每一次请求的唯一的字符串。
confidence 比对结果置信度,范围 [0,100],小数点后3位有效数字,数字越大表示两个人脸越可能是同一个人。注:如果传入图片但图片中未检测到人脸,则无法进行比对,本字段不返回。
thresholds 一组用于参考的置信度阈值,包含以下三个字段。每个字段的值为一个 [0,100] 的浮点数,小数点后 3 位有效数字。1e-3:误识率为千分之一的置信度阈值;1e-4:误识率为万分之一的置信度阈值;1e-5:误识率为十万分之一的置信度阈值;如果置信值低于“千分之一”阈值则不建议认为是同一个人;如果置信值超过“十万分之一”阈值,则是同一个人的几率非常高。请注意:阈值不是静态的,每次比对返回的阈值不保证相同,所以没有持久化保存阈值的必要,更不要将当前调用返回的 confidence 与之前调用返回的阈值比较。注:如果传入图片但图片中未检测到人脸,则无法进行比对,本字段不返回。
image_id1 通过 image_url1、image_file1 或 image_base64_1 传入的图片在系统中的标识。注:如果未传入图片,本字段不返回。
image_id2 通过 image_url2、image_file2 或 image_base64_2 传入的图片在系统中的标识。注:如果未传入图片,本字段不返回。
faces1 通过 image_url1、image_file1 或 image_base64_1 传入的图片中检测出的人脸数组,采用数组中的第一个人脸进行人脸比对。注:如果未传入图片,本字段不返回。如果没有检测出人脸则为空数组
faces2 通过 image_url2、image_file2 或 image_base64_2 传入的图片中检测出的人脸数组,采用数组中的第一个人脸进行人脸比对。注:如果未传入图片,本字段不返回。如果没有检测出人脸则为空数组
time_used 整个请求所花费的时间,单位为毫秒。
error_message 当请求失败时才会返回此字符串,具体返回内容见后续错误信息章节。否则此字段不存在

人脸搜索

  • 描述:
    在一个已有的 FaceSet 中找出与目标人脸最相似的一张或多张人脸,返回置信度和不同误识率下的阈值。

  • 支持传入图片或 face_token 进行人脸搜索。使用图片进行搜索时会选取图片中检测到人脸尺寸最大的一个人脸。

  • 调用URL
    https://api-cn.faceplusplus.com/facepp/v3/search

  • 调用方法
    POST

  • 请求体格式
    multipart/form-data

请求参数(必选):

参数名 参数说明
api_key 调用此API的API Key
api_secret 调用此API的API Secret

以下参数四选一(必选):

参数名 参数说明
face_token 进行搜索的目标人脸的 face_token,优先使用该参数
image_url 图片的 URL
image_file 一个图片,二进制文件,需要用post multipart/form-data的方式上传
image_base64 base64 编码的二进制图片数据如果同时传入了 image_url、image_file 和 image_base64 参数,本API使用顺序为 image_file 优先,image_url 最低

以下参数二选一(必选):

参数名 参数说明
faceset_token 用来搜索的 FaceSet 的标识
outer_id 用户自定义的 FaceSet 标识

返回值说明

字段 说明
request_id 用于区分每一次请求的唯一的字符串。
results 搜索结果对象数组 注:如果传入图片但图片中未检测到人脸,则无法进行人脸搜索,本字段不返回。
thresholds 一组用于参考的置信度阈值,包含以下三个字段。每个字段的值为一个 [0,100] 的浮点数,小数点后 3 位有效数字。1e-3:误识率为千分之一的置信度阈值;1e-4:误识率为万分之一的置信度阈值;1e-5:误识率为十万分之一的置信度阈值;如果置信值低于“千分之一”阈值则不建议认为是同一个人;如果置信值超过“十万分之一”阈值,则是同一个人的几率非常高。请注意:阈值不是静态的,每次比对返回的阈值不保证相同,所以没有持久化保存阈值的必要,更不要将当前调用返回的 confidence 与之前调用返回的阈值比较。注:如果传入图片但图片中未检测到人脸,则无法进行比对,本字段不返回。
image_id 传入的图片在系统中的标识。注:如果未传入图片,本字段不返回。
faces 传入的图片中检测出的人脸数组,采用数组中的第一个人脸进行人脸搜索。注:如果未传入图片,本字段不返回。如果没有检测出人脸则为空数组
time_used 整个请求所花费的时间,单位为毫秒。
error_message 当请求失败时才会返回此字符串,具体返回内容见后续错误信息章节。否则此字段不存在

results 数组中单个元素的结构

字段 说明
face_token 从 FaceSet 中搜索出的一个人脸标识 face_token。
confidence 比对结果置信度,范围 [0,100],小数点后3位有效数字,数字越大表示两个人脸越可能是同一个人。
user_id 用户提供的人脸标识,如果未提供则为空。

创建人脸库

  • 描述:
    创建一个人脸的集合 FaceSet,用于存储人脸标识 face_token。一个 FaceSet 能够存储10000个 face_token。

  • 试用API Key可以创建1000个FaceSet,正式API Key可以创建10000个FaceSet。

  • 调用URL
    https://api-cn.faceplusplus.com/facepp/v3/faceset/create

  • 调用方法
    POST

请求参数(必选):

参数名 参数说明
api_key 调用此API的API Key
api_secret 调用此API的API Secret

请求参数(非必选):

参数名 参数说明
outer_id 账号下全局唯一的 FaceSet 自定义标识,可以用来管理 FaceSet 对象。最长255个字符,不能包括字符^@,&=*'"
选择的参数为:
api_key
api_secret
outer_id产生了outer_id等..

如图:

返回值说明

字段 说明
request_id 用于区分每一次请求的唯一的字符串。除非发生404(API_NOT_FOUND ) 或403 (AUTHORIZATION_ERROR)错误,此字段必定返回。
faceset_token FaceSet 的标识
outer_id 用户自定义的 FaceSet 标识,如果未定义则返回值为空
face_added 本次操作成功加入 FaceSet的face_token 数量
face_count 操作结束后 FaceSet 中的 face_token 总数量
failure_detail 无法被加入 FaceSet 的 face_token 以及原因face_token:人脸标识reason:不能被添加的原因,包括 INVALID_FACE_TOKEN 人脸表示不存在 ,QUOTA_EXCEEDED 已达到 FaceSet 存储上限
time_used 整个请求所花费的时间,单位为毫秒。
error_message 当请求失败时才会返回此字符串,具体返回内容见后续错误信息章节。否则此字段不存在

添加人脸

  • 描述
    为一个已经创建的 FaceSet 添加人脸标识 face_token。一个 FaceSet 最多存储1,000个 face_token。

  • 调用 URL
    https://api-cn.faceplusplus.com/facepp/v3/faceset/addface

  • 调用方法
    POST

请求参数(必选):

参数名 参数说明
api_key 调用此API的API Key
api_secret 调用此API的API Secret

以下参数二选一(必选):

参数名 参数说明
faceset_token 用来搜索的 FaceSet 的标识
outer_id 用户自定义的 FaceSet 标识

请求参数(必选):

参数名 参数说明
face_tokens 人脸标识 face_token 组成的字符串,可以是一个或者多个,用逗号分隔。最多不超过5个face_token
1.先进行人脸检测
选择的参数为:
api_key
api_secret
image_file产生了face_token,face_num等..

如图:

2.将人脸检测后的face_token存储到faceset
选择的参数为:
api_key
api_secret
outer_id
face_token产生了face_count等..

如图:

返回值说明

字段 说明
request_id 用于区分每一次请求的唯一的字符串。除非发生404(API_NOT_FOUND ) 或403 (AUTHORIZATION_ERROR)错误,此字段必定返回。
faceset_token FaceSet 的标识
outer_id 用户自定义的 FaceSet 标识,如果未定义则返回值为空
face_added 本次操作成功加入 FaceSet的face_token 数量
face_count 操作结束后 FaceSet 中的 face_token 总数量
failure_detail 无法被加入 FaceSet 的 face_token 以及原因face_token:人脸标识reason:不能被添加的原因,包括 INVALID_FACE_TOKEN 人脸表示不存在 ,QUOTA_EXCEEDED 已达到 FaceSet 存储上限
time_used 整个请求所花费的时间,单位为毫秒。
error_message 当请求失败时才会返回此字符串,具体返回内容见后续错误信息章节。否则此字段不存在

获取人脸信息:

描述
获取一个 FaceSet 的所有信息,包括此 FaceSet 的 faceset_token, outer_id, display_name 的信息,以及此 FaceSet 中存放的 face_token 数量与列表。

调用URL
https://api-cn.faceplusplus.com/facepp/v3/faceset/getdetail

调用方法
POST
请求参数(必选):

参数名 参数说明
api_key 调用此API的API Key
api_secret 调用此API的API Secret

以下参数二选一(必选):

参数名 参数说明
faceset_token 用来搜索的 FaceSet 的标识
outer_id 用户自定义的 FaceSet 标识
选择的参数为:
api_key
api_secret
outer_id产生了face_tokens等..face_tokens是一个数组,里面装了faceset里的face_token
  • 如图:
  • 再往faceset里存一张人脸:

  • 如图:检测到了两张人脸

返回值说明

字段 说明
request_id 用于区分每一次请求的唯一的字符串。除非发生404(API_NOT_FOUND ) 或403 (AUTHORIZATION_ERROR)错误,此字段必定返回。
faceset_token FaceSet 的标识
outer_id 用户自定义的 FaceSet 标识,如果未定义则返回值为空
display_name 人脸集合的名字
user_data 自定义用户信息
tags 自定义标签
face_count 操作结束后 FaceSet 中的 face_token 总数量
face_tokens face_token的数组 注:如果该 FaceSet 下没有 face_token,则返回空数组。
next 用于进行下一次请求。返回值表示排在此次返回的所有 face_token 之后的下一个 face_token 的序号。如果返回此字段,则说明未返回完此 FaceSet 下的所有 face_token。可以将此字段的返回值,在下一次调用时传入 start 字段中,获取接下来的 face_token。如果没有返回该字段,则说明已经返回此 FaceSet 下的所有 face_token。
time_used 整个请求所花费的时间,单位为毫秒。
error_message 当请求失败时才会返回此字符串,具体返回内容见后续错误信息章节。否则此字段不存在

删除人脸

  • 描述
    移除一个FaceSet中的某些或者全部face_token

  • 调用URL
    https://api-cn.faceplusplus.com/facepp/v3/faceset/removeface

  • 调用方法
    POST

请求参数(必选):

参数名 参数说明
api_key 调用此API的API Key
api_secret 调用此API的API Secret

以下参数二选一(必选):

参数名 参数说明
faceset_token 用来搜索的 FaceSet 的标识
outer_id 用户自定义的 FaceSet 标识

请求参数(必选):

参数名 参数说明
face_tokens 需要移除的人脸标识字符串,可以是一个或者多个face_token组成,用逗号分隔。最多不能超过1,000个face_token注:face_tokens字符串传入“RemoveAllFaceTokens”则会移除FaceSet内所有的face_token

如图:
此时搜索到有两张人脸

删除人脸


选择的参数为:
api_key
api_secret
outer_id
face_tokensface_tokens可以在获取人脸里得到
产生了face_count等..


结果:
删除一张人脸后再获取一次
只剩一张人脸了

返回值说明

字段 说明
request_id 用于区分每一次请求的唯一的字符串。除非发生404(API_NOT_FOUND ) 或403 (AUTHORIZATION_ERROR)错误,此字段必定返回。
faceset_token FaceSet 的标识
outer_id 用户自定义的 FaceSet 标识,如果未定义则返回值为空
face_removed 成功从FaceSet中移除的face_token数量
face_count 操作结束后 FaceSet 中的 face_token 总数量
failure_detail 无法从FaceSet中移除的face_token以及原因face_token:人脸标识reason:不能被移除的原因,包括 INVALID_FACE_TOKEN 人脸标识不存在
time_used 整个请求所花费的时间,单位为毫秒。除非发生404(API_NOT_FOUND )或403 (AUTHORIZATION_ERROR)错误,此字段必定返回。
error_message 当请求失败时才会返回此字符串,具体返回内容见后续错误信息章节。否则此字段不存在

三、刷脸登录

  • 录入人脸信息,通过人脸检测接口得到face_token,存入outer_id=travel_faceset的faceset中当用户在登录的时候,得到用户当前登录图片,然后用人脸比对接口用当前登录图片和之前在
    faceset中保存的人脸信息进行比对。
  • 比对后的返回信息有我们设置的阈值(thresholds),可以根据自身的需求选择其中一个阈值,当相似度(confidence)高于这个阈值时就可以认为是同一个人,即可以登录成功,反之,不能登录成功。

代码

  • 添加依赖:
<dependency><groupId>org.reactivestreams</groupId><artifactId>reactive-streams</artifactId><version>1.0.3</version>
</dependency>
  • yml配置文件:
face:config:api-key: jlTzV7I-pWQoqHFXWUUgv312jTpS17FCapi-secret: eDULPcfETWuoRT9I4q51mvhlVpj_ECBpouter-id: link_faceset
  • 配置启动类:

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@SpringBootApplication
public class TravelApplication {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}public static void main(String[] args) {SpringApplication.run(TravelApplication.class, args);}
}
  • FaceDao
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;import java.nio.file.Paths;
import java.util.List;/*** 用于访问face++人脸系统*/
@ConfigurationProperties("face.config")
@Component
@Getter
@Setter
public class FaceDao {@Autowiredprivate RestTemplate restTemplate;private String apiKey;private String apiSecret;private String outerId;/*** 人脸检测*/public DetectResponseEntity detect(String filePath) {HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 多部件表单体MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder();// ----------------- 表单 partmultipartBodyBuilder.part("api_key", apiKey);multipartBodyBuilder.part("api_secret", apiSecret);// ----------------- 文件 part// 从磁盘读取文件multipartBodyBuilder.part("image_file", new FileSystemResource(Paths.get(filePath)), MediaType.IMAGE_PNG);// build完整的消息体MultiValueMap<String, HttpEntity<?>> multipartBody = multipartBodyBuilder.build();ResponseEntity<DetectResponseEntity> responseEntity = restTemplate.postForEntity("https://api-cn.faceplusplus.com/facepp/v3/detect", multipartBody, DetectResponseEntity.class);return responseEntity.getBody();}/*** 创建faceset*/public void faceSetCreate() {HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);MultiValueMap<String, String> map= new LinkedMultiValueMap<>();map.add("api_key", apiKey);map.add("api_secret", apiSecret);map.add("outer_id", outerId);HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);restTemplate.postForEntity("https://apicn.faceplusplus.com/facepp/v3/faceset/create", request, String.class);}/*** 得到outer_id=trave_faceset的信息*/public FaceSetResponseEntity getFaceSetDetail() {HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);MultiValueMap<String, String> map= new LinkedMultiValueMap<>();map.add("api_key", apiKey);map.add("api_secret", apiSecret);map.add("outer_id", outerId);HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);ResponseEntity<FaceSetResponseEntity> responseEntity = restTemplate.postForEntity("https://apicn.faceplusplus.com/facepp/v3/faceset/getdetail", request, FaceSetResponseEntity.class);return responseEntity.getBody();}/*** 添加faceToken到FaceSet* 人脸标识 faceTokens 组成的字符串,可以是一个或者多个,用逗号分隔。最多不超过5个face_token* @param faceTokens*/public void addFaceToFaceSet(String faceTokens) {HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);MultiValueMap<String, String> map= new LinkedMultiValueMap<>();map.add("api_key", apiKey);map.add("api_secret", apiSecret);map.add("outer_id", outerId);map.add("face_tokens", faceTokens);HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);restTemplate.postForEntity("https://apicn.faceplusplus.com/facepp/v3/faceset/addface", request, String.class);}/*** 人脸比对* @param faceToken1* @param faceToken2* @return*/public boolean compareFace(String faceToken1, String faceToken2) {HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 多部件表单体MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder();// ----------------- 表单 partmultipartBodyBuilder.part("api_key", apiKey);multipartBodyBuilder.part("api_secret", apiSecret);multipartBodyBuilder.part("face_token1", faceToken1);multipartBodyBuilder.part("face_token2", faceToken2);// ----------------- 文件 part// 从磁盘读取文件// multipartBodyBuilder.part("image_file", new FileSystemResource(Paths.get(filePath)), MediaType.IMAGE_PNG);// build完整的消息体MultiValueMap<String, HttpEntity<?>> multipartBody = multipartBodyBuilder.build();ResponseEntity<CompareResponseEntity> responseEntity = restTemplate.postForEntity("https://api-cn.faceplusplus.com/facepp/v3/compare", multipartBody, CompareResponseEntity.class);System.out.println(responseEntity);CompareResponseEntity e = responseEntity.getBody();if (e.getConfidence() >= e.getThresholds().e5) {return true;} else {return false;}}/*** 人脸比对返回实体类*/@Datapublic static class CompareResponseEntity {private Double confidence;private ThresholdsResponseEntity thresholds;}/*** 人脸对比置信度阈值返回实体类*/@Datapublic static class ThresholdsResponseEntity {@JsonProperty("1e-5")private Double e5;}/*** FaceSet返回实体类*/@Datapublic static class FaceSetResponseEntity{private String faceset_token;private String outer_id;private Integer face_count;private List<String> face_tokens;}@Data
/*** 人脸检测返回数据实体类*/public static class DetectResponseEntity {private String request_id;private Integer face_num;private List<FaceEntity> faces;}@Data/*** 人脸实体类*/public static class FaceEntity {private String face_token;}
}
  • FaceDaoTest

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class FaceDaoTest {@Autowiredprivate FaceDao faceDao;@Testpublic void detect() {FaceDao.DetectResponseEntity e = faceDao.detect("C:\\Users\\Administrator\\Desktop\\29.jpg");System.out.println(e);}@Testpublic void getFaceSetDetail() {FaceDao.FaceSetResponseEntity e = faceDao.getFaceSetDetail();System.out.println(e);}@Testpublic void createFaceSet() {faceDao.faceSetCreate();}@Testpublic void addFaceToFaceSet() {faceDao.addFaceToFaceSet("fb9929c6da2f035f6cf647cc78ab7675");}@Testpublic void campareFace() {boolean b = faceDao.compareFace("d64dc956a6be7c07ebaa3093923a66fa", "10447d93dd700e3f98c0a981c879c99d");System.out.println(b);}}
  • FaceService
public interface FaceService {public void addFace(String filePath);public boolean loginByFace(String filePath);
}
  • FaceServiceImpl

import com.lrk.travel.dao.FaceDao;
import com.lrk.travel.service.FaceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.File;
@Service
public class FaceServiceImpl implements FaceService {@Autowiredprivate FaceDao faceDao;@Overridepublic void addFace(String filePath) {FaceDao.FaceSetResponseEntity fs = null;try {fs = faceDao.getFaceSetDetail();} catch (Exception e) {}if (fs == null) { //faceset不存在faceDao.faceSetCreate();}FaceDao.DetectResponseEntity dr = faceDao.detect(filePath); //检视人脸for (FaceDao.FaceEntity f : dr.getFaces()) {faceDao.addFaceToFaceSet(f.getFace_token());}}@Overridepublic boolean loginByFace(String filePath) {boolean result = false;FaceDao.FaceSetResponseEntity fs = null;try {fs = faceDao.getFaceSetDetail();} catch (Exception e) {}if (fs == null) { //faceset不存在faceDao.faceSetCreate();fs = faceDao.getFaceSetDetail();}FaceDao.DetectResponseEntity dr = faceDao.detect(filePath); //检视人脸String ft1 = null;if (dr.getFace_num() >=1) {ft1 = dr.getFaces().get(0).getFace_token();} else {return false;}for (String ft2: fs.getFace_tokens()) {if (faceDao.compareFace(ft1, ft2)) {result = true;}}new File(filePath).delete(); //删除登录人脸return result;}}
  • FaceController

import com.lrk.travel.service.FaceService;
import com.lrk.travel.utils.ImageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.UUID;
@Controller
@RequestMapping("/admin/face")
public class FaceController {@Autowiredprivate FaceService faceService;/*** 调到录入人脸页面* @return*/@RequestMapping("/toinput")public String toInput() {return "/face/input";}@RequestMapping("/tologin")public String toLogin() {return "/face/login";}/*** 录入人脸* @param imgData* @param request* @return* @throws IOException*/@ResponseBody@RequestMapping("/upload")public ResponseEntity doAdd(@RequestParam("imgData") String imgData, HttpServletRequest request) throws IOException {String savePath = request.getServletContext().getRealPath("img/face/");String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".png";System.out.println(savePath);ImageUtils.generateImage(imgData.substring(22), savePath, fileName);faceService.addFace(savePath + fileName);return ResponseEntity.ok("{\"success\": \"true\"}");}/*** 人脸识别登录* @param imgData* @param request* @return* @throws IOException*/@ResponseBody@RequestMapping("/login")public ResponseEntity login(@RequestParam("imgData") String imgData,HttpServletRequest request) throws IOException {String savePath =request.getServletContext().getRealPath("img/face/login/");String fileName = UUID.randomUUID().toString().replaceAll("-", "") +".png";System.out.println(savePath);ImageUtils.generateImage(imgData.substring(22), savePath, fileName);boolean b = faceService.loginByFace(savePath + fileName);if (b) {System.out.println("登录成功");return ResponseEntity.ok("{\"success\": true}");} else {System.out.println("登录失败");return ResponseEntity.ok("{\"success\": false}");}}}

人脸识别-Java实现刷脸登录相关推荐

  1. 人脸识别入学注册 刷脸时代来临

    科技改变生活,从"现金还是刷卡"到"微信还是支付宝",到目前为止,我们几乎带脸出门就可以了,"没钱付账,和老板那么熟,刷个脸就行"从前的调侃 ...

  2. 人脸识别应用于刷脸考勤的设计与效果

    人脸识别应用于刷脸考勤的设计与效果 人脸识别在心通达OA中应用于刷脸考勤,技术采用的是Face SDK针对手机移动设备的人脸技术开发包,开发包SDK包含人脸检测.活体识别等功能.基于该技术,心通达OA ...

  3. 2018杭州·云栖大会人脸识别闸机“刷脸”服务12万人次【回顾篇】

    2018杭州·云栖大会中,最让人印象深刻的莫过于几乎无处不在的人脸识别技术. 进入大会首先看到的就是一排整齐有科技感的人脸识别闸机,采用这一新技术在线完成实名认证的嘉宾,通过云栖大会人脸闸机时,只需对 ...

  4. 活体检测+3D人脸识别:为“刷脸”上道安全锁

    人脸识别技术现已广泛应用于安全管理.移动支付.司法刑侦等多个领域.所谓人脸识别,就是利用计算机技术的对比分析功能来实现身份认证的过程,这是一种基于生物特征的识别技术. 运用2D摄像头或3D摄像头进行检 ...

  5. 火出圈的3D人脸识别如何让“刷脸”更安全?

    看一眼智能手机,就能自动唤醒屏幕进行刷脸解锁,很多人都习惯了不再手动输入密码.逛完超市,双手提着购物袋,看一眼收银台的终端设备,就能刷脸支付,节省了大家排队等待的时间.如此便利的体验,都缘于人脸识别这 ...

  6. 【登录】刷脸登录(java语言-百度云ai)

    刷脸登录(java语言-百度云ai) pdf文件 一. 浅谈人工智能 人工智能(Artificial Intelligence),英文缩写为AI.它是研究.开发用于模拟.延伸和扩展人的智能的理论.方法 ...

  7. 使用百度云AI实现刷脸登录

    前言 刷脸登录是基于人工智能.生物识别.3D传感.大数据风控技术,最新实现的登录形式.用户在无需输入用户名密码的前提下,凭借"刷脸"完成登录过程.实现刷脸登录的核心是人脸处理,在人 ...

  8. 人工智能-刷脸登录实现

    4 刷脸登录实现 4.1 需求分析 为了用户登录的便捷,我们在系统中增加刷脸登录的功能,大致流程如下图: 4.1.2 触发流程 用户在登录页面触发刷脸登录功能 在该页面中弹出一个二维码,此二维码是后台 ...

  9. java项目使用百度云AI完成刷脸登录

    刷脸登录 理解刷脸登录的需求 理解刷脸登录的开发流程 实现刷脸登录功能 1 浅谈人工智能 1.1 人工智能的概述 人工智能(Artificial Intelligence),英文缩写为AI.它是研究. ...

最新文章

  1. ora-01017 invalid username/password logon denied
  2. 输出1/n(是循环小数的,只输出第一个循环节)
  3. 利用虚拟硬盘(把内存当作硬盘)来提高数据库的效率(目前只针对SQL Server 2000)可以提高很多...
  4. 算法导论课后习题解析 第四章 下
  5. 二元查找树的后序遍历结果
  6. asp.net 取windows的所有进程
  7. C#LeetCode刷题之#171-Excel表列序号(Excel Sheet Column Number)
  8. html如何隐藏二进制字符串,如何用二进制代码隐藏字符串?
  9. [转载] python set集合如何有序输出_python set集合的用法
  10. vue-cli初始化一个项目
  11. 癌症病人不让吃鸡蛋,癌症病人营养要如何补充?
  12. 计算机无法安装操作系统的原因,关于电脑无法安装IE浏览器的原因有哪些
  13. 2018年前端笔试高频题精选(二)
  14. 招行首发芭比娃娃MP3
  15. 攀藤G5S数据位编码
  16. [Maven进阶]多环境配置与应用
  17. 21天,在Github上获取 6300 star
  18. 中小企业上云如何选择及操作 1
  19. 芯片STC89C52 (宏晶STC)
  20. 表白php制作教程视频,如何制作表白视频教程 浪漫表白视频 制作微信浪漫表白视频...

热门文章

  1. Spring和Spring Framework的理解
  2. windows 10 powershell 启用脚本执行功能
  3. java时间带T的格式化
  4. 准备了一周就去字节跳动面试,结果一面就被虐哭了------面试官做个人吧
  5. tensorflow实现lenet5
  6. 【MFO】飞蛾扑火优化算法(Moth Flame Optimization,MFO)理论分析与matlab性能仿真,使用CEC2017测试
  7. Mysql连接异常解决方法
  8. R语言-寻找向量内的游程
  9. MT2625平台最新物联网开发资料下载
  10. JAVA及数据库中的关键字(常用)