710官方网站做了一个基于GPUImage的实时美颜滤镜,做了八个遵照GPUImage的实时美颜滤镜

1.背景

    
前段时间由于品种供给,做了一个依据GPUImage的实时美颜滤镜。将来形形色色的直播、录像App熟视无睹,美颜滤镜的必要也更为多。为了回馈开源,未来本人把它内置了GitHub 上面,感兴趣的意中人能够去下载。上边将主要介绍落成美颜滤镜的法则和思路。

1.背景

其余一款直播软件都不能够不举行美颜,不然哪来的那么多美丽的女生,所以技术转移世界,不只是说说而已。美颜在采访的时候就得就行,让主播实时看到直播的效益。

2.GPUImage

    
GPUImage
是三个开源的基于GPU的图纸或录像的处理框架,其自个儿内置了多达120种种普遍的滤镜效果。有了它,添加实时的滤镜只需求简单地加上几行代码。上面的例子是以录制头的数目为源,对实际时地进行反色的操作(类似相片底片的效果):

运用GPUImage对摄像头数量添加滤镜的以身作则2.1

   
其实美颜也是千篇一律,若是有诸如此类一个美颜的滤镜(姑且叫做GPUImageBeautifyFilter),那么只需求把示例2.第11中学的GPUImageColorInvertFilter替换到GPUImageBeautifyFilter即可。大家只须求做一个GPUImageBeautifyFilter就能兑现实时美颜了,难点来了,到底什么样算是美颜呢?作者的通晓是,我们对此美颜相比较常见的急需正是磨皮、美白。当然升高饱和度、提亮之类的就遵照供给而定。本文将第②介绍磨皮的贯彻(实际上GPUImageBeautifyFilter也落到实处了美白、提亮等作用)。

前段时间由于品种供给,做了3个依照GPUImage的实时美颜滤镜。未来见惯不惊的直播、录制App层见迭出,美颜滤镜的要求也越多。为了回馈开源,今后小编把它内置了GitHub上面,感兴趣的恋人能够去下载。上面将注重介绍落成美颜滤镜的规律和思路。

1.美颜规律

事实上美颜的真面目正是美白和磨皮,分别通过提升亮度和混淆像素点举办。我们一般用GPUImage那几个开源的图像处理库来完毕。摄像的精神就是一张张再而三的图形,磨皮便是对于图片上的像素点的取值与普遍的像素点取值相关联。常见的有高斯模糊和两边滤波(Bilateral
Filter)。
  高斯模糊是最普遍的一种模糊方式,像素点取值是由广泛像素点求加权平均所得,而权重全面则是像素间的距离的高斯函数,大约关系是偏离越小、权重周密越大。高斯模糊会导致边缘不明晰。
  双方滤波是有针对点的模糊像素点,能担保边缘不被混为一谈。

3.磨皮

    
磨皮的泰山真面目实际上是指鹿为马。而在图像处理领域,模糊便是将像素点的取值与大规模的像素点取值相关联。而小编辈广大的高斯模糊 ,它的像素点取值则是由广泛像素点求加权平均所得,而权重全面则是像素间的距离的高斯函数,大概关系是偏离越小、权重周全越大。下图3.1是高斯模糊效果的演示:

高斯模糊效果示例3.1

   
如果仅仅使用高斯模糊来磨皮,获得的作用是不满的。原因在于,高斯模糊只考虑了像素间的偏离关系,没有考虑到像素值自己之间的反差。举个例子来讲,头发与人脸分界处(颜色差距非常的大,浅灰与人肌肤的水彩),假设采纳高斯模糊则那几个边缘也会搅乱掉,那眼看不是我们目的在于看到的。而双方滤波(Bilateral
Filter)
 则考虑到了颜色的差异,它的像素点取值也是常见像素点的加权平均,而且权重也是高斯函数。不一样的是,这么些权重不仅与像素间距离有关,还与像素值本人的异样有关,具体讲是,像素值差别越小,权重越大,也是以此特点让它富有了维系边缘的天性,因而它是3个很好的磨皮工具。下图3.2是二者滤波的效劳示例:

互相滤波效果示例3.2

    
比较3.1和3.2,双边滤波效果实在在人脸细节部分保留得更好,由此小编动用了双方滤波作为磨皮的基础算法。双边滤波在GPUImage中也有得以实现,是GPUImageBilateralFilter。

   
依据图3.2,能够观察图中仍有一部分人脸的细节爱抚得不够,还有我们并不愿意将人的头发也搅乱掉(大家只需求对皮肤进行拍卖)。由此拉开出来的千锤百炼思路是整合双方滤波,边缘检查和测试以及肤色检查和测试。全体逻辑如下:

磨皮处理逻辑图3.3

     Combination 
Filter是我们友好定义的三输入的滤波器。多少个输入分别是原图像A(x,
y),双边滤波后的图像B(x, y),边缘图像C(x,
y)。当中A,B,C能够当做是图像矩阵,(x,y)能够当作个中某一像素的坐标。Combination 
Filter的拍卖逻辑如下图:

Combination Filter逻辑图3.3

     上面是关键的shader代码:

combination filter的shader代码3.4

     Combination
Filter通过肤色检查和测试和边缘检查和测试,只对肌肤和非边缘部分举行拍卖。上边是运用这种方法举办磨皮之后的意义图:

末尾磨皮效果图3.5

    
相比较3.5与3.2,能够看来3.5对人脸细节的保障更好,同时对于面部磨皮效果也很好,给人备感更是真实。

2.GPUImage

2.GPUImage介绍

  GPUImage
是三个开源的依据GPU的图形或录像的处理框架,其自己内置了多达120各类常见的滤镜效果。有了它,添加实时的滤镜只必要简单地增加几行代码,相当有力。想研商源码的校友上,能够去GitHub上下载。

4.延伸

    
小编所利用的磨皮算法是基于双方滤波的,主借使考虑到它同时结合了像素间空间距离以及像素值本人的不一致。当然也不自然要选拔双边滤波,也有通过革新高斯模糊(结合像素值差别)来兑现磨皮的,甚至能收获更好的效劳。别的GPUImageBeautifyFilter不仅仅具有磨皮功效,也落到实处了log曲线调色,亮度、饱和度的调整,具体详情能够参见demo 。

   

GPUImage是四个开源的基于GPU的图片或录像的处理框架,其自小编内置了多达120各样常见的滤镜效果。有了它,添加实时的滤镜只必要不难地加上几行代码。下边包车型大巴例证是以摄像头的数额为源,对实在时地举行反色的操作(类似相片底片的意义):

3.效果

710官方网站 1

UI.png

&esmp;&esmp;请见谅那篇唯有UI效果图。用多少个Slider来决定磨皮和美白的作用,从上到下取值范围分别为[-1,1]
[0,100];

710官方网站 2

4.GPUImage使用办法

1.用CocoaPods集成到品种中。

pod 'GPUImage', '~> 0.1.7'

2.代码演示

#import "FHUImageFilterViewController.h"
#import <GPUImage/GPUImage.h>

@interface FHUImageFilterViewController ()

// 视频源
@property (nonatomic, strong)GPUImageVideoCamera *videoCamera;
// 磨皮滤镜
@property (nonatomic, weak)GPUImageBilateralFilter *bilateralFilter;
// 美白滤镜
@property (nonatomic, weak)GPUImageBrightnessFilter *brightnessFilter;
@end

@implementation FHUImageFilterViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 创建视屏源
      /*
     * sessionPreset : 屏幕分辨率
     * cameraPosition: 摄像头位置
     **/
    GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:AVCaptureDevicePositionFront];
    // 设置输出图像方向
    videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
    self.videoCamera = videoCamera;

    // 创建最终预览View
    GPUImageView *captureVideoPreview = [[GPUImageView alloc] initWithFrame:self.view.bounds];
    captureVideoPreview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view insertSubview:captureVideoPreview atIndex:0];

    // 创建滤镜:磨皮,美白,组合滤镜
    GPUImageFilterGroup *groupFilter = [[GPUImageFilterGroup alloc] init];

    // 磨皮滤镜
    GPUImageBilateralFilter *bilateraFilter = [[GPUImageBilateralFilter alloc] init];
    [groupFilter addTarget:bilateraFilter];
    _bilateralFilter = bilateraFilter;

    // 美白滤镜
    GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
    [groupFilter addTarget:brightnessFilter];
    _brightnessFilter = brightnessFilter;

    // 设置滤镜组链
    [bilateraFilter addTarget:brightnessFilter];
    [groupFilter setInitialFilters:@[bilateraFilter]];
    groupFilter.terminalFilter = brightnessFilter;

    // 设置GPUImage的响应链, 从数据源 ==> 滤镜 ==> 最终界面效果
    [videoCamera addTarget:groupFilter];
    [groupFilter addTarget:captureVideoPreview];

    // 必须采用startCameraCapture, 底层才会把采集到的视频源,渲染到GPUImageView中,就能显示了。
    [videoCamera startCameraCapture];
}

备注:手提式无线电话机分辨率(sessionPreset)有13个值可选,但最好设置成AVCaptureSessionPresetHigh,手提式有线电电话机会自动识别。假诺设置的太高,手提式有线电话机不扶助,会直接报错。

- (IBAction)brightnessFiller:(id)sender {
    UISlider *slider = (UISlider *)sender;
    // 亮度(brightness)
    _brightnessFilter.brightness = slider.value;
}
- (IBAction)bilateralFilter:(id)sender {
    UISlider *slider = (UISlider *)sender;
    CGFloat maxValue = 100;
    //平滑因子(distanceNormalizationFactor)
    _bilateralFilter.distanceNormalizationFactor = maxValue - slider.value;
    NSLog(@"distanceNormalizationFactor=%f",_bilateralFilter.distanceNormalizationFactor);
}

备注:(1)亮度(brightness)取值范围[-1,1],0为平常状态,私下认可。
(2)平滑因子(distanceNormalizationFactor)值越小,磨皮效果越好,暗中认可为8。小编为了演示效果,把最大值设置成100,这样大致就没有磨皮效果了,平常极端10以内。最好大于0,否则就会变形。

选用GPUImage对录制头数量添加滤镜的以身作则2.1

5.自定义滤镜

一旦你觉得GPUImage自带的滤镜不够用的话,也得以自定义滤镜,使用情势和地点的大都。笔者以3个别人写的美颜滤镜为例。
1.demo下载地址。把GPUImageBeautifyFilter文件夹导入你的工程中。
2.代码演示

#import "FHBeautyViewController.h"
#import "GPUImageBeautifyFilter.h"
#import <GPUImage/GPUImage.h>

@interface FHBeautyViewController ()
//视频源一定要强引用
@property(nonatomic,strong) GPUImageVideoCamera *videoCamera;

@end

@implementation FHBeautyViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 创建视频源
    _videoCamera  = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:AVCaptureDevicePositionFront];
    _videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;

    // 创建美颜滤镜
    GPUImageBeautifyFilter *beautifyFilter = [[GPUImageBeautifyFilter alloc] init];

    // 创建最终预览View
    GPUImageView *captureVideoPreview = [[GPUImageView alloc] initWithFrame:self.view.bounds];
    captureVideoPreview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view insertSubview:captureVideoPreview atIndex:0];

    // 设置GPUImage处理链,从数据源 => 滤镜 => 最终界面效果
    [_videoCamera addTarget:beautifyFilter];
    [beautifyFilter addTarget:captureVideoPreview];

    // 开始采集视屏
    [_videoCamera startCameraCapture];

}

实际美颜也是均等,假诺有那般1个美颜的滤镜(姑且叫做GPUImageBeautifyFilter),那么只必要把示例2.1中的GPUImageColorInvertFilter替换成GPUImageBeautifyFilter即可。大家只供给做二个GPUImageBeautifyFilter就能落到实处实时美颜了,难点来了,到底如何算是美颜呢?作者的驾驭是,大家对于美颜相比较宽泛的必要正是磨皮、美白。当然升高饱和度、提亮之类的就依据需求而定。本文将注重介绍磨皮的达成(实际上GPUImageBeautifyFilter也达成了美白、提亮等职能)。

6.demo下载

demo下载地址。下载下来运维,发现报错。

710官方网站 3

报错.png

那是因为小编没有在工程里上传ijkplayer视屏直播框架,作者能上传上去,但下载太慢了,什么来头大家都知道。笔者把ijkplayer视屏直播框架放到百度云上了,没有密码,下载下来之后,放到LiveApp德姆o-master文件夹里,重新打开就能够运转了。

710官方网站 4

文件夹.png

3.磨皮

磨皮的真相实际上是歪曲。而在图像处理领域,模糊便是将像素点的取值与广大的像素点取值相关联。而大家普遍的高斯模糊,它的像素点取值则是由广泛像素点求加权平均所得,而权重周详则是像素间的相距的高斯函数,大概关系是距离越小、权重全面越大。下图3.1是高斯模糊效果的言传身教:

710官方网站 5

高斯模糊效果示例3.1

只要只是使用高斯模糊来磨皮,获得的作用是遗憾的。原因在于,高斯模糊只考虑了像素间的相距关系,没有设想到像素值自个儿之间的差别。举个例子来讲,头发与人脸分界处(颜色差距不小,天灰与人肌肤的水彩),假使采用高斯模糊则这些边缘也会搅乱掉,这明显不是大家盼望见到的。而相互滤波(Bilateral
Filter)
则设想到了颜色的出入,它的像素点取值也是普遍像素点的加权平均,而且权重也是高斯函数。差别的是,那几个权重不仅与像素间距离有关,还与像素值本身的歧异有关,具体讲是,像素值差别越小,权重越大,也是那脾特性让它兼具了维持边缘的表征,因而它是三个很好的磨皮工具。下图3.2是两者滤波的功效示例:

710官方网站 6

二者滤波效果示例3.2

对照3.1和3.2,双边滤波效果的确在人脸细节部分保留得更好,因而作者使用了双方滤波作为磨皮的功底算法。双边滤波在GPUImage中也有落到实处,是GPUImageBilateralFilter。

基于图3.2,能够看出图中仍有部分人脸的底细珍视得不够,还有大家并不期望将人的头发也搅乱掉(大家只必要对肌肤进行拍卖)。因此拉开出来的修正思路是整合双方滤波,边缘检查和测试以及肤色检查和测试。全体逻辑如下:

710官方网站 7

磨皮处理逻辑图3.3

Combination 
Filter是大家和好定义的三输入的滤波器。两个输入分别是原图像A(x,
y),双边滤波后的图像B(x, y),边缘图像C(x,
y)。个中A,B,C能够看作是图像矩阵,(x,y)能够看作个中某一像素的坐标。Combination 
Filter的处理逻辑如下图:

710官方网站 8

Combination Filter逻辑图3.3

下边是首要的shader代码:

710官方网站 9

combination filter的shader代码3.4

Combination
Filter通过肤色检查和测试和边缘检测,只对肌肤和非边缘部分进行拍卖。上面是利用那种措施实行磨皮之后的功力图:

710官方网站 10

说到底磨皮效果图3.5

相对而言3.5与3.2,可以看出3.5对人脸细节的珍惜更好,同时对于面部磨皮效果也很好,给人感觉到越是真实。

4.延伸

自小编所利用的磨皮算法是依照双方滤波的,主即便考虑到它同时组成了像素间空间距离以及像素值本人的差别。当然也不自然要利用双边滤波,也有经过核查高斯模糊(结合像素值差距)来贯彻磨皮的,甚至能得到更好的功用。其余GPUImageBeautifyFilter不仅仅具有磨皮效用,也落到实处了log曲线调色,亮度、饱和度的调整,具体详情能够瞻仰demo

文/琨君(简书俺)

初稿链接:http://www.jianshu.com/p/945fc806a9b4

相关文章