腾讯人脸识别

通过腾讯接口人脸识别本地照片人的年龄。

所有开通腾讯云人脸识别服务的客户,每月每种服务均有10000次的免费调用额度,以资源包的形式发放到您的腾讯云账号中,优先扣除。您可以在 控制台-资源包管理 中查看免费资源包的消耗情况。离线 SDK 默认免费绑定3台设备测试60天。

只保留成年人图片

import os
import base64
from PIL import Image
import json
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.iai.v20200303 import iai_client, models

# 获取当前文件夹下的所有jpg文件
jpg_files = [f for f in os.listdir('.') if f.endswith('.jpg')]

try:
    # 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
    # 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
    # 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
    cred = credential.Credential("AKID*", "Z*")

    # 实例化一个http选项,可选的,没有特殊需求可以跳过
    httpProfile = HttpProfile()
    httpProfile.endpoint = "iai.tencentcloudapi.com"

    # 实例化一个client选项,可选的,没有特殊需求可以跳过
    clientProfile = ClientProfile()
    clientProfile.httpProfile = httpProfile

    # 实例化要请求产品的client对象,clientProfile是可选的
    client = iai_client.IaiClient(cred, "ap-beijing", clientProfile)

    # 遍历所有jpg文件,逐一检测人脸
    for filename in jpg_files:
        f = open(filename, 'rb')
        imagebytes = str(base64.b64encode(f.read()))[2:-1]
        f.close()

        req = models.DetectFaceAttributesRequest()
        params = {
            "MaxFaceNum": 1,
            "Image": imagebytes,
            "FaceAttributesType": "Age"
        }
        req.from_json_string(json.dumps(params))

        try:
            resp = client.DetectFaceAttributes(req)
            resp_dict = json.loads(resp.to_json_string())
            face_info = resp_dict["FaceDetailInfos"][0]
            age = face_info["FaceDetailAttributesInfo"]["Age"]
            if age < 18:
                print(f"图片:{filename} 人脸年龄小于:18岁 年龄为:{age}岁")
                os.remove(filename)
            else:
                print(f"图片:{filename} 人脸年龄大于等于:18岁 年龄为:{age}岁")
        except TencentCloudSDKException as err:
            print(f"图片:{filename} 检测人脸失败,错误信息:{err}")
            os.remove(filename)

except TencentCloudSDKException as err:
    print(err)

显示人脸图片的年龄

import os
import base64
from PIL import Image
import json
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.iai.v20200303 import iai_client, models

# 需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
# 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
cred = credential.Credential("AKID*", "Z*")
httpProfile = HttpProfile()
httpProfile.endpoint = "iai.tencentcloudapi.com"
clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
client = iai_client.IaiClient(cred, "ap-beijing", clientProfile)

# 定义要搜索的图像文件扩展名列表
img_exts = ['.jpg', '.jpeg', '.png', '.bmp']

# 循环当前目录中的文件并检测图像文件中的人脸年龄
for filename in os.listdir('.'):
    if os.path.isfile(filename) and os.path.splitext(filename)[1].lower() in img_exts:
        print(f"文件名: {filename}...")
        with open(filename, 'rb') as f:
            imagebytes = str(base64.b64encode(f.read()))[2:-1] # 图片转换成二进制
        req = models.DetectFaceAttributesRequest()
        params = {
            "MaxFaceNum": 1,
            "Image": imagebytes, # 图片二进制赋值给腾讯接口
            "FaceAttributesType": "Age"
        }
        req.from_json_string(json.dumps(params))
        try:
            resp = client.DetectFaceAttributes(req)
            resp_dict = json.loads(resp.to_json_string())
            age = resp_dict["FaceDetailInfos"][0]["FaceDetailAttributesInfo"]["Age"]
            if age > 18:
                print(f" (这张照片年龄是: {age} 岁,大于 18 岁).")
            else:
                print(f" (这张照片年龄是: {age} 岁,小于 18 岁).")
        except TencentCloudSDKException as err:
            print(f"  Error detecting age: {err}.")

腾讯云人脸识别提供在线 API 调用和离线识别 SDK 使用两种服务方式,您可以单独使用其中一种,也可以二者结合形成端与云方案使用。

  • 针对在线 API 调用服务方式,提供按 QPS 计费和按调用次数计费两种计费模式。
  • 针对离线识别 SDK 服务方式,提供按设备永久授权方式(50台起购)。

调用次数计费(资源包)

资源包当前不支持退款和剩余次数冻结。如需购买,请单击 购买资源包

资源包规格 10万次 100万次 1000万次 5000万次 1亿次
人脸检测与分析 48元 450元 4100元 17500元 25000元
五官定位 198元 1900元 18200元 82500元 135000元
人脸比对 318元 3100元 30400元 142500元 255000元
人脸验证 318元 3100元 30400元 142500元 255000元
人脸搜索 318元 3100元 30400元 142500元 255000元
人员库管理 318元 3100元 30400元 142500元 255000元
资源包规格 1万次 10万次 100万次
人脸静态活体检测(高精度版) 1200元 11500元 100000元

调用次数计费(后付费)

月接口调用总量 0 < 调用量 ≤ 300万 300万<调用量 ≤ 1500万 调用量 > 1500万
人脸检测与分析 0.0005元/次 0.0004元/次 0.0003元/次
五官定位 0.002元/次 0.0018元/次 0.0015元/次
人脸比对 0.0032元/次 0.003元/次 0.0027元/次
人脸验证 0.0032元/次 0.003元/次 0.0027元/次
人脸搜索 0.0032元/次 0.003元/次 0.0027元/次
人员库管理 0.0032元/次 0.003元/次 0.0027元/次
人脸静态活体检测(高精度版) 0.15元/次 0.15元/次 0.15元/次

调用次数计费(资源包)

  • 示例一
    用户预计一年内调用人脸比对接口3000万次,可购买3个1000万次规格的人脸对比资源包,所需支付的费用计算如下:
    30400 * 3 = 91200(元)
  • 示例二
    用户当月累计调用人脸搜索接口3200万次,调用人员搜索接口2000万次,且已购买了1个5000万次规格的人脸搜索资源包。按照资源包次数耗尽后超额使用转入后付费模式的计算方式,且人脸搜索和人员搜索接口同属于 人脸搜索相关接口 合并计算调用量,所需支付的费用计算如下:
    (32000000 + 20000000 – 50000000-10000) * 0.0032 + 142500 = 148868(元)

调用次数计费(后付费)

  • 示例一
    用户当月累计调用五官定位接口 100 万次,按照阶梯到达的计算方式,所需支付的费用计算如下:
    (1000000 – 10000) * 0.002 = 1980(元)
  • 示例二
    用户当月累计调用人脸比对接口350万次,按照阶梯到达的计算方式,所需支付的费用计算如下:
    (3500000 – 10000) * 0.003 = 10470(元)
  • 示例三
    用户当月累计调用创建人员接口300万次、增加人脸接口200万次、获取人员库列表10万次、获取人员列表100万次,因为创建人员、增加人脸、获取人员库列表、获取人员列表四个接口同属 人员库管理相关接口,且仅创建人员和增加人脸两个子接口收费并合并计入人员库管理,按照阶梯到达的计算方式,所需支付的费用计算如下:
    (3000000 + 2000000 – 10000) * 0.003 = 14970(元)

QPS 计费

  • 示例
    用户需要购买1个月 + 5天的10个 QPS,可以按照包月 + 按天的搭配模式购买,所需支付的费用计算如下:
    (240 * 1 + 16 * 5) * 10 = 3200元

离线识别 SDK

按设备授权方式购买

  • 示例
    用户购买了1000台设备的离线人脸识别 SDK,按照阶梯到达的计算方式,所需支付的费用计算如下:
    1000 * 118 = 118000元

公共库识别人脸代码

import os
from PIL import Image
import face_recognition

# https://github.com/Silufer/dlib-python
# setx CMAKE_C_COMPILER "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\cl.exe"
# setx CMAKE_CXX_COMPILER "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\cl.exe"
# pip install face_recognition CMake Boost
# pip install cmake
# pip install dlib==19.8.1
# pip install face_recognition
# pip install opencv-contrib-python==4.1.0.25
# pip install twisted

def is_human_face(image_path):
    image = face_recognition.load_image_file(image_path)
    face_locations = face_recognition.face_locations(image)
    if len(face_locations) == 0:
        return False
    
    top, right, bottom, left = face_locations[0]
    face_width = right - left
    face_height = bottom - top
    face_area = face_width * face_height
    
    # 如果面积小于 70,视为非人脸
    if face_area < 70:
        return False
    
    return True

should_crop = input("是否需要裁剪人脸?(y/n)")
if should_crop == "y":
    should_crop = True
elif should_crop == "n":
    should_crop = False
else:
    print("无效输入,程序结束。")
    exit()

if not os.path.exists('face'):
    os.makedirs('face')

num_of_faces_detected = 0  # 统计检测到人脸的照片数量
x = 30 # 上下左右裁剪人脸间隔像素

for file_name in os.listdir('.'):
    if file_name.endswith('.jpg') or file_name.endswith('.png'):
        image_path = os.path.join('.', file_name)

        if is_human_face(image_path):
            
            # 移动原始人脸
            face_image_path = os.path.join('face', file_name)
            if os.path.exists(face_image_path):
                os.remove(face_image_path)
            os.rename(image_path, face_image_path)
            
            # 裁剪人脸区域并保存
            if should_crop:
                image = face_recognition.load_image_file(face_image_path)
                face_locations = face_recognition.face_locations(image)
                top, right, bottom, left = face_locations[0]
                top = max(0, top - x)
                bottom = min(image.shape[0], bottom + x)
                left = max(0, left - x)
                right = min(image.shape[1], right + x)
                face_image = Image.fromarray(image[top:bottom, left:right])
                face_image_path = os.path.join('face', file_name[:-4] + '_cut.jpg')
                face_image.save(face_image_path)
            
            num_of_faces_detected += 1

print("共检测到{}张人脸照片,已保存至 face 文件夹。".format(num_of_faces_detected))

if should_crop:
    print("已裁剪所有检测到的人脸,人脸上下左右各加" + str(x) + "像素,并保存至 face 文件夹中。")