iOS 基于GPUImage的实时美颜滤镜

5,255 阅读2分钟

前言

目前是准备做一个美颜相机类的项目,这篇将介绍美颜滤镜的一些思路。 代码已上传MagicCamera,你的star和fork是对我最好的支持和动力。

实现

流程图

GPUImage

GPUImage 是一个开源的基于GPU的图片或视频的处理框架,在这基础上我们可以很方便的实现各种滤镜效果。本文的主要实现继承自GPUImageThreeInputFilter的三输入:双边滤波、边缘检测、原图

     // 双边滤波
     highp vec4 bilateral = texture2D(inputImageTexture, textureCoordinate);
     // 边缘检测
     highp vec4 canny = texture2D(inputImageTexture2, textureCoordinate2);
     // 原图
     highp vec4 source = texture2D(inputImageTexture3,textureCoordinate3);

双边滤波:在高斯模糊的基础上加了梯度分量来组成权重信息实现模糊平滑图像,具有保留边缘的功能。同样也可以采用高斯滤波。

高反差保留算法

通过高反差来得到皮肤细节的MASK,根据MASK中细节区域,比如皮肤中的斑点区域位置,将原图对应区域进行颜色减淡处理,以此来达到斑点弱化,美肤的目的,使得皮肤看起来比较光滑自然。 公式 = 原图 - 高斯模糊图,注:用双边代替高斯避免多一个输入源

高反差保留算法

//高反差保留算法 (原图 - 高斯模糊图 注:双边代替高斯)
highp vec4 highPass = source - bilateral;

经过高反差以后,图像比较暗淡,这里进行一个强光操作

// 强光处理 color = 2 * color1 * color2
mediump float intensity = 24.0;   // 强光程度
highPass.r = clamp(2.0 * highPass.r * highPass.r * intensity,0.0,1.0);
highPass.g = clamp(2.0 * highPass.g * highPass.g * intensity,0.0,1.0);
highPass.b = clamp(2.0 * highPass.b * highPass.b * intensity,0.0,1.0);

融合

// 融合 -> 磨皮
// 蓝色通道
mediump float value = clamp((min(source.b, bilateral.b) - 0.2) * 5.0, 0.0, 1.0);
// RGB 的最大值
mediump float maxChannelColor = max(max(highPass.r, highPass.g), highPass.b);
// 磨皮程度
mediump float currentIntensity = (1.0 - maxChannelColor / (maxChannelColor + 0.2)) * value * buffingDegree;
// 混合
// mix = x⋅(1−a)+y⋅a
highp vec4 fuse = vec4(mix(source.rgb,bilateral.rgb,currentIntensity), 1.0);

肤色检测

//精准磨皮 肤色
lowp float r = source.r;
lowp float g = source.g;
lowp float b = source.b;

highp vec4 result;

if (canny.r < 0.2 && r > 0.3725 && g > 0.1568 && b > 0.0784 && r > b && (max(max(r, g), b) - min(min(r, g), b)) > 0.0588 && abs(r-g) > 0.0588) {
 result = fuse;
} else {
 result = source;
}

细节调整

最后加上USM锐化、HSB增强边沿细节、色调、饱和度、亮度等。

效果图

参考

blog.csdn.net/Trent1985/a…

www.jianshu.com/p/945fc806a…

www.jianshu.com/p/5f860f14f…