作者:busyboxs

本项目主要使用的 API 是人脸关键点检测。因为给人脸加眼镜特效其实只需要眼睛相关的关键点即可,所以本项目为了简单,使用的是百度 AI 人脸检测 API 中的 landmark4(左眼中心、右眼中心、鼻尖、嘴中心),所以也不算是一个新品体验吧。但是呢可以在更多的关键点上加更多的特效,等后期有时间再完善吧。

本项目主要基于 python3 实现。代码地址:https://github.com/busyboxs/baiduAIFace/blob/master/face_landmarks_simple.py

人脸检测与属性分析 API 介绍
本部分参考自官方文档,更多细节参考 http://ai.baidu.com/docs#/Face-Detect-V3/top

接口能力
•人脸检测:检测图片中的人脸并标记出位置信息;
•人脸关键点:展示人脸的核心关键点信息,及150个关键点信息。
•人脸属性值:展示人脸属性信息,如年龄、性别等。
•人脸质量信息:返回人脸各部分的遮挡、光照、模糊、完整度、置信度等信息。

请求参数

•max_face_num: 为了能够检测多个人脸,这个参数最好设置为 10;
•image: 图像信息,依据 image_type 不同而不同;
•image_type: (BASE64, image 为图片的 base64 编码), (URL, image 为图片的URL地址),(FACE_TOKEN, image 为一个唯一的标志)
•face_field:包括(age, beauty, expression, face_shape,gender, glasses, landmark, landmark72, landmark150, race, quality, eye_status, emotion, face_type),可以根据具体需求进行设置。

其他两个参数保持默认就行,若是有特殊需要,也可进行修改。

如果 image_type 设置为 BASE64,则图像需要进行 base64 编码,python3 中 base64 编码的具体代码如下:

import base64def pic_base64(image_path):with open(image_path, 'rb') as f:base64_data = base64.b64encode(f.read())return base64_data

输出的 base64_data 的 type 为 。

返回参数
根据 face_field 的不同返回的结果不同。具体的返回结果参数及描述参见 http://ai.baidu.com/docs#/Face-Detect-V3/top 。接下来对不同的 face_field 进行讨论。

默认返回字段
默认情况下,即不论 face_field 为什么,都一定会输出的字段。这些字段包括 angle, face_probability, face_token 和 location,分别代表人脸在三维中的角度,人脸置信度,人脸图片的唯一标识和人脸在框。其中一个输出样例如下:

{'face_list': [{'angle': {'pitch': 9.28, 'roll': 20.87, 'yaw': 5.92},'face_probability': 1,'face_token': 'a8b2a513ffa1f726ec15818d81583861','location': {'height': 198,'left': 436.45,'rotation': 24,'top': 98.36,'width': 214}}],'face_num': 1}

其他返回字段注:以下展示的返回不包括上面的四个默认字段,但是这四个字段是一定会返回的。
•face_field 包含 age 时,代表年龄,返回包含 ‘face_list’: [{‘age’: 25}]​

•face_field 包含 beauty 时,代表美丑打分,返回包含 ‘face_list’: [{‘beauty’: 63.9,}]​

•face_field 包含 expression 时,代表表情,返回包含 ‘face_list’: [{‘expression’: {‘probability’: 0.64, ‘type’: ‘none’},}]​

•face_field 包含 face_shape 时,代表脸型,返回包含 ‘face_list’: [{‘face_shape’: {‘probability’: 0.44, ‘type’: ‘oval’},}]​

•face_field 包含 gender 时,代表性别,返回包含 ‘face_list’: [{‘gender’: {‘probability’: 1, ‘type’: ‘female’},}]​

•face_field 包含 glasses 时,代表是否带眼镜,返回包含 ‘face_list’: [{‘glasses’: {‘probability’: 1, ‘type’: ‘none’},}]​

•face_field 包含 landmark 时,会返回 4 点 landmark 和 72 点 landmark,

face_list': [{'landmark': [{'x': 465.13, 'y': 146.17},{'x': 550.82, 'y': 184.07},{'x': 481.01, 'y': 212.33},{'x': 464.83, 'y': 260.26}],'landmark72': [{'x': 422.01, 'y': 130.14},{'x': 410.94, 'y': 158.96},{'x': 403.67, 'y': 184.87},...{'x': 462.4, 'y': 263.8},{'x': 447.01, 'y': 254.79}],}]

•face_field 包含 landmark72 时,竟然没有对应的返回值,这可能是个 bug。
•face_field 包含 landmark150 时,返回对应 150 个关键点,

'face_list': [{'landmark150': {'cheek_left_1': {'x': 623.08, 'y': 219.69},'cheek_left_10': {'x': 497.4, 'y': 323.65},...'nose_tip': {'x': 477.8, 'y': 210.79}},}]​

•face_field 包含 race 时,代表人种,返回包含

'face_list': [{'race': {'probability': 1, 'type': 'white'}}],}]​

•face_field 包含 quality 时,代表人脸质量信息,返回包含

'face_list': [{'quality': {'blur': 0,'completeness': 1,'illumination': 157,'occlusion': {'chin_contour': 0,'left_cheek': 0.1,'left_eye': 0.59,'mouth': 0,'nose': 0,'right_cheek': 0.02,'right_eye': 0.33}}}]​

•face_field 包含 eye_status 时,代表双眼状态(睁开/闭合),返回包含 ‘face_list’: [{‘eye_status’: {‘left_eye’: 1, ‘right_eye’: 1},}]​

•face_field 包含 emotion 时,代表情绪,返回包含 ‘face_list’: [{‘emotion’: {‘probability’: 0.71, ‘type’: ‘happy’},}]​

•face_field 包含 face_type 时,代表真实人脸/卡通人脸,返回包含 ‘face_list’: [{‘face_type’: {‘probability’: 0.98, ‘type’: ‘human’},}]​

关于人脸关键点的更多信息参考 http://ai.baidu.com/docs#/Face-Detect-V3/top

利用关键点实现戴眼镜特效
获取 access_token
要调用百度 AI API 的接口,需要创建对应的应用并获取 access_token.

创建应用
首先登陆百度 AI 控制台(https://console.bce.baidu.com/?fromai=1#/aip/overview ) ,然后点击右侧导航栏里面的 “人脸识别”。

然后点击创建应用,好像有些接口在 V3 版本中才有,具体的参考文档。

填好“应用名称”和“应用描述”后点击“创建应用”。

创建好应用之后,进入“应用列表”,就能看到应用的相关信息,我们需要的是 API Key 和 Secret Key。

获取 access token
通过 API Key 和 Secret Key 获取的 access_token。更多关于 access_token 的获取方法参考 http://ai.baidu.com/docs#/Auth/top 。

下面代码是 python3 获取 access_token 的代码

from urllib.request import urlopen, Request
import jsondef get_token_key():token_key = ''client_id = '填写上面获取的 API key'  # API keyclient_secret = '填写上面获取的 Secret key'  # Secret keyhost = f'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials' \f'&client_id={client_id}&client_secret={client_secret}'request = Request(host)request.add_header('Content-Type', 'application/json; charset=UTF-8')response = urlopen(request)token_content = response.read()if token_content:token_info = json.loads(token_content)token_key = token_info['access_token']return token_key

调用人脸检测接口
调用人脸检测接口的 python3 实现代码如下:

from urllib.request import urlopen, Request
import jsondef get_face_info(image_base64, token_key):request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"params_d = dict()params_d['image'] = str(image_base64, encoding='utf-8')params_d['image_type'] = 'BASE64'params_d['face_field'] = 'landmark'params_d['max_face_num'] = 10params = json.dumps(params_d).encode('utf-8')access_token = token_keyrequest_url = request_url + "?access_token=" + access_tokenrequest = Request(url=request_url, data=params)request.add_header('Content-Type', 'application/json')response = urlopen(request)content = response.read()if content:data = json.loads(content)assert data['error_code'] == 0, data# pprint(data)return data['result']

这里将具体的几个字段直接通过字符串指定在函数内,你也可以通过传递参数来实现。注意,该函数参数 image_base64 的 type 为 byte,需要转换为 str 才能序列化为 json。通过指定不同的 face_field 值能够得到前面说明的返回字段,该项目只需要使用人脸关键点,并且使用的是 4 个人脸关键点,所以指定 face_field 为 landmrak。

得到返回结果后,我们还需要将人脸关键点结构化,下面是 python3 获取 landmark 的代码:

def get_face_num(data):return data['face_num']def get_landmark4(data):landmarks = list()face_num = get_face_num(data)for i in range(face_num):landmark = list()for j in range(4):x = data['face_list'][i]['landmark'][j]['x']y = data['face_list'][i]['landmark'][j]['y']landmark.append(list(map(int, (x, y))))landmarks.append(landmark)return landmarks

因为可能一张图像中含有多个人脸,因此需要对每个人脸的关键点进行结构化。

4个关键点位置分别为左眼中心、右眼中心、鼻尖、嘴中心,我们只需要左眼中心和右眼中心,即 landmark[0] 和 landmark[1]。

加眼镜特效
首先通过两个坐标点(左眼中心、右眼中心)可以计算出两点所在直线相对于水平线的夹角,同时可以计算出两点之间的距离。

lmk0 = np.array(landmark[0])  # right eye center
lmk1 = np.array(landmark[1])  # left eye center
# for j in range(len(landmark))[:2]:
#     cv2.circle(image, (landmark[j][0], landmark[j][1]), 1, (0, 255, 0), 2)glasses_center = np.mean([lmk0, lmk1], axis=0)  # the center of glasses mask
glasses_size = np.linalg.norm(lmk0 - lmk1) * 2  # the width of glasses mask
angle = -util.angle_between(lmk0, lmk1)

这里认为两点间线段的中点坐标为需要带上的眼镜图像(glasses mask)的中心,将线段间的距离的2倍认为是需要带上眼镜图像的宽(width,带有一定角度)。

然后我们这里默认输入的眼镜图像是透明的(png)和水平的,例如

glasses_h, glasses_w = glasses.shape[:2]
glasses_c = (glasses_w / 2, glasses_h / 2)
M = cv2.getRotationMatrix2D(glasses_c, angle, 1)
cos = np.abs(M[0, 0])
sin = np.abs(M[0, 1])# compute the new bounding dimensions of the image
nW = int((glasses_h * sin) + (glasses_w * cos))
nH = int((glasses_h * cos) + (glasses_w * sin))# adjust the rotation matrix to take into account translation
M[0, 2] += (nW / 2) - glasses_c[0]
M[1, 2] += (nH / 2) - glasses_c[1]rotated_glasses = cv2.warpAffine(glasses, M, (nW, nH))

这段代码也可以直接使用 rotated_glasses = imutils.rotate_bound(glasses, -angle) 来替换,不过需要安装 imutils,关于该函数和该库的说明可以参见 https://blog.csdn.net/u011511601/article/details/79529318

比如一个旋转一定角度的眼镜图像为

然后将旋转后的眼镜图像与人脸图像在指定的眼镜 mask 区域进行融合,融合代码如下:

def overlay_transparent(background_img, img_to_overlay_t, x, y, overlay_size=None):bg_img = background_img.copy()# convert 3 channels to 4 channelsif bg_img.shape[2] == 3:bg_img = cv2.cvtColor(bg_img, cv2.COLOR_BGR2BGRA)if overlay_size is not None:img_to_overlay_t = cv2.resize(img_to_overlay_t.copy(), overlay_size)b, g, r, a = cv2.split(img_to_overlay_t)mask = cv2.medianBlur(a, 5)h, w, _ = img_to_overlay_t.shaperoi = bg_img[int(y - h / 2):int(y + h / 2), int(x - w / 2):int(x + w / 2)]img1_bg = cv2.bitwise_and(roi.copy(), roi.copy(), mask=cv2.bitwise_not(mask))img2_fg = cv2.bitwise_and(img_to_overlay_t, img_to_overlay_t, mask=mask)bg_img[int(y - h / 2):int(y + h / 2), int(x - w / 2):int(x + w / 2)] = cv2.add(img1_bg, img2_fg)# convert 4 channels to 3 channelsbg_img = cv2.cvtColor(bg_img, cv2.COLOR_BGRA2BGR)return bg_img

这个代码来自 https://github.com/kairess/cat_hipsterizer/blob/master/test.py, 【这是一个不错的项目】。

原图和戴眼镜后的效果如下:

识别人脸关键点给人脸加眼镜特效相关推荐

  1. 人工智能AI系列 - 人脸识别套件列表,包括人脸检测,人脸识别,人脸关键点,人脸比对,人脸搜索等等。

    人脸识别套件列表 打造最好的java开源人脸识别套件,包括人脸检测,人脸识别,人脸关键点,人脸比对,人脸搜索等等. 人脸检测SDK 人脸检测SDK 链接 人脸检测 (含5个人脸关键点) SDK 链接 ...

  2. paddle2.0高层API实现人脸关键点检测(人脸关键点检测综述_自定义网络_paddleHub_趣味ps)

    paddle2.0高层API实现人脸关键点检测(人脸关键点检测综述_自定义网络_paddleHub_趣味ps) 本文包含了: - 人脸关键点检测综述 - 人脸关键点检测数据集介绍以及数据处理实现 - ...

  3. 基于人脸关键点修复人脸,腾讯等提出优于SOTA的LaFIn生成网络

    作者 | Yang Yang.Xiaojie Guo.Jiayi Ma.Lin Ma.Haibin Ling 译者 | 刘畅 编辑 | Jane 出品 | AI科技大本营(ID:rgznai100) ...

  4. caffe 人脸关键点检测_全套 | 人脸检测 人脸关键点检测 人脸卡通化

    点击上方"AI算法与图像处理",选择加"星标"或"置顶" 重磅干货,第一时间送达 来源:CVPy 人脸检测历险记 可能跟我一样,人脸检测是很 ...

  5. 【dlib库】进行人脸检测+人脸关键点检测+人脸对齐

    原图像: 1. 人脸检测 import cv2 import dlib import matplotlib.pyplot as plt # 获取图片 my_img = cv2.imread('my_i ...

  6. Opencv与dlib联合进行人脸关键点检测与识别

    前言 依赖库:opencv 2.4.9 /dlib 19.0/libfacedetection 本篇不记录如何配置,重点在实现上.使用libfacedetection实现人脸区域检测,联合dlib标记 ...

  7. 【技术综述】人脸关键点检测的数据集与核心算法

    人脸关键点检测是诸如人脸识别.表情分析.三维人脸重建等其它人脸相关任务的基础.近些年来,深度学习方法已被成功应用到了人脸的关键点检测,本章将介绍深度学习方法在人脸关键点检测方向的研究.包括人脸关键点任 ...

  8. 关键点提取:face_recognition、疲劳检测、人脸校准、人脸数据库

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 人脸识别功能实现的原理介绍与算法介绍 人脸识别:人脸数据集 A ...

  9. caffe 人脸关键点检测_人脸关键点对齐

    摘要: 从传统方法到深度学习方法,对人脸关键点定位/人脸对齐的发展进行梳理,对该领域中经典的方法,最新成果进行汇总,并给出相应的paper原文,项目主页及代码链接.重点介绍深度学习的几种最新方法. 1 ...

最新文章

  1. 如何确定最佳训练数据集规模?6 大必备“锦囊”全给你了
  2. Hive和HBase
  3. 【freemarker】渲染列表一系列操作
  4. .实现 linkedlist 类java_面试官:兄弟,说说 ArrayList 和 LinkedList 有什么区别
  5. flask基础之jinja2模板-语法定义
  6. matlab中GUI的属性检查器中的XLimMode是什么_如何在Matlab中使用GUI做一个简易音乐播放器? ---- (二)GUIDE...
  7. 信息安全工程师笔记-恶意代码防范技术原理
  8. java treemap value排序_【TreeMap】对Map按key和value分别排序
  9. 红米旗舰机命名Redmi X?卢伟冰:会有更好的名字
  10. 对10亿个数据去重java_JAVA 8 新特性
  11. HDU 2588 GCD
  12. 队列在层次遍历中的应用
  13. vue-cli搭建项目引入jquery和jquery-weui步骤详解
  14. 01-【分析】神策系统的拆解与分析
  15. 使用QT写的串口调试助手源代码分享(一)
  16. C-CCSK云计算安全知识认证
  17. 【浅墨著作】 OpenCV3编程入门 内容简介 勘误 配套源代码下载
  18. Mysql:外码约束
  19. 源码时代UI干货分享| AE如何实现文字消散效果?看这一篇就够了!
  20. 小程序识别企业微信二维码功能

热门文章

  1. 用case语句后面跟范围
  2. Android 不让系统相册扫描到指定目录下的图片
  3. 通用软件版本记录笔记(6/5)
  4. 云服务器使用初体验博客征文获奖通知
  5. 对PPS文件的再编辑
  6. C# Winform Chart控件用法4之饼状图
  7. c语言中用简易暗纹来输入密码,本人打印下载练习时,想去掉暗纹或底纹,想请 – 手机爱问...
  8. mac安装git的时候踩过的坑
  9. LaTeX C++代码块
  10. 日本公司怎么注册?有何优势呢?