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

作者: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, 【这是一个不错的项目】。

原图和戴眼镜后的效果如下:
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/35952.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发之路,穷且益坚,不坠青云之志(入门开发者共勉)

引言 2023毕业季,距离笔者毕业已过2年有余。 互联网从业环境由盛转衰,互联网从业者数量剧增,市场竞争异常激烈,原本的利润空间被不断挤压,以至于很多开发者对互联网已经失去了信心与激情。 互联网的市场份额依旧是占…

【数据架构系列-03】数据仓库、大数据平台、数据中台... 我不太认同《DataFun数据智能知识地图》中的定义

关注DataFunTalk有2年多了,DataFun确实像创始人王大川讲的那样,践行选择、努力和利他原则,专注于大数据、人工智能技术应用的分享与交流,秉承着开源开放的精神,免费的共享了很多有营养的行业实践专业知识,对…

VS2022配置OpenGL+GLAD

Glew(The OpenGL Extension Wrangler Library)是对底层OpenGL接口的封装,可以让你的代码跨平台。Glad与Glew作用相同,可以看作它的升级版。 Freeglut(OpenGL Utility Toolkit)主要用于创建并管理窗口和Ope…

chatMOSS的使用方法

1、开发者们在VScode界面找到应用商店扩展 2、搜索ChatMoss 并安装 3、CtrlF9快速唤醒使用 4、注册登录 字符数会更多(填:zgy999139.com 双方都会获得可用字符数)。 笔者体验用来写点小东西确实体验,加快效率,大家可以…

CoinMarketCap推出加密资产数据APP

点击上方 “蓝色字” 可关注我们! 暴走时评: 加密货币数据提供商CoinMarketCap推出了其首款Android应用程序并改进了其Apple iOS产品。 值得注意的是,该应用程序提供了CoinMarketCap网站上尚未提供的功能,包括投资组合跟踪&#x…

加密货币--Cryptocurrency

原文链接 Ever since Nas Daily’s video came out about how I earned over $400,000 with less than $10,000 investing in Bitcoin and Ethereum, I’ve been getting hundreds of questions from people around the world about how to get started with cryptocurrency i…

GIBXChange上线MT5交易平台:MT5 LP MAM+5A对冲模式强势来袭

引子 人类近代史就是一部金融的发展史,尤其21世纪更是金融的时代。金融市场的流动性带动着社会资源更广维度流动分配。交易的全球化,推动着地区资源和生产资料的全球化分配。尤其以外汇、期货市场的发展,携带着全球最大规模资金流通量的交易盘口,重构着全球金融市场的新秩…

Ubcoin市场:加密货币-商品交易平台

Ubcoin是一个区块链平台,使用例如亚马逊、Etsy和eBay所用的线上市场模型,打造全球首个真正有别于传统的加密货币交易平台。Ubcoin用户仅需售卖真实商品即可换取加密货币,并且能够使用加密货币购买商品,整条链上无需法定货币的参与…

印度尼西亚通过加密货币期货交易规则

点击上方 “蓝色字” 可关注我们! 暴走时评: 印度尼西亚贸易部下属的商品期货交易监管机构(Bappebti)于周一公布了该国期货交易所的加密资产交易新规则,规定加密货币期货交易所必须进行登记,获准后才能运营…

放弃几百万年薪的后续

厂长:和洋哥认识很久了,最近他从网易离职,放弃了几百万的年薪,全身心的投入AIGC,刚开始我得到这个消息很是诧异,在详谈之后才明白了洋哥背后的思考逻辑,刚好今天他也写了篇文章做了解释&#xf…

盘点一个AI你画我猜的小工具

点击上方“Python爬虫与数据挖掘”,进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 寻声暗问弹者谁,琵琶声停欲语迟。 大家好,我是Python进阶者。 一、前言 前几天在【ChatGPT&AI破局俱乐部】知识星球发现了一…

不愧是比亚迪!

最近这段时间,因为我自己准备买车嘛,然后先后去试驾了比亚迪汉、小鹏P7i、蔚来ET5、智己LS7这几辆车,接下来想分4篇文章依次给大家分享一下这四个品牌的车试驾体验。 比亚迪汉 小鹏P7i 蔚来ET5 这四个品牌总共花了三天时间,也算是…

使用AI,做抖音漫画短视频,4个人2天的工作量,1人仅需5小时即可完成

3 天前 ChatGPT云炬学长 ​关注 ​之前仅用一个多月就在抖音涨粉25w,虽然涨粉速度还可以,但账号至少需要4~5个人,(其中包括1个文案,2个漫画师,一个剪辑师,一个运营)才能保证日更。…

雷军也入局了...

风口理论的发明者雷总最近也杀入大模型&AI领域了,早在10多天前雷军在微博就发过一段话: 这段话其实已经暗示了雷军和他的小米已经在研发大模型产品了,相信要不了多久小米的大模型产品就会面世。 这下国内几乎所有互联网巨头都杀入了大模型…

阿里放大招了...

昨天阿里放了个大招:宣布自研大模型“通义千问”发布,不过目前只邀请企业用户进行体验测试,用户可通过官网申请,符合条件的用户可参与体验。 我没还没拿到邀请码,申请了体验资格正在排队中。但看完第三方的评测还是充满…

我干了一件大事!

最近读者朋友们应该都知道我做了一个付费社群,马上就要突破10000人了。 我一口气推了10多篇文章,都是关于我的AI星球:ChatGPT破局俱乐部。有些读者抱怨我:洋哥是不是在割韭菜? 另一方面因为我这个星球发展实在太快了&a…

转身卷OpenAI,这才真的香!

ChatGPT爆火后,OpenAI逐渐进入人们的视野。据levels.fyi显示,最近OpenAI给AI/ML岗(L5)开出$900k的高薪👇 反观其他大厂lowball的现状,转身卷OpenAI,是真的香! HC多、面试难&#xff…

自注意力机制(Self-Attention)

目录 一、注意力机制和自注意力机制的区别 二、引入自注意力机制的目的 三、Self-Attention详解 3.1 单个输出 3.2 矩阵形式 四、Multi-head Self-attention 五、Positional Encoding 六、Self-Attention和RNN的区别 一、注意力机制和自注意力机制的区别 Attention机制与…

慌了!ChatGPT吃我饭,还要掀我碗?

ChatGPT面世,各种被AI取代“失业言论”笼罩在人们头顶,本文聚焦这一问题,推荐关注ChatGPT的小伙伴阅读。 一时间火爆全网的新晋网红——ChatGPT,就问:还有谁不认识? 谷歌计划在旗舰搜索引擎中添加对话式人…

GPT/GP2/GPT3

GPT,GPT-2,GPT-3 论文精读【论文精读】_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1AF411b7xQ?spm_id_from333.999.0.0&vd_source4aed82e35f26bb600bc5b46e65e25c22 笔记:李沐老师GPT系列讲解 - 知乎今天分享的是李沐大神讲解…