python+opencv+百度智能云 人脸识别——人数识别+标记

发布时间:2022-08-19 12:48

一.设计流程
1.导入模块

import time
import base64
import cv2
import requests

time模块:计时

base64模块:由于某些系统中只能使用ASCII字符。Base64就是用来将非ASCII字符的数据转换成 ASCII字符的一种方法。

cv2模块:本程序中要用到opencv的框选模块

requests模块:使得python进行网络请求时,变得人性化,使用Requests可以轻而易举的完成浏览器可有的任何操作

2.获取token

这里首先要在百度智能云获取到自己的APP_ID、API_KEY、SECRET_KEY,具体方法:获取token

def gettoken():
    token = ""
    if token == "":
        APP_ID = '*****'  # 你的APP_ID
        API_KEY = '*****'  # 你的API_KEY
        SECRET_KEY = '*****'  # 你的SECRET_KEY

        # client_id 为官网获取的AK, client_secret 为官网获取的SK
        host = 'https://aip.baidubce.com/oaut/2.0/token?grant_type=client_credentials' + '&client_id=' + API_KEY + '&client_secret=' + SECRET_KEY
        # print(host)
        response = requests.get(host)
        # if response:
        #     for item in response.json().items():  # 逐项遍历response.json()----字典
        #         print(item)
        token = response.json()["access_token"]
        print(">>成功获取到token")
        return token

需要注意的是:这里获取的token你可以自己输出一下,如果是24.*****(一长串)就说明对了

3.图片读取

name为图片名称,以“rb”方式打开图片
几种文件打开方式的用法和区别:python文件打开方式用法

def read_pic(name):
    f = open(name, "rb")
    base64_data = base64.b64encode(f.read())
    s = base64_data.decode()
    print(">>图片读取成功")
    return s

4.人脸检测与属性分析

首先调用我们获取到的token,将我们需要访问的url通过字符串拼接完整,通过post方式访问url,并通过json()函数转换成python支持的dict。最后返回response 供后面我们框选人脸使用。

# 人脸检测与属性分析
def face_nums(picture):
    token = gettoken()
    request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"
    params = {"image": picture,
              "image_type": "BASE64",
              "quality_control": "NORMAL",
              "max_face_num": 10}
    request_url = request_url + "?access_token=" + token
    headers = {'content-type': 'application/json'}
    response = requests.post(request_url, data=params, headers=headers).json()
    if response:
        print(">>成功获取到response")
        # for item in response.items():       # 遍历response
        #     print(item)
    else:
        print("response == NULL")

    if response["error_code"] == 0:
        num = response["result"]["face_num"]
        print("图中人数为:%d" % num)
        print(">>人数检测完成\n")
    else:
        print("出错了")
    return response

5.人脸标记
得到上一步的response(其为字典结构),我们试着将其输出看看:

        for item in response.items():       # 遍历response
            print(item)

得到输出结果:

('error_code', 0)
('error_msg', 'SUCCESS')
('log_id', 579201101157)
('timestamp', 1612106758)
('cached', 0)
('result', {'face_num': 4, 'face_list': [{'face_token': 'fa26f3aa9227ef72c65dccc2cef4e09b', 'location': {'left': 331.56, 'top': 158.35, 'width': 101, 'height': 101, 'rotation': -20}, 'face_probability': 1, 'angle': {'yaw': 14.84, 'pitch': 0.53, 'roll': -19.51}}, {'face_token': '2f0747b582fa60572fa7340c3bdf081c', 'location': {'left': 245.17, 'top': 136.09, 'width': 70, 'height': 70, 'rotation': -23}, 'face_probability': 1, 'angle': {'yaw': 19.23, 'pitch': 11.06, 'roll': -28.17}}, {'face_token': '19ff570779608d83977781f2f20dfe25', 'location': {'left': 172.71, 'top': 95.36, 'width': 52, 'height': 52, 'rotation': 0}, 'face_probability': 1, 'angle': {'yaw': 0.81, 'pitch': 2.76, 'roll': -4.04}}, {'face_token': 'ad478dbf67ec8ca57657d41b520e09ae', 'location': {'left': 121.06, 'top': 49.85, 'width': 53, 'height': 47, 'rotation': 9}, 'face_probability': 1, 'angle': {'yaw': -0.72, 'pitch': 8.11, 'roll': 7.21}}]})

我们仔细分析一下,不要觉得他很复杂,其实就是一个字典里套字典的形式。其result键下就是我们需要的的信息,包括人数,人脸坐标,还有旋度,俯仰角等。所以我们把需要的人数和人脸坐标提取出来,通过cv2.rectangle()函数将人脸框选出来(注意,此函数里的所有参数只能为int类型,我们从字典中得到的数字为字符串类型,所以需要转换一下)。

实现代码:

def face_load(response, frame):
    num = response["result"]["face_num"]
    load = response["result"]["face_list"]
    # print(load)
    # for item in load.items():
    #     print(item)
    for i in range(num):                # 使用遍历把所有的人脸都标出框
        location = load[i]['location']  # 获取人脸坐标
        # print(location)
        cv2.rectangle(frame, (int(location['left']), int(location['top'])),
                      (int(location['width'] + location['left']), int(location['height'] + location['top'])),
                      (0, 0, 255), 2)   # opencv的标框函数
        cv2.imshow('人脸检测', frame)
        cv2.waitKey(1)                  # 刷新界面 不然只会呈现灰色
        print('运行时间是{}'.format(time.time() - t1))
        time.sleep(3)                   # 暂停3秒  展示图片

6.主函数

输入图片,调用函数,完成

def main():
    # p1 = read_pic("we.jpeg")
    p1 = read_pic("Hero.jpg")
    response = face_nums(p1)
    frame = cv2.imread("Hero.jpg")
    # frame = cv2.imread("we.jpeg")
    cv2.waitKey(0)
    # print("frame为:\n", frame)
    face_load(response, frame)

二.运行结果
python+opencv+百度智能云 人脸识别——人数识别+标记_第1张图片

三.总结
1.官方人脸检测API文档
2.官方常见问题及排查API文档
3.官方常见错误码API文档
4.注意事项&解决方案:
(1)post参数中,body中imageimage_type为必要参数,其他根据自己的需要添加
(2)请求体格式化Content-Typeapplication/json,通过json格式化请求体。
(3)Base64编码:请求的图片需经过Base64编码,图片的base64编码指将图片数据编码成一串字符串,使用该字符串代替图像地址。您可以首先得到图片的二进制,然后用Base64格式编码即可。需要注意的是,图片的base64编码是不包含图片头的,如data:image/jpg;base64,
(4)图片格式:现支持PNG、JPG、JPEG、BMP,不支持GIF图片
(5)cv2.rectangle()函数里的所有参数只能为int类型,我们从字典中得到的数字为字符串类型,所以需要转换一下
(6)cv2.imshow()之后必须加cv2.waitKey(),否则打开时间过短会报错
例如:

cv2.imshow('人脸检测', frame)
cv2.waitKey(1)           

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号