基于PaddleHub的人脸美颜

随着各种美颜相机的出现,我们可以拍出各种胜似明星的照片,我们可以瘦脸、大眼、红唇以及增白,但这背后是如何实现的,你又了解多少呢?

AI美颜核心技术之一就是人脸关键点检测。PaddleHub已经开源了人脸关键点检测模型face_landmark_localization。人脸关键点检测是人脸识别和分析领域中的关键一步,它是诸如自动人脸识别、表情分析、三维人脸重建及三维动画等其它人脸相关问题的前提和突破口。该模型转换自 Github,支持同一张图中的多个人脸检测。它可以识别人脸中的68个关键点。

1、准备工作

(1)线上环境:百度AI Studio提供了线上一站式开发实训平台,直接可在该平台完成。
(2)本地实现:在本编译器中,需要提前安装PaddleHub库,pip安装即可,最好加上国内源。

pip install paddlehub==1.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

2、实现步骤

(1)人脸关键点检测

import cv2
import paddlehub as hub
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import mathsrc_img = cv2.imread('./test_sample.jpg')module = hub.Module(name="face_landmark_localization")
result = module.keypoint_detection(images=[src_img])tmp_img = src_img.copy()
for index, point in enumerate(result[0]['data'][0]):# cv2.putText(img, str(index), (int(point[0]), int(point[1])), cv2.FONT_HERSHEY_COMPLEX, 3, (0,0,255), -1)cv2.circle(tmp_img, (int(point[0]), int(point[1])), 2, (0, 0, 255), -1)res_img_path = 'face_landmark.jpg'
cv2.imwrite(res_img_path, tmp_img)img = mpimg.imread(res_img_path)
# 展示预测68个关键点结果
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis('off')
plt.show()

可得出人脸的68个关键点图:

(2)瘦脸

利用识别到的68个关键点完成瘦脸功能。左右脸各瘦多少,可以根据图片和自己的满意度,改变参数 face_landmark[ ]。同时利用局部平移算法局部平移算法完成瘦脸.

import numpy as np
import math
'''1、瘦脸'''
def thin_face(image, face_landmark):"""实现自动人像瘦脸image: 人像图片face_landmark: 人脸关键点"""end_point = face_landmark[30]# 瘦左脸,3号点到5号点的距离作为瘦脸距离dist_left = np.linalg.norm(face_landmark[3] - face_landmark[5])image = local_traslation_warp(image, face_landmark[3], end_point, dist_left)# 瘦右脸,13号点到15号点的距离作为瘦脸距离dist_right = np.linalg.norm(face_landmark[13] - face_landmark[15])image = local_traslation_warp(image, face_landmark[13], end_point, dist_right)return imagedef local_traslation_warp(image, start_point, end_point, radius):"""局部平移算法"""radius_square = math.pow(radius, 2)image_cp = image.copy()dist_se = math.pow(np.linalg.norm(end_point - start_point), 2)height, width, channel = image.shapefor i in range(width):for j in range(height):# 计算该点是否在形变圆的范围之内# 优化,第一步,直接判断是会在(start_point[0], start_point[1])的矩阵框中if math.fabs(i - start_point[0]) > radius and math.fabs(j - start_point[1]) > radius:continuedistance = (i - start_point[0]) * (i - start_point[0]) + (j - start_point[1]) * (j - start_point[1])if (distance < radius_square):# 计算出(i,j)坐标的原坐标# 计算公式中右边平方号里的部分ratio = (radius_square - distance) / (radius_square - distance + dist_se)ratio = ratio * ratio# 映射原位置new_x = i - ratio * (end_point[0] - start_point[0])new_y = j - ratio * (end_point[1] - start_point[1])new_x = new_x if new_x >= 0 else 0new_x = new_x if new_x < height - 1 else height - 2new_y = new_y if new_y >= 0 else 0new_y = new_y if new_y < width - 1 else width - 2# 根据双线性插值法得到new_x, new_y的值image_cp[j, i] = bilinear_insert(image, new_x, new_y)return image_cpdef bilinear_insert(image, new_x, new_y):"""双线性插值法"""w, h, c = image.shapeif c == 3:x1 = int(new_x)x2 = x1 + 1y1 = int(new_y)y2 = y1 + 1part1 = image[y1, x1].astype(np.float) * (float(x2) - new_x) * (float(y2) - new_y)part2 = image[y1, x2].astype(np.float) * (new_x - float(x1)) * (float(y2) - new_y)part3 = image[y2, x1].astype(np.float) * (float(x2) - new_x) * (new_y - float(y1))part4 = image[y2, x2].astype(np.float) * (new_x - float(x1)) * (new_y - float(y1))insertValue = part1 + part2 + part3 + part4return insertValue.astype(np.int8)face_landmark = np.array(result[0]['data'][0], dtype='int')src_img = thin_face(src_img, face_landmark)res_img_path = 'res.jpg'
cv2.imwrite(res_img_path, src_img)img = mpimg.imread(res_img_path)
# 展示瘦脸图片
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.axis('off')
plt.show()

瘦脸图片展示:

(3)大眼

完成瘦脸之后,我们还可以对人像中的眼睛进行放大。在识别到的左右眼中的一个位置,对其进行缩放(图像局部缩放算法),实现大眼。

'''2、大眼
完成瘦脸之后,我们还可以对人像中的眼睛进行放大。
在识别到的左右眼中的一个位置,对其进行缩放(图像局部缩放),实现大眼。'''
import math
import numpy as npdef enlarge_eyes(image, face_landmark, radius=15, strength=10):"""放大眼睛image: 人像图片face_landmark: 人脸关键点radius: 眼睛放大范围半径strength:眼睛放大程度"""# 以左眼最低点和最高点之间的中点为圆心left_eye_top = face_landmark[37]left_eye_bottom = face_landmark[41]left_eye_center = (left_eye_top + left_eye_bottom)/2# 以右眼最低点和最高点之间的中点为圆心right_eye_top = face_landmark[43]right_eye_bottom = face_landmark[47]right_eye_center = (right_eye_top + right_eye_bottom)/2# 放大双眼local_zoom_warp(image, left_eye_center, radius=radius, strength=strength)local_zoom_warp(image, right_eye_center, radius=radius, strength=strength)def local_zoom_warp(image, point, radius, strength):"""图像局部缩放算法"""height = image.shape[0]width = image.shape[1]left =int(point[0] - radius) if point[0] - radius >= 0 else 0top = int(point[1] - radius) if point[1] - radius >= 0 else 0right = int(point[0] + radius) if point[0] + radius < width else width-1bottom = int(point[1] + radius) if point[1] + radius < height  else height-1radius_square = math.pow(radius, 2)for y in range(top, bottom):offset_y = y - point[1]for x in range(left, right):offset_x = x - point[0]dist_xy = offset_x * offset_x + offset_y * offset_yif dist_xy <= radius_square:scale = 1 - dist_xy / radius_squarescale = 1 - strength / 100 * scalenew_x = offset_x * scale + point[0]new_y = offset_y * scale + point[1]new_x = new_x if new_x >=0 else 0new_x = new_x if new_x < height-1 else height-2new_y = new_y if new_y >= 0 else 0new_y = new_y if new_y < width-1 else width-2image[y, x] = BilinearInsert(image, new_x, new_y)# 双线性插值法
def BilinearInsert(src, ux, uy):w, h, c = src.shapeif c == 3:x1 = int(ux)x2 = x1 + 1y1 = int(uy)y2 = y1 + 1part1 = src[y1, x1].astype(np.float) * (float(x2) - ux) * (float(y2) - uy)part2 = src[y1, x2].astype(np.float) * (ux - float(x1)) * (float(y2) - uy)part3 = src[y2, x1].astype(np.float) * (float(x2) - ux) * (uy - float(y1))part4 = src[y2, x2].astype(np.float) * (ux - float(x1)) * (uy - float(y1))insertValue = part1 + part2 + part3 + part4return insertValue.astype(np.int8)
'''在瘦脸的基础上,继续放大双眼'''
enlarge_eyes(src_img, face_landmark, radius=13, strength=13)
cv2.imwrite(res_img_path, src_img)
img = mpimg.imread(res_img_path)
plt.figure(figsize=(10, 10))
plt.imshow(img)
plt.axis('off')
plt.show()

大眼结果展示:

(4)红唇

目前已经叠加了瘦脸、大眼的美颜功能,我们还可以给人像增添气色,给人像画上红唇。我们只需将识别到的唇部位置给涂上红色即可达到相应的目的。

import cv2def rouge(image, face_landmark, ruby=True):"""自动涂口红image: 人像图片face_landmark: 人脸关键点ruby:是否需要深色口红"""image_cp = image.copy()if ruby:rouge_color = (0, 0, 255)else:rouge_color = (0, 0, 200)points = face_landmark[48:68]hull = cv2.convexHull(points)cv2.drawContours(image, [hull], -1, rouge_color, -1)cv2.addWeighted(image, 0.2, image_cp, 0.9, 0, image_cp)return image_cp
'''继续叠加红唇'''
src_img = rouge(src_img, face_landmark)
cv2.imwrite(res_img_path, src_img)
img = mpimg.imread(res_img_path)
plt.figure(figsize=(10, 10))
plt.imshow(img)
plt.axis('off')
plt.show()

红唇结果展示:

(5)美白

我们还可以加上美肤功能。由于标记出来的68个关键点没有涵盖额头的位置,我们需要预估额头位置。为了简单估计二头所在区域,本教程以0号、16号点所在线段为直径的半圆为额头位置。

import cv2
import numpy as npdef whitening(img, face_landmark):"""美白"""# 简单估计额头所在区域# 根据0号、16号点画出额头(以0号、16号点所在线段为直径的半圆)radius=(np.linalg.norm(face_landmark[0] - face_landmark[16]) / 2).astype('int32')center_abs=tuple(((face_landmark[0] + face_landmark[16]) / 2).astype('int32'))angle=np.degrees(np.arctan((lambda l:l[1]/l[0])(face_landmark[16]-face_landmark[0]))).astype('int32')face = np.zeros_like(img)cv2.ellipse(face,center_abs,(radius,radius),angle,180,360,(255,255,255),2)points=face_landmark[0:17]hull = cv2.convexHull(points)cv2.polylines(face, [hull], True, (255,255,255), 2)index = face >0face[index] = img[index]dst = np.zeros_like(face)# v1:磨皮程度v1 = 3# v2: 细节程度v2 = 2tmp1 = cv2.bilateralFilter(face, v1 * 5, v1 * 12.5, v1 * 12.5)tmp1 = cv2.subtract(tmp1,face)tmp1 = cv2.add(tmp1,(10,10,10,128))tmp1 = cv2.GaussianBlur(tmp1,(2*v2-1, 2*v2-1),0)tmp1 = cv2.add(img,tmp1)dst = cv2.addWeighted(img, 0.1, tmp1, 0.9, 0.0)dst = cv2.add(dst,(10, 10, 10,255))index = dst>0img[index] = dst[index]return img
    '''美白'''src_img = whitening(src_img, face_landmark)cv2.imwrite(res_img_path, src_img)img = mpimg.imread(res_img_path)plt.figure(figsize=(10, 10))plt.imshow(img)plt.axis('off')plt.savefig('result_pic_test2.png')plt.show()

美白后的图片:

3、后续

经过前面几步,大体的美颜工作已经完成,同时我们可以在美白后的基础上继续一些处理,比如描眉、去痘等等。

同时,需要注意的是瘦脸时的,点一定要选好,不然图片中人脸会变形。

人脸美颜——飞桨PaddleHub实战相关推荐

  1. 一键人物抠图、人物图片背景替换——飞桨PaddleHub实战

    PaddleHub一键抠图并替换背景 抠图模型千千万,而我就用DeepLabv3+.DeepLabv3+ 是Google DeepLab语义分割系列网络的最新作,其前作有 DeepLabv1,Deep ...

  2. 当飞桨PaddleHub遇到微信小程序,AI也能指物作诗

    点击左上方蓝字关注我们 [飞桨开发者说]刘建建,飞桨开发者,现工作于西部某厂,从事管理工作. 项目构想 最近飞桨PaddleHub大火,吸引无数开发者眼球,作为俗人的我也不例外,被看图写诗和艺术风格迁 ...

  3. 飞桨PaddleHub实现皮影戏

    飞桨(PaddlePaddle)是集深度学习核心框架.工具组件和服务平台为一体的技术先进.功能完备的开源深度学习平台,已被中国企业广泛使用,深度契合企业应用需求,拥有活跃的开发者社区生态.提供丰富的官 ...

  4. 使用飞桨PaddleHub实现将视频动作转化为皮影戏

    前言 飞桨(PaddlePaddle)是集深度学习核心框架.工具组件和服务平台为一体的技术先进.功能完备的开源深度学习平台,已被中国企业广泛使用,深度契合企业应用需求,拥有活跃的开发者社区生态.提供丰 ...

  5. Linux系统 安装飞桨PaddleHub+LAC实现词法分析 实现加载自定义词典分词 (解决Lac服务启动报错问题、解决自定义词典空格无法分词问题)

    1.先上链接:飞桨PaddlePaddle-源于产业实践的开源深度学习平台 2.LAC模型简介:Lexical Analysis of Chinese,简称 LAC,是一个联合的词法分析模型,能整体性 ...

  6. 超有范,使用飞桨paddleHub抠图制作任意形状的词云(学习心得)

    文章目录 1 抠图代码 2 抠图效果 3 绘制词云图 4 词云效果图 5 项目链接 链接 1 抠图代码 # 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Als ...

  7. 双服务器架构实战飞桨部署-自动上色和老相片修复

    双服务器架构实战飞桨部署-自动上色和老相片修复 宋 朱熹 <即事有怀寄彦辅仲宗二兄>诗之二:"闻说双飞桨,翩然下广津. 飞桨功能强大,部署非常简单方便(对我这个不熟练的人,并不是 ...

  8. 截屏就可以转文字?飞桨带您体验OCR超轻量中英文识别模型

    [飞桨开发者说]陈千鹤,华中科技大学计算机科学与技术学院大一在读 任务背景 目前很多实用小工具都趋向收费模式,即使免费,不是功能不完整,就是有很多约束条件,在应用时效果无法达到我们的预期.于是我萌生一 ...

  9. “OpenI/O 2020启智开发者大会”共话开源,百度飞桨引领行业发展

    点击左上方蓝字关注我们 2020年12月2日,"OpenI/O 2020启智开发者大会"在北京国家会议中心召开.大会以"启智筑梦 开源先行"为主题,立足于国际国 ...

最新文章

  1. cordova 学习笔记
  2. boost::graph::dimacs_basic_reader用法的测试程序
  3. P4294-[WC2008]游览计划【斯坦纳树】
  4. tms tck_在雅加达EE TCK中使用Arquillian的可能方法
  5. Jmeter 生成HTML性能测试报告
  6. java 对象流 乱码,JAVA 中的 IO 流
  7. 配置hive元数据到mysql后启动不了 java.sql.SQLException: Access denied for user ‘root‘@‘hd101‘ (using password:
  8. yapi接口管理工具
  9. java实现日期转中文大写形式
  10. 2db多少功率_功率换算(dB与W).doc
  11. python中正则表达式与jieba分词的使用
  12. xinxin--小爱同学
  13. 视频教程-Excel玩转财务管理-Office/WPS
  14. 软件开发中的需求分析
  15. mysql 安装启动服务器一直失败_mysql安装后服务器启动失败的几种解决办法
  16. 软件测试是要学习什么技能?
  17. 上海无印良品地理空间分布特征与选址策略可视化研究
  18. matlab中nnt,基于MATLAB的边坡稳定性评价方法
  19. 注意力不集中是因为你没有紧迫感
  20. 『C语言』题集 of ⑩

热门文章

  1. IIS无法访问aspx文件的解决方法
  2. spark 面试题汇总
  3. Android视频背景,动态背景
  4. Go 语言是一种什么语言?
  5. 透过《2021中国SaaS市场研究报告》,看用友YonSuite等如何引领云服务发展
  6. 外卖CPS公众号分销裂变小程序搭建和培训(附源代码和0基础搭建教程)
  7. Shark(鲨鱼记账系统)--附源码
  8. 好用的DNS服务器推荐
  9. 计算机系统软件怎么记,我是怎样记住和应用电脑软件快捷键的
  10. 戴尔服务携手SAP助力中国企业全球化发展