文章目录

  • 美颜瘦脸
  • 先看效果
  • 先上源码
  • 实现
    • 识别人脸并定位特征点
    • 人脸分割
    • 瘦脸变形
  • 像素偏移后结果
  • 去掉特征点后结果

美颜瘦脸

在这个靠脸吃饭的时代,有张漂亮的脸蛋无疑会令你加分不少;那万一天生的颜值不够怎么办呢?。。。还有美颜来拯救。

现在很多相机以及大多数修图软件都提供了瘦脸的功能。现在主流的瘦脸功能都是基于opengl来完成的。

先看效果

原图:

瘦脸:

很明显下面的照片要比上面的照片的脸要瘦了很多。
下面一步步去实现这些功能。

先上源码

VS2019的项目,环境完整,可直接运行

实现

识别人脸并定位特征点

用dlib或者face++或者自己训练个神经网络去识别出特征点。
这里我用dlib 识别出特征点

初始化dlib:

    dlib::frontal_face_detector detector;dlib::shape_predictor pose_model;std::string  facemodel = "./model/shape_predictor_68_face_landmarks.dat";detector = dlib::get_frontal_face_detector();dlib::deserialize(facemodel) >> pose_model;

识别人脸并保存特征点

    dlib::cv_image<dlib::bgr_pixel> cimg(src);std::vector<dlib::rectangle> faces = detector(cimg);  // Detect facesdlib::full_object_detection  shape;      // Find the pose of one facefacelandmarks.clear();if (faces.size() > 0) {shape = pose_model(cimg, faces[0]);facerect = cv::Rect(cv::Point2i(faces[0].left(), faces[0].top()), cv::Point2i(faces[0].right() + 1, faces[0].bottom() + 1));for (int i = 0; i < 68; i++) {facelandmarks.push_back(cv::Point2f(shape.part(i).x(), shape.part(i).y()));}}else {return -1;}

识别的特征点如下 共68个:

人脸分割

这里为了简单只将图片分为26个三角形。若想效果更平滑,可以将图片分的更细。

 //人脸分割cv::Point2f LALL0 = cv::Point2f(-1.0f, -1.0f);cv::Point2f LALL1 = cv::Point2f(-1.0f, 1.0f);cv::Point2f LALL2 = cv::Point2f(1.0f, 1.0f);cv::Point2f LALL3 = cv::Point2f(1.0f, -1.0f);cv::Point2f LFace30 = cv::Point2f(facelandmarks[30].x * 2.0 / width - 1.0, (height - facelandmarks[30].y) * 2.0 / height - 1.0);cv::Point2f LFace3 = cv::Point2f(facelandmarks[3].x * 2.0 / width - 1.0, (height - facelandmarks[3].y) * 2.0 / height - 1.0);cv::Point2f LFace4 = cv::Point2f(facelandmarks[4].x * 2.0 / width - 1.0, (height - facelandmarks[4].y) * 2.0 / height - 1.0);cv::Point2f LFace5 = cv::Point2f(facelandmarks[5].x * 2.0 / width - 1.0, (height - facelandmarks[5].y) * 2.0 / height - 1.0);cv::Point2f LFace6 = cv::Point2f(facelandmarks[6].x * 2.0 / width - 1.0, (height - facelandmarks[6].y) * 2.0 / height - 1.0);cv::Point2f LFace7 = cv::Point2f(facelandmarks[7].x * 2.0 / width - 1.0, (height - facelandmarks[7].y) * 2.0 / height - 1.0);cv::Point2f LFace8 = cv::Point2f(facelandmarks[8].x * 2.0 / width - 1.0, (height - facelandmarks[8].y) * 2.0 / height - 1.0);cv::Point2f LFace9 = cv::Point2f(facelandmarks[9].x * 2.0 / width - 1.0, (height - facelandmarks[9].y) * 2.0 / height - 1.0);cv::Point2f LFace10 = cv::Point2f(facelandmarks[10].x * 2.0 / width - 1.0, (height - facelandmarks[10].y) * 2.0 / height - 1.0);cv::Point2f LFace11 = cv::Point2f(facelandmarks[11].x * 2.0 / width - 1.0, (height - facelandmarks[11].y) * 2.0 / height - 1.0);cv::Point2f LFace12 = cv::Point2f(facelandmarks[12].x * 2.0 / width - 1.0, (height - facelandmarks[12].y) * 2.0 / height - 1.0);cv::Point2f LFace13 = cv::Point2f(facelandmarks[13].x * 2.0 / width - 1.0, (height - facelandmarks[13].y) * 2.0 / height - 1.0);cv::Point2f VALL0 = cv::Point2f(0.0f, 1.0f);cv::Point2f VALL1 = cv::Point2f(0.0f, 0.0f);cv::Point2f VALL2 = cv::Point2f(1.0f, 0.0f);cv::Point2f VALL3 = cv::Point2f(1.0f, 1.0f);cv::Point2f VFace30 = cv::Point2f(facelandmarks[30].x / width, facelandmarks[30].y / height);cv::Point2f VFace3 = cv::Point2f(facelandmarks[3].x / width, facelandmarks[3].y / height);cv::Point2f VFace4 = cv::Point2f(facelandmarks[4].x / width, facelandmarks[4].y / height);cv::Point2f VFace5 = cv::Point2f(facelandmarks[5].x / width, facelandmarks[5].y / height);cv::Point2f VFace6 = cv::Point2f(facelandmarks[6].x / width, facelandmarks[6].y / height);cv::Point2f VFace7 = cv::Point2f(facelandmarks[7].x / width, facelandmarks[7].y / height);cv::Point2f VFace8 = cv::Point2f(facelandmarks[8].x / width, facelandmarks[8].y / height);cv::Point2f VFace9 = cv::Point2f(facelandmarks[9].x / width, facelandmarks[9].y / height);cv::Point2f VFace10 = cv::Point2f(facelandmarks[10].x / width, facelandmarks[10].y / height);cv::Point2f VFace11 = cv::Point2f(facelandmarks[11].x / width, facelandmarks[11].y / height);cv::Point2f VFace12 = cv::Point2f(facelandmarks[12].x / width, facelandmarks[12].y / height);cv::Point2f VFace13 = cv::Point2f(facelandmarks[13].x / width, facelandmarks[13].y / height);float vertices[] = {//----位置----                       ---纹理---LALL0.x,    LALL0.y,    0.0f,       VALL0.x,    VALL0.y,LALL1.x,    LALL1.y,    0.0f,       VALL1.x,    VALL1.y,LALL2.x,    LALL2.y,    0.0f,       VALL2.x,    VALL2.y,LALL3.x,    LALL3.y,    0.0f,       VALL3.x,    VALL3.y,LFace30.x,  LFace30.y,  0.0f,       VFace30.x,  VFace30.y,LFace3.x, LFace3.y,   0.0f,       VFace3.x,   VFace3.y,LFace4.x,  LFace4.y,   0.0f,       VFace4.x,   VFace4.y,LFace5.x,  LFace5.y,   0.0f,       VFace5.x,   VFace5.y,LFace6.x,  LFace6.y,   0.0f,       VFace6.x,   VFace6.y,LFace7.x,  LFace7.y,   0.0f,       VFace7.x,   VFace7.y,LFace8.x,  LFace8.y,   0.0f,       VFace8.x,   VFace8.y,LFace9.x,  LFace9.y,   0.0f,       VFace9.x,   VFace9.y,LFace10.x, LFace10.y,  0.0f,       VFace10.x,  VFace10.y,LFace11.x,    LFace11.y,  0.0f,       VFace11.x,  VFace11.y,LFace12.x,    LFace12.y,  0.0f,       VFace12.x,  VFace12.y,LFace13.x,    LFace13.y,  0.0f,       VFace13.x,  VFace13.y};unsigned int indices[] = {0,1,5,5,1,4,4,1,2,2,4,15,15,2,3,0,5,6,0,6,7,0,7,8,0,8,9,0,9,10,0,10,3,3,10,11,3,11,12,3,12,13,3,13,14,3,14,15,4,5,6,4,6,7,4,7,8,4,8,9,4,9,10,4,10,11,4,11,12,4,12,13,4,13,14,4,14,15};

瘦脸变形

只需要将图中标记的点按照箭头方向拖动,即可实现瘦脸,为了不显得太过于尖锐,我们将范围包括到附近的几个点。

关于像素偏移调节,可以参考这篇文章

shader:

#version 330 core
precision mediump float;in vec2 TexCoord;
out vec4 outColor;
uniform sampler2D inputTexture;uniform float face5x;
uniform float face5y;vec2 stretchFun(vec2 textureCoord, vec2 originPosition, vec2 targetPosition, float radius,float curve)
{vec2 direction = targetPosition - originPosition;float infect = distance(textureCoord, originPosition)/radius;infect =1.0 -  pow(infect,curve);infect = clamp(infect,0.0,1.0);vec2 offset = direction * infect;vec2 result = textureCoord - offset;return result;
}void main(){vec2 A1 = vec2(face5x,face5y);vec2 A2 = vec2(face5x+0.02f,face5y + 0.01f);vec2 TexCoord2 = stretchFun(TexCoord,A1,A2,0.19f,2.0f);vec3 tmpColor = texture(inputTexture, TexCoord2).rgb;outColor = vec4(tmpColor,1.0f);
}

像素偏移后结果

去掉特征点后结果

完成

opengl 实现瘦脸等脸部微调相关推荐

  1. OpenGL ES 实现瘦脸大眼效果

    该原创文章首发于微信公众号:字节流动 旧文中我们用 OpenGL 给小姐姐实现了瘦身和大长腿效果,结果小姐姐眯着眼睛.嘟着嘴说,我需要瘦身和大长腿效果吗? 笔者若有所思地看着她的眼睛和脸庞,终于弄明白 ...

  2. matlab瘦脸大眼的代码,OpenGL ES 实现瘦脸大眼效果

    Hi 小姐姐,这是你要的大眼瘦脸效果? 该原创文章首发于微信公众号:字节流动 旧文中我们用 OpenGL 给小姐姐实现了瘦身和大长腿效果,结果小姐姐眯着眼睛.嘟着嘴说,我需要瘦身和大长腿效果吗? 笔者 ...

  3. Python实现PhotoShop人脸液化变形效果

    在PhotoShop中,我们经常利用液化工具的向前工具来对人脸进行形变处理,例如瘦脸.放大眼睛等常规P图操作. 瘦脸与眼睛放大可以算作图像局部扭曲算法的一个应用,其参考文献可以追溯至1993年的一篇博 ...

  4. android对图片提升清晰度,轻颜相机如何提升图片清晰度?

    大家都知道,轻颜相机是一款非常优秀的美颜相机软件,拥有时下最流行的滤镜和美颜效果,是众多爱美人士必不可少的美颜工具之一,拍照时支持脸部微调,后期就不用再P,功能十分强大.不过,最近有用户反映,拍出来的 ...

  5. 在OpenGL中利用shader进行实时瘦脸大眼等脸型微调

    在OpenGL中利用shader进行实时瘦脸大眼等脸型微调 在现在这个靠脸吃饭的时代,如果你没有一张瓜子脸一双大眼睛,那还怎么去吃饭呢,而现在一些直播视频App相机应用基本都会有瘦脸大眼效果.本文是在 ...

  6. OpenGL ES之实现“瘦脸大眼”效果

    一."瘦脸效果"的实现 瘦脸效果的实现,是将指定区域内的像素按照一定的规则进行整体偏移,从而形成一种对脸部挤压的效果: 如下所示,BC 表示偏移方向和偏移程度的向量,将圆内的所有像 ...

  7. 图像滤镜艺术---人脸编辑(五官微调+瘦脸美型)

    写本文的目的,实际上是对目前人脸美型这一块技术做个总结,跟大家 分享一下! 目前提到美颜算法,大家都会想到磨皮美白 /大眼瘦脸,实际上做好 美颜这件事情,关乎的不仅仅是这些,还有五官的协调比例等,今天 ...

  8. 人像瘦脸效果实现(网格液化)——OpenGL实现

    一.网格液化形变 1.液化     网格液化形变是指,事先将图片划分成若干个网格,再对其中某一些网格的坐标进行变换,以达到图像形变的效果.     网格可以是四边形,或三角形,在计算机图形当中用三角形 ...

  9. OpenGL Shader 自动瘦脸与眼睛放大

    图像局部扭曲算法有三个:局部缩放(Local Scaling)算法.局部平移(Local Transition)算法和局部旋转(Local Rotation)算法.其中应用局部缩放算法可实现眼睛放大, ...

最新文章

  1. java 清空一个list数据库_java – JPA EntityManager删除数据库中的所有记录
  2. 字节跳动简历冷却期_干货 | 字节跳动HR是如何挑选简历的?
  3. 手机号正则_这20个正则表达式,对你有大帮助,快来Make
  4. Android之 如何解决ScrollView 和ListView滑动冲突的问题如何解决ScrollView can host only one direct child
  5. 火狐查看html的隐藏域,IE/火狐/Chrome操作display:none对象所遇问题解答
  6. 来自IT公司速查手册的各大IT公司薪资和待遇内幕
  7. 计算机应用基础实操题怎么操,计算机基础实操试题
  8. python编程语言在线编译手机_groovy在线运行,groovy在线编译,支持手机在线编程写代码 - Groovy教程...
  9. sql查询重复订单号
  10. wifi的WPS功能
  11. Android集合之SparseArray、ArrayMap详解
  12. IDEA中写代码间距变大报红,报错Cannot resolve symbol
  13. PS打开时显示程序出错
  14. 聚类分析及R编程实现
  15. 我国最高山峰是珠穆朗玛峰:8848m,我现在有一张足够大的纸张,厚度为:0.01m。请问,我折叠多少次,就可 以保证厚度不低于珠穆朗玛峰的高度?
  16. Windows cmd 进入其他盘
  17. 评价星星三级样式:好、一般、差
  18. 国庆西北环游之旅(一大波照骗来袭)
  19. 003day (css文本、列表、背景相关属性,精灵图的制作)
  20. 瓦里安、勃林格殷格翰将参展第四届进博会;森世海亚集团中国区总部落地上海 | 医药健闻...

热门文章

  1. “玩伴女郎”误入学术圈--lena图象的使用数字图像历史上最重要的事件之一
  2. python画漫画_用Python抓腾讯漫画?
  3. python模拟微信发红包算法_微信红包的随机算法是怎样实现的?
  4. XDOJ-车牌限行_分支结构-7
  5. UGNX Imachining VoluMill动态与高速铣视频教程
  6. 捂碳星球|换季整理衣橱,衣服该怎么存放和处理?
  7. 分布式事务--TCC--流程/原理
  8. 抖音小店无货源店群,我走过最长的路,就是同行的套路!
  9. Android studio 连接Mysql数据库
  10. 【线性代数(13)】矩阵的特征值与特征向量含义及性质