基于华为云人脸识别服务(FRS)开发体验

描述

手把手的技术干货教程,记录从0到1的开发过程。

一、前言

1.1 内容简介

这篇文章的内容主要介绍:华为云人脸识别服务(FRS)接口的使用过程。 利用华为云提供的人脸识别服务(FRS),完成:人脸检测人脸库创建向人脸库添加人脸在人脸库里搜索匹配的人脸完成人脸对比 等几个主要的功能。 只要完成了这几个功能,就可以开发成品软件,完成很多需要人脸服务的 场景,行业的项目落地。 比如:人脸识别考勤人脸识别签到人脸门禁开锁 等等场景。

人脸识别服务基于人的脸部特征信息,利用计算机对人脸图像进行处理、分析和理解,用户通过实时访问和调用API获取人脸处理结果,帮助用户自动进行人脸的识别、比对以及相似度查询等。 人脸识别服务提供了开放API接口,提供人脸识别能力,用户可以直接调用API接口访问华为云人脸识别服务,完成人脸识别后返回的结果为JSON格式,用户通过API接口与人脸识别服务交互,就可以完成项目开发。

当前开发案例时,编译语言采用Python(毕竟环境安装简单,符合大部分人的需求),开发环境使用华为云新推出的开发者空间的云主机,也就是在开发者空间的云主机里完成上面所说的项目开发体验。

这里使用的华为云开发者空间云主机,是华为云为全球开发者打造的一个云端开发环境,简化开发流程、提高开发效率,并促进技术创新。这个平台提供了一个无需成本即可探索和使用华为云服务的机会,每位注册的开发者在年度内都能享有数百小时的云主机使用权。云主机预装了CodeArts IDE(华为云的集成开发环境)、代码仓库以及JDK、Python等关键运行时插件,从而避免了本地环境配置的复杂性,让开发者能够快速上手并立即开始工作。

除了云主机外,华为云还提供了5GB的云存储容量及定制化的场景模拟沙箱,这些资源帮助开发者在安全隔离的环境中进行实验和测试。华为云开发者空间提供了丰富的技术培训课程和专业认证资料,助力开发者提升技能,并通过认证来证明自己的能力。该空间特别注重于应用全周期管理,涵盖从应用构建到运维的全过程,确保开发者可以高效地完成云端应用搭建。

华为云开发者空间云主机围绕CodeArts IDE打造了一个全面的开发工具生态系统,整合了鲲鹏、昇腾、鸿蒙等核心生态的开发资源,提供广泛的开源软件库和实用开发插件,支持从代码托管到应用运维的各个阶段。这不仅提升了开发效率,也方便了开发者与华为先进技术和全球开发者社区互动,共同推动技术进步和应用创新。

华为云开发者空间云主机的操作系统版本为Ubuntu 22.04.4 LTS,并且内置了一些常用的应用程序如Gitcode等,为开发者提供了一个稳定而高效的开发环境。

下面是运行效果:

华为云

华为云

华为云

1.2 开发环境

在使用华为云人脸识别服务(FRS)进行开发时,开发环境是华为云新推出的开发者空间云主机。这个开发环境为开发者提供了便捷且功能丰富的云端工作空间,特别适合进行各种云原生应用的开发和测试。
当前项目使用的相关软件工具已经上传到网盘:[https://ccnr8sukk85n.feishu.cn/wiki/QjY8weDYHibqRYkFP2qcA9aGnvb?from=from_copylink]

(1)开发者空间云主机

云主机中预装了华为云CodeArts IDE 开发工具,这是一款集成了多种开发插件的一站式开发环境,支持代码编写、调试、版本控制等功能。

(2)开发环境的具体配置

  • 操作系统 :云主机的操作系统版本为Ubuntu 22.04.4 LTS,这是一个广泛使用的Linux发行版,拥有良好的社区支持和丰富的软件包。
  • 存储容量 :每位注册的开发者都能获得5GB的云存储空间,用于存放项目文件和个人数据。
  • 开发语言 :选择了Python为例。

(3)开发流程

  1. 初始化设置 :登录华为云账号后进入开发者空间,领取并配置云主机,包括选择默认配置以及等待初始化过程完成。
  2. 环境准备 :在云主机上安装必要的开发工具和依赖库,比如Python及其相关库requests等,以便调用华为云API。
  3. 获取API凭证 :在华为云平台上创建并获取Access Key ID和Secret Access Key,用于身份验证。
  4. 开发与测试 :利用Python脚本调用人脸识别服务的各种API接口,实现人脸检测、人脸库管理及人脸比对等功能,并进行充分的测试以保证功能正确性。
  5. 部署与优化 :根据实际应用场景将开发完成的人脸识别解决方案部署到生产环境中,并持续优化性能和用户体验。

1.3 功能说明

华为云人脸识别服务(FRS)提供了一系列功能,通过这些功能可以实现多种应用场景中的人脸识别需求。

当前使用华为云FRS接口完成的主要功能:

(1) 人脸检测 :这一功能用于从图像或视频流中识别人脸的位置和大小。它能够返回人脸的边界框、关键点以及姿态信息等,是进行后续处理的基础步骤。

(2) 人脸库创建 :在实际应用中,通常需要将特定的人脸数据存储起来以便后续查询对比。此功能允许用户创建一个或多个人脸库,每个人脸库可以包含多个不同的人脸记录。

(3) 向人脸库添加人脸 :当创建了人脸库后,可以通过上传图片的方式将人脸添加到已有的人脸库中。每张图片代表一个人脸样本,并且可以与该人脸相关的额外信息一同保存,如姓名、ID号等。

(4) 人脸比对/搜索 :这项功能支持在指定的人脸库中查找与给定人脸相似度最高的匹配项。通过比较两张人脸图片或者直接使用人脸特征值来进行比对,从而判断是否为同一人。这一步骤对于实现诸如考勤系统、访问控制等场景非常关键。

基于上述功能,开发者可以开发出多种实用的应用程序,例如:

  • 人脸识别考勤 :自动记录员工的上下班时间。
  • 人脸识别签到 :会议、活动中的快速签到解决方案。
  • 人脸门禁开锁 :通过识别访客身份来控制物理访问权限。

1.4 实现过程

  • 环境准备 :在华为云开发者空间的云主机上设置好Python开发环境,包括安装必要的库如requests等,以便调用华为云提供的API接口。
  • 获取API凭证 :在开始调用API之前,需要在华为云平台上注册并获取相应的认证密钥(Access Key ID 和 Secret Access Key),这些信息会在每次请求时用来验证身份。
  • 调用人脸检测API :使用Python脚本发送HTTP POST请求至华为云FRS的人脸检测端点,传入待分析的图片文件,接收JSON格式的结果。
  • 创建人脸库 :同样地,通过发送合适的HTTP请求来创建新的人脸库,并获取其唯一标识符。
  • 添加人脸至库 :将欲存储的人脸图片上传至刚刚创建好的人脸库中,同时关联相关信息。
  • 执行人脸比对 :最后,利用人脸比对API,将现场捕捉到的人脸与数据库内已有的记录进行对比,根据返回的相似度分数做出决策。

二、华为云开发者空间

2.1 进入开发者空间

链接地址:[https://developer.huaweicloud.com/space/devportal/desktop]

登录华为云账号,进去之后看到的页面如下:

华为云

2.2 配置云主机

在左上角可以看到云主机的配置提醒,目前默认是基础版。

华为云

点击配置云主机,会弹出对话框,让你选择云主机的配置,进行安装系统。我这里选择ubuntu 22.04.

华为云

2.3 安装系统

点击安装后,会进行安装系统。需要等等一段时间。

华为云

华为云

2.4 启动云主机

安装完毕之后,直接可以在浏览器里启动云主机。

华为云

启动需要一段时间初始环境。

华为云

进去之后会有引导界面,提示云主机的使用技巧。

华为云

进入桌面后的默认效果如下。

华为云

2.5 全屏切换

在桌面页面上有个按钮可以全屏切换,切换全屏后,可视化空间更大,开发更加方便。

华为云

2.6 共享桌面

云主机还有共享桌面功能,如果需要远程演示项目,共享开发过程,对方还可以远程操作,这个功能非常的方便。 直接双击666

华为云

2.5 测试Python开发环境

点击左下角的所有应用程序,可以看到开发菜单里,有安装好的Python环境,可以直接使用。

华为云

启动之后的效果如下。

华为云

进去之后,点击左上角,新建一个文件。

华为云

然后保存文件,名字叫:test.py

华为云

华为云

然后编写一段简单的python代码,测试当前的开发环境是否正常。

华为云

代码如下:

import socket

def get_local_ip():
    """
    获取本地 IP 地址
    """
    try:
        # 创建一个 socket 对象,并连接到一个公共地址
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        local_ip = s.getsockname()[0]
        s.close()
        return local_ip
    except Exception as e:
        return f"无法获取本地 IP 地址: {e}"

if __name__ == '__main__':
    print("本地 IP 地址是:", get_local_ip())

点击左上角运行。

华为云

结果如下:

华为云

2.6 安装requests库

接下来需要使用Python代码的requests库,发起HTTP请求。先提前安装环境。

华为云

2.7 安装Pillow库

PillowPIL(Python Imaging Library)的一个分支,提供了图片处理功能。

pip3 install Pillow

华为云

到此,云主机的开发环境已经测试OK。

三、人脸识别服务使用

3.1 开通人脸识别服务

链接地址: https://console.huaweicloud.com/frs/?region=cn-north-4&locale=zh-cn#/frs/manage/index

华为云

开通之后的效果。

华为云

3.2 接口文档

在控制台页面中,可以看到每个功能都有一个接口文档按钮,点击可以一键翻到对应的帮助文档页面。快速了解此功能的使用办法。

华为云

这里以人脸检测V2 接口文档介绍为例。 点击进去访问的页面如下。

华为云

向下翻,可以看到此接口如何调用,需要传入什么参数。

在下面可以看到一个请求参数的说明。第一个参数是:X-Auth-Token,这个很重要,调用华为云的API接口都需要填这个参数。 关于如何获取这个X-Auth-Token参数。 下面章节里会详细介绍。

华为云

3.3 项目凭证

接下来调用人脸服务的API接口,都需要token进行鉴权,需要使用项目凭证 这个参数。

【1】获取项目凭证 点击左上角用户名,选择下拉菜单里的我的凭证。 记住这个项目ID,后面会用到。

华为云

3.4 创建IAM账户

创建一个IAM账户,因为接下来使用人脸服务的API接口,这些接口都需要token进行鉴权。简单来说,就是身份的认证。 调用接口获取Token时,就需要填写IAM账号信息。所以,接下来演示一下过程。

地址: https://console.huaweicloud.com/iam/?region=cn-north-4#/iam/users

鼠标放在左上角头像上,在下拉菜单里选择统一身份认证

华为云

点击右上角创建用户

填写用户名和密码信息:

华为云

继续点击下一步:

华为云

然后点击创建用户

华为云

创建成功:

华为云

创建完成

华为云

用户信息如下:

主用户名  xiao_ping_ping
IAM用户  ds_abc
密码     DS12345678

然后回到人脸服务去的控制台页面 要点击开通管理,给新创建的IAM用户赋予权限。 一定要开,不然后面访问API是没有权限的。

华为云

就像这样,点击开通服务 即可。

华为云

3.5 获取token鉴权

【1】Token介绍

为了方便接下来调用华为云的API接口,这里先完成token参数的获取。

帮助文档:https://support.huaweicloud.com/api-iam/iam_30_0001.html

华为云

获取的Token有效性说明:

Token的有效期为 24小时 。建议进行缓存,避免频繁调用。使用Token前请确保Token离过期有足够的时间,防止调用API的过程中Token过期导致调用API失败。重新获取Token,不影响已有Token有效性。

华为云

【2】接口使用说明

在文档页面,向下翻,可以看到对于此接口的详细说明。还支持使用在线调试。

华为云

【3】编写代码获取token

import requests
import json

# 主账号用户名
MAIN_USER = "[填你自己的]"

# IAM 子账户用户名
IAM_USER = "[填你自己的]"

# IAM 子账户密码
IAM_PASSWORD = "[填你自己的]"

# 项目 ID
PROJECT_ID = "[填你自己的]"

# 服务器区域代号
SERVER_ID = "cn-north-4"

# 保存 TOKEN 的文件路径
TOKEN_FILE_PATH = "token.txt"

def get_token():
    """
    功能: 获取 TOKEN 并保存到本地文件
    """
    # 请求地址
    request_url = f"https://iam.{SERVER_ID}.myhuaweicloud.com/v3/auth/tokens"

    # 构造请求头
    headers = {
        "Content-Type": "application/json;charset=UTF-8"
    }

    # 构造请求体
    payload = {
        "auth": {
            "identity": {
                "methods": ["password"],
                "password": {
                    "user": {
                        "domain": {
                            "name": MAIN_USER
                        },
                        "name": IAM_USER,
                        "password": IAM_PASSWORD
                    }
                }
            },
            "scope": {
                "project": {
                    "name": SERVER_ID
                }
            }
        }
    }

    # 发出 POST 请求
    try:
        response = requests.post(request_url, headers=headers, data=json.dumps(payload))

        # 打印状态码
        print(f"状态码: {response.status_code}")

        if response.status_code == 201:
            # 读取 X-Subject-Token 响应头
            token = response.headers.get("X-Subject-Token")

            # 打印返回的数据和 Token
            print(f"反馈的数据: {response.json()}")
            print(f"Token: {token}")

            # 保存 TOKEN 到本地文件
            if token:
                save_token_to_file(token)
                print(f"TOKEN 已保存到 {TOKEN_FILE_PATH}")
            else:
                print("未能获取到 TOKEN")
        else:
            print(f"获取 TOKEN 失败: {response.text}")

    except Exception as e:
        print(f"请求发生错误: {e}")

def save_token_to_file(token):
    """
    保存 TOKEN 到本地文件
    """
    try:
        with open(TOKEN_FILE_PATH, "w") as file:
            file.write(token)
    except Exception as e:
        print(f"保存 TOKEN 时发生错误: {e}")

def main():
    # 获取 TOKEN
    get_token()

if __name__ == "__main__":
    main()

代码说明:

(1) 依赖库 :使用requests库发起 HTTP 请求。 如果没有安装,在运行代码前安装依赖库:

pip install requests

(2) 主要逻辑 :构造请求头和请求体。发起 POST 请求,获取响应。从响应头中提取 X-Subject-Token 并保存到本地文件。

(3) TOKEN 保存 : TOKEN 被保存到 token.txt 文件中,方便后续直接读取使用。

(4) 运行方式 : 将代码保存为get_token.py,可以通过命令运行:

python get_token.py

也可以直接在终端运行,更加方便。 代码编写完毕,点击右上角的绿色三角形按钮,运行。 得到了Token然后保存到本地文件里。

华为云

3.6 人脸检测功能

【1】接口地址

帮助文档地址: https://support.huaweicloud.com/api-face/face_02_0084.html

人脸检测功能的API接口地址:https://face.cn-north-4.myhuaweicloud.com/v2/{project_id}/face-detect

【2】请求参数

参数参数类型描述
X-Auth-TokenString用户Token。
Content-TypeString参数值为application/json
参数名参数类型说明
image_base64String图像数据,Base64编码,要求:Base64编码后大小不超过8MB,建议小于1MB。图片为JPG/JPEG/BMP/PNG格式。
attributesString是否返回人脸属性,希望获取的属性列表,多个属性间使用逗号(,)隔开。目前支持的属性有:2:年龄4:装束(帽子、眼镜)6:口罩7:发型8:胡须11:图片类型12:质量13:表情21:人脸图片旋转角(顺时针偏转角度),支持0°、90°、180°和270°图片旋转。

【3】响应参数

如果状态返回400,表示肯定是调用出错了,如果返回状态码是 200,那么返回的值就是以下的几种情况。

参数描述
faces检测到的人脸。 调用失败时无此字段。
参数描述
bounding_box人脸在图像中的位置。
attributes人脸关键属性,比如头部姿态。
参数描述
width人脸图像所在矩形框的宽度。
top_left_y矩形框左上角纵坐标。
top_left_x矩形框左上角横坐标。
height人脸图像所在矩形框的高度。
参数描述
dress包含glass和hat两个属性结果。
glass是否戴眼镜:yes:戴眼镜dark:戴墨镜none:未戴眼镜unknown:未知
hat是否戴帽子:yes:戴帽子none:未戴帽子unknown:未知
age年龄。
mask是否戴口罩:yes:戴口罩none:未戴口罩unknown:未知
beard胡须:yes:有胡须none:无胡须unknown:未知
phototype图片类型:idcard:证件照monitor:摄像头监控internet photo:网络图片
quality图片中人脸的遮挡度、模糊度、光照强度、姿态角度。
hair发型:long:长发short:短发unknown:未知
expression人脸表情,包括中性、高兴、害怕、惊讶、伤心、生气、厌恶。
face_angle人脸图片旋转角(顺时针偏转角度),支持0°、90°、180°和270°图片旋转。
参数参数类型描述
glassString是否戴眼镜:yes:戴眼镜dark:戴墨镜none:未戴眼镜unknown:未知
hatString是否戴帽子:yes:戴帽子none:未戴帽子unknown:未知
参数参数类型描述推荐值
total_scoreDouble人脸质量总分,取值范围[0-1],分值越大质量越高。大于0.45
blurDouble模糊度,取值范围[0-1],分值越大模糊问题越严重。小于0.3
poseDouble姿态,取值范围[0-1],分值越大姿态问题越严重。小于0.3
occlusionDouble遮挡,取值范围[0-1],分值越大遮挡问题越严重。小于0.3
illuminationDouble光照,取值范围[0-1],分值越大光照问题越严重。小于0.3
参数参数类型描述
typeString人脸表情类型:neutral:中性happy:高兴fear:害怕surprise:惊讶sad:伤心angry:生气disgust:厌恶unknown:图片质量问题导致未识别
probabilityDouble表情置信度,取值范围[0-1]。

【4】准备测试的图片

打开文件管理器,在/home/developer目录下创建一个image文件夹。

华为云

然后打开浏览器,下载几张测试的图片。

华为云

准备好两张测试的照片。

华为云

【5】编写代码

重新新建一个face_detect.py 文件。用于编写测试人脸检测代码。

华为云

编写代码如下:

import requests
import base64
import json

# 项目 ID 和服务器区域代号
PROJECT_ID = "填你自己的"
SERVER_ID = "cn-north-4"

# TOKEN 文件路径
TOKEN_FILE_PATH = "token.txt"

def read_token_from_file():
    """
    从文件中读取 TOKEN
    """
    try:
        with open(TOKEN_FILE_PATH, "r") as file:
            token = file.read().strip()
        return token
    except Exception as e:
        print(f"读取 TOKEN 文件时发生错误: {e}")
        return None

def image_to_base64(image_path):
    """
    将图片转换为 Base64 编码
    """
    try:
        with open(image_path, "rb") as image_file:
            encoded_string = base64.b64encode(image_file.read()).decode("utf-8")
        return encoded_string
    except Exception as e:
        print(f"图片编码为 Base64 时发生错误: {e}")
        return None

def face_detect(image_path):
    """
    人脸检测功能
    """
    # 获取 TOKEN
    token = read_token_from_file()
    if not token:
        print("TOKEN 无法加载,检测失败")
        return

    # 请求地址
    request_url = f"https://face.{SERVER_ID}.myhuaweicloud.com/v2/{PROJECT_ID}/face-detect"

    # 将图片转换为 Base64 编码
    img_data = image_to_base64(image_path)
    if not img_data:
        print("图片无法转换为 Base64,检测失败")
        return

    # 构造请求头
    headers = {
        "Content-Type": "application/json",
        "X-Auth-Token": token
    }

    # 构造请求体
    payload = {
        "image_base64": img_data,
        "attributes": "1,2,4,6,7,8"  # 自定义返回字段
    }

    # 发送 POST 请求
    try:
        response = requests.post(request_url, headers=headers, data=json.dumps(payload))

        # 打印状态码
        print(f"状态码: {response.status_code}")

        # 解析和打印返回结果
        if response.status_code == 200:
            print("人脸检测成功,结果如下:")
            print(json.dumps(response.json(), indent=4, ensure_ascii=False))
        else:
            print(f"人脸检测失败: {response.text}")

    except Exception as e:
        print(f"请求发生错误: {e}")

def main():
    # 图片路径,替换为你要检测的图片路径
    image_path = "/home/developer/image/1.jpeg"

    # 执行人脸检测
    face_detect(image_path)

if __name__ == "__main__":
    main()

以下是用 Python 实现的人脸检测功能代码,使用 requests 库来发出 HTTP 请求,并从本地的 token.txt 文件中读取 TOKEN。代码也包含将图片转换为 Base64 编码的逻辑:

import requests
import base64
import json

# 项目 ID 和服务器区域代号
PROJECT_ID = "填你自己的"
SERVER_ID = "cn-north-4"

# TOKEN 文件路径
TOKEN_FILE_PATH = "token.txt"

def read_token_from_file():
    """
    从文件中读取 TOKEN
    """
    try:
        with open(TOKEN_FILE_PATH, "r") as file:
            token = file.read().strip()
        return token
    except Exception as e:
        print(f"读取 TOKEN 文件时发生错误: {e}")
        return None

def image_to_base64(image_path):
    """
    将图片转换为 Base64 编码
    """
    try:
        with open(image_path, "rb") as image_file:
            encoded_string = base64.b64encode(image_file.read()).decode("utf-8")
        return encoded_string
    except Exception as e:
        print(f"图片编码为 Base64 时发生错误: {e}")
        return None

def face_detect(image_path):
    """
    人脸检测功能
    """
    # 获取 TOKEN
    token = read_token_from_file()
    if not token:
        print("TOKEN 无法加载,检测失败")
        return

    # 请求地址
    request_url = f"https://face.{SERVER_ID}.myhuaweicloud.com/v2/{PROJECT_ID}/face-detect"

    # 将图片转换为 Base64 编码
    img_data = image_to_base64(image_path)
    if not img_data:
        print("图片无法转换为 Base64,检测失败")
        return

    # 构造请求头
    headers = {
        "Content-Type": "application/json",
        "X-Auth-Token": token
    }

    # 构造请求体
    payload = {
        "image_base64": img_data,
        "attributes": "1,2,4,6,7,8"  # 自定义返回字段
    }

    # 发送 POST 请求
    try:
        response = requests.post(request_url, headers=headers, data=json.dumps(payload))

        # 打印状态码
        print(f"状态码: {response.status_code}")

        # 解析和打印返回结果
        if response.status_code == 200:
            print("人脸检测成功,结果如下:")
            print(json.dumps(response.json(), indent=4, ensure_ascii=False))
        else:
            print(f"人脸检测失败: {response.text}")

    except Exception as e:
        print(f"请求发生错误: {e}")

def main():
    # 图片路径,替换为你要检测的图片路径
    image_path = "/home/developer/image/1.jpeg"

    # 执行人脸检测
    face_detect(image_path)

if __name__ == "__main__":
    main()

代码说明:

(1) 依赖库

  • 使用 requests 进行 HTTP 请求。
  • 使用 base64 将图片转换为 Base64 编码。
  • 确保安装了依赖库:pip install requests

(2) 主要逻辑

  • 读取 TOKEN :从 token.txt 文件中读取 TOKEN。
  • 图片编码 :将输入图片文件转为 Base64 格式。
  • 构造请求 :设置请求头和请求体,指定自定义返回字段。
  • 发送请求 :调用 API 完成人脸检测,打印响应结果。

(3) 错误处理 :捕获文件读取、图片编码以及 HTTP 请求的异常,方便排查问题。

(4) 运行方式

  • 将代码保存为 face_detect.py
  • 替换 image_path 为本地图片的实际路径。
  • 运行代码:
    python face_detect.py
    

(5) 输出

  • 成功时,打印 API 返回的 JSON 数据。
  • 失败时,打印错误状态码及返回信息。

【6】终端运行测试

也可以直接在终端运行,更加方便。 代码编写完毕,点击右上角的绿色三角形按钮,运行。

华为云

当前调用测试的图片是:

华为云

接口返回的结果:

{
    "faces": [
        {
            "bounding_box": {
                "width": 150,
                "top_left_y": 431,
                "top_left_x": 192,
                "height": 182
            },
            "attributes": {
                "gender": "female",
                "age": 25,
                "dress": {
                    "glass": "none",
                    "hat": "none"
                },
                "mask": "none",
                "hair": "long",
                "beard": "none"
            }
        },
        {
            "bounding_box": {
                "width": 148,
                "top_left_y": 428,
                "top_left_x": 358,
                "height": 188
            },
            "attributes": {
                "gender": "female",
                "age": 26,
                "dress": {
                    "glass": "none",
                    "hat": "none"
                },
                "mask": "none",
                "hair": "long",
                "beard": "none"
            }
        }
    ]
}

JSON数据表示的含义如下:

  • 检测到了两张人脸。
  • 第一张人脸
    • 位置:左上角坐标(192, 431),宽度150像素,高度182像素。
    • 属性:女性,年龄25岁,未戴眼镜和帽子,长发,无胡须,未戴口罩。
  • 第二张人脸
    • 位置:左上角坐标(358, 428),宽度148像素,高度188像素。
    • 属性:女性,年龄26岁,未戴眼镜和帽子,长发,无胡须,未戴口罩。

这些信息提供了每张人脸的位置以及一些基本属性如性别、年龄、是否佩戴眼镜或帽子等。

到此,接口就已经调用成功了。从返回的

3.7 创建人脸库

【1】人脸库的作用

如果我们要做考勤系统,签到系统,那么设计之前需要创建人脸库,录入每个人员的人脸信息,才可以设计后面的考勤,签到的人脸对比识别功能。

【2】接口地址

创建人脸库的帮助文档地址: https://support.huaweicloud.com/api-face/face_02_0088.html

华为云

继续向下翻,可以看到接口地址请求参数的说明。

华为云

接口地址: https://face.cn-north-4.myhuaweicloud.com/v2/{project_id}/face-sets

【3】请求参数

参数描述
X-Auth-Token用户Token。
Content-Type参数值为application/json
参数描述
external_fields用户自定义数据,自定义字段不能以vector、bounding_box、external_image_id、face_id、create_time、_id、_all、_source等字段命名,这些字段为内置字段,自定义字段避免使用。自定义字段的key值长度范围为[1,36],string类型的value长度范围为[1,256]。如果在后续操作中,使用该自定义字段向人脸库中添加人脸,需要在创建人脸库时定义该字段。
face_set_name人脸库的名称,字符串长度1-64。建议人脸库的名称不要以下划线(_)开头,否则云监控服务会无法采集人脸数量。
face_set_capacity人脸库最大的容量,填写1万整数倍的数字,例如:30000。默认为100000,最大值为100000,可通过创建新的人脸库进行扩容,每个用户可使用10个人脸库,每个人脸库容量为10万个人脸特征。如需扩容单个人脸库规模,请联系华为云客服确认扩容规模与价格。
参数描述
type数据类型支持string、integer、double、long等。

【4】响应参数

正常情况下,返回的状态码:200

参数描述
face_number人脸库中已有的人脸特征的数量。
external_fields用户的自定义字段。
face_set_id人脸库ID,随机生成的包含八个字符的字符串。
face_set_name人脸库名称。
create_date创建时间。
face_set_capacity人脸库最大的容量。创建人脸库时,请求参数如果不设置face_set_capacity参数,默认每个人脸库最大容量为10万个人脸特征。

【5】编写代码

创建一个新文件名字为:face-sets.py

华为云

编写代码:

import requests

# 项目ID和服务器区域代号
PROJECT_ID = "填你自己的"
SERVER_ID = "cn-north-4"

# 从当前目录下的token.txt文件读取Token
with open('token.txt', 'r') as file:
    Token = file.read().strip()

def create_face_database(face_lib_name):
    # 设置请求地址
    url = f"https://face.{SERVER_ID}.myhuaweicloud.com/v2/{PROJECT_ID}/face-sets"

    # 构造请求头
    headers = {
        "Content-Type": "application/json",
        "X-Auth-Token": Token
    }

    # 构造请求体
    payload = {
        "external_fields": {
            "face_name": {"type": "string"},
            "face_phone": {"type": "string"},
            "face_class": {"type": "string"}
        },
        "face_set_name": face_lib_name
    }

    # 发送POST请求
    response = requests.post(url, json=payload, headers=headers)
    
    # 输出响应状态码及内容
    print(f"Status Code: {response.status_code}")
    print(f"Response: {response.json()}")

# 调用函数创建人脸库
create_face_database("face_1")

运行代码的时候,要修改最前面的项目ID参数,和最后创建的人脸库名称。 代码从本地文件token.txt中读取认证Token。记得在运行此脚本之前检查token.txt文件是否存在且包含有效的Token值(最前面已经说了怎么得到这个Token值)。

【6】终端运行代码测试

华为云

返回的结果如下:

Response: {'face_set_info': {'face_number': 0, 'face_set_id': 'tKzQuUW4', 'face_set_name': 'face_1', 'create_date': '2024-11-28 08:41:49', 'face_set_capacity': 100000, 'external_fields': {'face_name': {'type': 'string'}, 'face_phone': {'type': 'string'}, 'face_class': {'type': 'string'}}}}

根据返回的JSON响应数据以及华为云人脸识别服务FRS的文档说明,下面是JSON数据信息的总结:

face_set_info :包含了创建的人脸库的具体信息。

  • face_number :人脸库中已有的人脸特征数量。当前值为0,表示刚刚创建的人脸库还没有添加任何人脸特征。
  • face_set_id :人脸库的唯一标识符,随机生成的字符串。这里的ID是tKzQuUW4
  • face_set_name :用户指定的人脸库名称。这里命名为face_1
  • create_date :人脸库的创建时间。这里是2024-11-28 08:41:49(UTC+08:00)。
  • face_set_capacity :人脸库的最大容量。默认情况下为100,000个人脸特征,这里显示的也是100,000。
  • external_fields :用户自定义字段的信息。
    • face_name :类型为string,用于存储人脸名称。
    • face_phone :类型为string,用于存储电话号码。
    • face_class :类型为string,用于存储人脸分类信息。

JSON响应表明成功创建了一个名为face_1的人脸库,该库的ID是tKzQuUW4,创建于2024年11月28日08:41:49,并且设置了三个自定义字段(face_nameface_phoneface_class),每个字段的类型都是string。目前该人脸库尚未添加任何人脸特征。

3.8 向人脸库添加人脸

【1】接口地址

帮助文档:https://support.huaweicloud.com/api-face/face_02_0093.html

华为云

接口地址: https://face.cn-north-4.myhuaweicloud.com/v2/{project_id}/face-sets/{face_set_name}/faces

参数参数类型描述
project_idString项目ID
face_set_nameString人脸库名称,字符串长度1-64。

【2】请求参数

参数是否必选参数类型描述
X-Auth-TokenString用户Token。
Content-TypeString发送的实体的MIME类型,参数值为“application/json”。
参数名参数类型说明
image_base64String图像数据,Base64编码,要求:Base64编码后大小不超过8MB,建议小于1MB。图片为JPG/JPEG/BMP/PNG格式。
external_image_idString用户指定的图片外部ID,与当前图像绑定。用户没提供,系统会生成一个。该ID长度范围为1~36位,可以包含字母、数字、中划线或者下划线,不包含其他的特殊字符。
external_fieldsObject根据用户自定义数据类型,填入相应的数值。需在创建人脸库时定义external_fields字段,才可以在添加人脸时使用该字段。
singleboolean是否将图片中的最大人脸添加至人脸库。可选值包括:true:传入的单张图片中如果包含多张人脸,则只将最大人脸添加到人脸库中。false:默认为false。传入的单张图片中如果包含多张人脸,则将所有人脸添加至人脸库中。

【3】响应参数

状态码:200

参数描述
face_set_id人脸库ID。 调用失败时无此字段。
face_set_name人脸库名称。 调用失败时无此字段。
faces调用失败时无此字段。

【4】编写代码

创建新文件:face-sets_lib.py

华为云

编写代码如下:

import requests
import base64
import io

# 项目ID和服务器区域代号
PROJECT_ID = "填你自己的"
SERVER_ID = "cn-north-4"

# 从当前目录下的token.txt文件读取Token
with open('token.txt', 'r') as file:
    Token = file.read().strip()

def to_base64(image_path):
    """将图片转换为Base64编码的字符串"""
    with open(image_path, 'rb') as image_file:
        return base64.b64encode(image_file.read()).decode('utf-8')

def register_face(image_path, face_lib, name):
    # 读取图片并进行Base64编码
    img_data = to_base64(image_path)

    # 设置请求地址
    url = f"https://face.{SERVER_ID}.myhuaweicloud.com/v2/{PROJECT_ID}/face-sets/{face_lib}/faces"

    # 构造请求头
    headers = {
        "Content-Type": "application/json",
        "X-Auth-Token": Token
    }

    # 构造请求体
    payload = {
        "image_base64": img_data,
        "external_fields": {"face_name": name},
        "single": True
    }

    # 发送POST请求
    response = requests.post(url, json=payload, headers=headers)
    
    # 输出响应状态码及内容
    print(f"Status Code: {response.status_code}")
    print(f"Response: {response.json()}")

# 调用函数注册人脸
register_face("/home/developer/image/1.jpeg", "face_1", "xiaolong")

运行代码时,替换"face_1""xiaolong"为你实际的人脸库名称和自定义字段值。代码从本地文件token.txt中读取认证Token,并从指定路径读取图片进行Base64编码。

【5】终端运行测试

华为云

返回的结果如下:

Response: {'face_set_id': 'tKzQuUW4', 'face_set_name': 'face_1', 'faces': [{'face_id': '1cOqkdyg', 'external_image_id': 'JAHIqXTA', 'bounding_box': {'width': 148, 'top_left_x': 358, 'top_left_y': 428, 'height': 188}, 'external_fields': {'face_name': 'xiaolong'}}]}
Response: {'face_set_id': 'tKzQuUW4', 'face_set_name': 'face_1', 'faces': [{'face_id': '1cOqkdyg', 'external_image_id': 'JAHIqXTA', 'bounding_box': {'width': 148, 'top_left_x': 358, 'top_left_y': 428, 'height': 188}, 'external_fields': {'face_name': 'xiaolong'}}]}
Response: {'face_set_id': 'tKzQuUW4', 'face_set_name': 'face_1', 'faces': [{'face_id': '1cOqkdyg', 'external_image_id': 'JAHIqXTA', 'bounding_box': {'width': 148, 'top_left_x': 358, 'top_left_y': 428, 'height': 188}, 'external_fields': {'face_name': 'xiaolong'}}]}

Response: {'face_set_id': 'tKzQuUW4', 'face_set_name': 'face_1', 'faces': [{'face_id': '1cOqkdyg', 'external_image_id': 'JAHIqXTA', 'bounding_box': {'width': 148, 'top_left_x': 358, 'top_left_y': 428, 'height': 188}, 'external_fields': {'face_name': 'xiaolong'}}]}

根据返回的JSON响应数据以及华为云人脸识别服务FRS的文档,以下是JSON数据信息的总结:

  • face_set_id :人脸库的唯一标识符。这里的ID是tKzQuUW4
  • face_set_name :人脸库的名称。这里是face_1
  • faces :一个数组,包含了成功添加到人脸库中的人脸信息。
    • face_id :系统生成的唯一标识符,用于标识该人脸。这里的ID是1cOqkdyg
    • external_image_id :用户指定的图片外部ID,与当前图像绑定。这里的ID是JAHIqXTA
    • bounding_box :描述了人脸在图像中的位置。
      • width :矩形框的宽度。这里是148像素。
      • top_left_x :矩形框左上角的横坐标。这里是358像素。
      • top_left_y :矩形框左上角的纵坐标。这里是428像素。
      • height :矩形框的高度。这里是188像素。
    • external_fields :用户自定义字段的信息。
      • face_name :自定义字段face_name的值,这里是xiaolong

这个JSON响应表明成功将一张包含人脸的图片添加到了名为face_1的人脸库中。人脸库的ID是tKzQuUW4。添加的人脸具有以下特征:

  • 人脸ID为1cOqkdyg
  • 图片外部ID为JAHIqXTA
  • 人脸在图片中的位置由矩形框表示,宽度为148像素,高度为188像素,左上角坐标为(358, 428)。
  • 自定义字段face_name的值为xiaolong

3.9 从人脸库匹配人脸

【1】功能说明

人脸搜索是指在已有的人脸库中,查询与目标人脸相似的一张或者多张人脸,并返回相应的置信度。如果图片中包含多个人脸,选取图片中检测到的最大尺寸人脸作为检索的输入。 支持传入图片或者faceID进行人脸搜索。

【2】帮助文档

地址:https://support.huaweicloud.com/api-face/face_02_0086.html

华为云

【3】接口地址

https://face.cn-north-4.myhuaweicloud.com/v2/{project_id}/face-sets/{face_set_name}/search

参数参数类型描述
project_idString项目ID
face_set_nameString人脸库名称,字符串长度1-64。

【4】请求参数

参数是否必选参数类型描述
X-Auth-TokenString用户Token。
Content-TypeString发送的实体的MIME类型,参数值为“application/json”。
参数名说明
image_base64图像数据,Base64编码,要求:Base64编码后大小不超过8MB,建议小于1MB。图片为JPG/JPEG/BMP/PNG格式。
face_id导入人脸时,系统返回的人脸编号,即人脸ID。
top_n返回查询到的最相似的N张人脸,N默认为10,取值范围[0,1000]。N张人脸按照置信度降序排序,置信度越大越靠前。
threshold人脸相似度阈值,低于这个阈值则不返回,取值范围[0,1],一般情况下建议取值0.93,默认为0。
sort支持字段排序
filter过滤条件
return_fields指定返回的自定义字段。

【5】响应参数

状态码:200

参数参数类型描述
facesArray of SearchFace objects查找的人脸集合。 调用失败时无此字段。
参数参数类型描述
bounding_boxBoundingBox object人脸在图像中的位置。
similarityDouble人脸搜索时用于被检索的相似度。
external_fieldsObject用户添加的额外自定义字段。
external_image_idString人脸所在的外部图片ID。
face_idString人脸ID,由系统内部生成的唯一ID。
参数参数类型描述
widthInteger矩形框宽度。
top_left_yInteger矩形框左上角纵坐标。
top_left_xInteger矩形框左上角横坐标。
heightInteger矩形框高度。

【6】编写代码

新建文件。face-sets_search.py

华为云

代码编写如下:

import base64
import requests
import io

# 项目ID
PROJECT_ID = "填你自己的"

# 服务器区域代号
SERVER_ID = "cn-north-4"

# 从当前目录下的token.txt文件中读取Token
with open('token.txt', 'r') as file:
    TOKEN = file.read().strip()

def image_to_base64(image_path):
        """
        将图片转换为 Base64 编码
        """
        try:
            with open(image_path, "rb") as image_file:
                encoded_string = base64.b64encode(image_file.read()).decode("utf-8")
            return encoded_string
        except Exception as e:
            print(f"图片编码为 Base64 时发生错误: {e}")
            return None

def to_base64(image):
    """将图片转换为Base64编码"""
    buffered = io.BytesIO()
    image.save(buffered, format="JPEG")
    img_str = base64.b64encode(buffered.getvalue()).decode('utf-8')
    return img_str

def find_face(image_path, face_lib, threshold=0.93):
    # 将图片转换为 Base64 编码
    img_data = image_to_base64(image_path)
    if not img_data:
        print("图片无法转换为 Base64,检测失败")
        return
    
    # 设置请求地址
    request_url = f"https://face.{SERVER_ID}.myhuaweicloud.com/v2/{PROJECT_ID}/face-sets/{face_lib}/search"
    
    # 设置数据提交格式及请求头
    headers = {
        "Content-Type": "application/json",
        "X-Auth-Token": TOKEN
    }
    
    # 构造请求体
    payload = {
        "image_base64": img_data,
        "return_fields": ["face_name"],
        "threshold": threshold
    }
    
    # 发送POST请求
    response = requests.post(request_url, json=payload, headers=headers)
    
    # 检查响应状态码
    if response.status_code == 200:
        print("人脸搜索成功:", response.json())
    else:
        print("人脸搜索失败:", response.status_code, response.text)

# 调用函数
find_face("/home/developer/image/1.jpeg", "face_1")

替换'/home/developer/image/1.jpeg''face_1'为实际的图片路径和人脸库名称。确保在调用此脚本之前,已正确配置好token.txt文件,并且该文件位于与脚本相同的目录下 [前面说了这个token怎么来的]。

【7】终端运行代码测试

华为云

返回的结果如下:

人脸搜索成功: {'faces': [{'face_id': '1cOqkdyg', 'external_image_id': 'JAHIqXTA', 'bounding_box': {'width': 148, 'top_left_x': 358, 'top_left_y': 428, 'height': 188}, 'external_fields': {'face_name': 'xiaolong'}, 'similarity': 1.0}]}

根据返回的JSON响应数据以及华为云人脸识别服务FRS的文档,以下是JSON数据信息的总结:

  • faces :一个数组,包含了搜索到的人脸信息。
    • face_id :系统生成的唯一标识符,用于标识该人脸。这里的ID是1cOqkdyg
    • external_image_id :用户指定的图片外部ID,与当前图像绑定。这里的ID是JAHIqXTA
    • bounding_box :描述了人脸在图像中的位置。
      • width :矩形框的宽度。这里是148像素。
      • top_left_x :矩形框左上角的横坐标。这里是358像素。
      • top_left_y :矩形框左上角的纵坐标。这里是428像素。
      • height :矩形框的高度。这里是188像素。
    • external_fields :用户自定义字段的信息。
      • face_name :自定义字段face_name的值,这里是xiaolong
    • similarity :人脸搜索时的相似度分数。这里的值为1.0,表示完全匹配。

这个JSON响应表明成功搜索到了一张人脸,并且该人脸与人脸库中的一张人脸完全匹配。

  • 人脸ID为1cOqkdyg
  • 图片外部ID为JAHIqXTA
  • 人脸在图片中的位置由矩形框表示,宽度为148像素,高度为188像素,左上角坐标为(358, 428)。
  • 自定义字段face_name的值为xiaolong
  • 相似度分数为1.0,表示完全匹配。

四、图形化项目开发

4.1 安装Tkinter库

为了方便能直观的展示项目的整体功能,接下来安装 Tkinter ,完成人脸识别系列功能的设计。

在Python中, Tkinter用于创建图形用户界面(GUI)。这是Python的标准GUI库。

下面是安装方法:

华为云

4.2 测试Tkinter环境

创建一个新的文件。

华为云

编写代码:

import tkinter as tk  # 导入 Tkinter 模块

# 创建主窗口
window = tk.Tk()

# 设置窗口标题
window.title("Hello Tkinter")

# 设置窗口大小(宽 x 高)
window.geometry("400x300")

# 显示窗口并进入事件循环
window.mainloop()

运行效果如下:

华为云

代码解析

(1)导入 Tkinter

import tkinter as tk

tkinter 是 Python 的标准库模块,用于创建和管理 GUI 界面。

(2)创建主窗口

window = tk.Tk()

Tk() 方法创建了一个主窗口对象,称为“顶级窗口”。

(3)设置窗口标题

window.title("Hello Tkinter")

title() 方法用来设置窗口标题。

(4)设置窗口大小

window.geometry("400x300")

geometry() 方法用来设置窗口的尺寸,这里是宽400像素,高300像素。

(5)运行窗口

window.mainloop()

mainloop() 方法启动窗口的事件循环,程序会在这里等待用户的操作(例如关闭窗口或点击按钮)。

4.3 设计界面

编写代码如下:

import tkinter as tk
from tkinter import filedialog, messagebox

# 全局变量,保存当前载入的图片路径
current_image_path = None

# 创建主窗口
window = tk.Tk()
window.title("人脸识别服务工具")
window.geometry("600x400")  # 增大窗口尺寸以显示图片

# 图片显示标签
image_label = tk.Label(window, text="图片显示区域", width=50, height=20, relief="solid")
image_label.pack(pady=10)

# 定义功能函数
def load_image():
    global current_image_path
    file_path = filedialog.askopenfilename(
        title="选择图片文件",
        filetypes=[("图片文件", "*.jpg *.jpeg *.png *.bmp")]
    )
    if file_path:
        current_image_path = file_path
        display_image(file_path)

def display_image(file_path):
    try:
        img = Image.open(file_path)
        img = img.resize((300, 300))  # 调整图片尺寸
        img_tk = ImageTk.PhotoImage(img)
        image_label.config(image=img_tk, text="")  # 显示图片,清除文本
        image_label.image = img_tk  # 防止垃圾回收
    except Exception as e:
        messagebox.showerror("错误", f"无法载入图片:{e}")

def face_detection():
    if not current_image_path:
        messagebox.showwarning("提示", "请先载入图片!")
        return
    messagebox.showinfo("功能提示", f"人脸检测功能待实现!当前图片路径:{current_image_path}")

def create_face_library():
    messagebox.showinfo("功能提示", "创建人脸库功能待实现!")

def add_face_to_library():
    if not current_image_path:
        messagebox.showwarning("提示", "请先载入图片!")
        return
    messagebox.showinfo("功能提示", f"向人脸库添加人脸功能待实现!当前图片路径:{current_image_path}")

def search_face():
    if not current_image_path:
        messagebox.showwarning("提示", "请先载入图片!")
        return
    messagebox.showinfo("功能提示", f"搜索匹配人脸功能待实现!当前图片路径:{current_image_path}")

# 创建按钮
btn_load_image = tk.Button(window, text="载入图片", command=load_image, width=20)
btn_face_detection = tk.Button(window, text="人脸检测", command=face_detection, width=20)
btn_create_library = tk.Button(window, text="创建人脸库", command=create_face_library, width=20)
btn_add_face = tk.Button(window, text="添加人脸到库", command=add_face_to_library, width=20)
btn_search_face = tk.Button(window, text="搜索匹配人脸", command=search_face, width=20)

# 布局按钮
btn_load_image.pack(pady=5)
btn_face_detection.pack(pady=5)
btn_create_library.pack(pady=5)
btn_add_face.pack(pady=5)
btn_search_face.pack(pady=5)

# 运行主事件循环
window.mainloop()

运行界面如下:

华为云

五、总结

华为云人脸识别服务(FRS)及其开发者空间云主机为开发者提供了一个功能强的开发平台,使得人脸识别技术的应用和实现变得更加简单和便捷。通过调用开放的API接口,开发者可以轻松实现人脸检测、人脸库管理、人脸对比等关键功能,为考勤、签到、门禁等场景提供智能化解决方案。

开发者空间云主机为用户提供了预配置的云端开发环境,避免了繁琐的本地配置过程,快速上手成为可能。结合CodeArts IDE以及预装的开发工具链,开发者能够专注于核心开发任务,提升效率。借助华为云丰富的资源,如云存储、沙箱测试环境、技术培训课程等,开发者不仅能快速验证创意,还能通过学习和认证不断提升技能。

此外,华为云开发者空间云主机深度整合了鲲鹏、昇腾和鸿蒙等生态资源,助力开发者在广泛的技术领域展开创新,并与全球开发者社区互动交流,共同推动技术进步。这一平台为云端开发提供了全面支持,涵盖从开发到运维的全周期服务,是开发者实现技术突破和项目落地的重要助力。

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分