大白话磨皮美颜原理

大白话磨皮美颜原理

在这里插入图片描述
谈到磨皮美颜,大家可能认为是一个很高深难懂的事情,网上搜索关于美颜的文章,一般都是搬出许多算法,看得让你头晕目眩的。本篇文章将用大白话来让你快速认识磨皮美颜原理,轻松get到她的点!只要你耐着性子读完本篇文章,你会发现美颜原理其实也是一件很好理解的事情

磨皮美颜概念


认清目的


讲磨皮美颜之前,先讲讲我们的人脸,认清磨皮美颜的目的;通常,我们的人脸上或许有许多痘痘和一些暗色粗糙皮肤,美颜的目的就是尽可能使痘痘消失,暗色皮肤变白,使粗糙变细腻,达到美颜效果,从上诉的分析可以得出我们需要做的事情如下:

  1. 寻找脸上的特征点,如痘痘、暗色粗糙皮肤
  2. 对痘痘、粗糙皮肤加以处理,完成美化

特征点分析


我们通常看到痘痘和暗色皮肤,仔细观察,会发现这些特征点和周围正常皮肤在肤色上有一个差别;如果拍照拍下来,用灰度值查看这个图片,你会发现特征点灰度值较低,而正常白色皮肤灰度值较高,这是一个凸变的过程,正常皮肤到特征点,灰度值从高点陡然下跌;我们可以用这个现象来把特征点提取出来,如何提取请继续往下看;

另一个是局部粗糙皮肤,其局部灰度值,也需要尽可能将其数字磨平,让它和正常皮肤一样,和上面痘痘一样,也会有一个灰度值陡然下降的过程

特征点提取


这里需要一种滤波算法,可以是均值化滤波、高斯滤波、双边滤波和导向滤波等算法,考虑到手机CPU性能,我们一般选择高斯滤波,加权求平均的算法;试想一下,一张二维灰度值人脸图片,特征点灰度值低,正常皮肤灰度值高,滤波算法过后,正常皮肤变化不大,特征点因为周围正常皮肤灰度值较高的原因,普遍灰度值会有一个变大的效果,这个时候我们用原图灰度值减去滤波后的灰度值,那么特征点的灰度值是小于0位负的,正常皮肤灰度值为正的,这样我们就得到整张人脸图片的特征点了

= 特征点 = 原图 - 滤波后的图

我们归一化灰度值,也就是将灰度值0-255归一化为0-1的取值,按照上面的步骤,得到特征点后,给他统一加0.5,也就是

= + 0.5 特征点 = 原图 - 滤波后的图 + 0.5

这样,我们的特征点小于0.5,正常皮肤的是大于0.5的

特征点加强

为了使我们的特征点更明显,我们对特征点加强,主要是使特征更加明显,后续好处理;得到一个高度反差的图像,如下图:
在这里插入图片描述
如上图,手上有皱纹以及关节处黑色比较明显,得到了特征点加强图片

源码:

float features = primaryColor - filterColor + 0.5;
for(int i = 0; i < 5; i++){
	strength(features);
}

float strength(int color){
	if(color <= 0.5)
        color = color * color * 2.0;
    else
        color = 1.0 - ((1.0 - color)*(1.0 - color) * 2.0);
    return color;
}

注意: 滤波越细腻,磨皮效果越好

特征点处理


经过上一步,特征点已经处理了,那特征点如何处理了,处理的原则又是什么呢?
那就是对特征点亮化处理,增加其灰度值大小,使其尽可能比原色更白,和正常肤色一样,那如何才能达成这一效果?
请看以下算法:

//点积 luminance为原图计算后的灰度值
float luminance = dot(primaryColor, W);
//luminance的params次冪 第二个参数越小,alpha越小,后一步原图与高反差的减后值越大,加上原图后值更大,亮度更好,也就是美颜越好
float alpha = pow(luminance, 0.1);
//原图减去高反差higPass,高反差小于0.5的变得更小,原图减去更小的黑色高反差,会是正值,保留的是正值加上原图,黑色像素部分能量更大,如痘印黑色皮肤,能量大显示就偏白,美白效果
//而大于0.5的白色,高反差highPass更大,原图减去后则是负值,原图加负值则能量变小,白色就偏暗
vec3 smoothColor = primaryColor + (primaryColor-vec3(features))*alpha*0.1;

算法解释都在代码注释里面了,主要还是看第三句代码:

primaryColor-vec3(features):
原图减去特征点,暗色的特征点很小,减法后值更大;正常皮肤特征点大,减法后值越小;最后在加上原图,原图特征点值变大了,就会显得亮度更亮,实现了我们要的效果

细节补偿


进过上面的图像处理时,会有一定的图像细节丢失,我们需要将原始图像和处理图像融合进行细节补偿,达到细节补偿效果;

gl_FragColor = vec4(mix(smoothColor.rgb, max(smoothColor, primaryColor), alpha), 1.0);

先用max选择亮度较高的灰度值,最后在与处理图融合;
这里为什么要用max函数来处理一遍呢,因为在特征点处理步骤,正常图片做减法后的加法,其灰度值可能比原图更低,所以这里这么处理,最后我们得到的图片效果;

在这里插入图片描述

美颜扩展

以上就是磨皮美颜的常规处理,最终效果上看确实达到了美颜的效果;

美颜不仅仅是美肤,还有瘦脸、大眼睛等,这些才是美颜的进阶!

更多精彩博文,微信看下图!

在这里插入图片描述

发布了148 篇原创文章 · 获赞 41 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/jackzhouyu/article/details/103678687