GPUImageBeautifyFilter.h文件中

#import <GPUImage/GPUImage.h>
@class GPUImageCombinationFilter;
@interface GPUImageBeautifyFilter : GPUImageFilterGroup //继承于图像滤镜组{GPUImageBilateralFilter *bilateralFilter; //双边模糊(磨皮)滤镜--继承于高斯模糊滤镜GPUImageGaussianBlurFilterGPUImageCannyEdgeDetectionFilter *cannyEdgeFilter;//Canny边缘检测算法滤镜--继承于图像滤镜组GPUImageFilterGroupGPUImageHSBFilter *hsbFilter;//HSB颜色滤镜--继承于颜色矩阵滤镜GPUImageColorMatrixFilterGPUImageCombinationFilter *combinationFilter;//滤镜的组合---继承于三输入滤镜GPUImageThreeInputFilter
}@end
复制代码

GPUImageBeautifyFilter.m文件中

#import "GPUImageBeautifyFilter.h"
/***************************************************/
// Internal CombinationFilter(It should not be used outside)
@interface GPUImageCombinationFilter : GPUImageThreeInputFilter//继承于三输入的滤镜
{GLint smoothDegreeUniform;//全局磨皮参数(平滑程度)
}@property (nonatomic, assign) CGFloat intensity;@end/***********************************************/
//自定义的Shader着色器代码
//Shader出现在OpenGL ES 2.0中,允许创建自己的Shader。必须同时创建两个Shader,分别是Vertex shader(顶点着色器)和Fragment shader(片段着色器).http://www.jianshu.com/p/8687a040eb48//Varyings:用来在Vertex shader和Fragment shader之间传递信息的,比如在Vertex shader中写入varying值,然后就可以在Fragment shader中读取和处理
//Uniforms:在渲染循环里作为不变的输入值
//vec2:两个浮点数,适合在Fragment shader中保存X和Y坐标的情况
//vec4:四个浮点数,在图像处理中持续追踪每个像素的R,G,V,A这四个值。
//highp:属性负责变量精度,这个被加入可以提高效率
//smpler2D:接收一个图片的引用,当做2D的纹理。//根据这个字符串创建Shader
NSString *const kGPUImageBeautifyFragmentShaderString = SHADER_STRING
(varying highp vec2 textureCoordinate;//纹理坐标1varying highp vec2 textureCoordinate2;//纹理坐标2varying highp vec2 textureCoordinate3;//纹理坐标3uniform sampler2D inputImageTexture;//输入图像纹理1uniform sampler2D inputImageTexture2;//输入图像纹理2uniform sampler2D inputImageTexture3;//输入图像纹理3uniform mediump float smoothDegree;//平滑度void main(){highp vec4 bilateral = texture2D(inputImageTexture, textureCoordinate);//双边模糊的2D纹理highp vec4 canny = texture2D(inputImageTexture2, textureCoordinate2);//边缘检测的2D纹理highp vec4 origin = texture2D(inputImageTexture3,textureCoordinate3);//原始图像的2D纹理highp vec4 smooth;lowp float r = origin.r;lowp float g = origin.g;lowp float b = origin.b;//判断是不是边缘,是不是皮肤.通过肤色检测和边缘检测,只对皮肤和非边缘部分进行处理。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) {smooth = (1.0 - smoothDegree) * (origin - bilateral) + bilateral;}else {smooth = origin;}smooth.r = log(1.0 + 0.2 * smooth.r)/log(1.2);smooth.g = log(1.0 + 0.2 * smooth.g)/log(1.2);smooth.b = log(1.0 + 0.2 * smooth.b)/log(1.2);gl_FragColor = smooth;});
/******************************************/@implementation GPUImageCombinationFilter //组合滤镜
//Combination  Filter是我们自己定义的三输入的滤波器。三个输入分别是原图像A(x, y),双边滤波后的图像B(x, y),边缘图像C(x, y)。其中A,B,C可以看成是图像矩阵,(x,y)可以看成其中某一像素的坐标。- (id)init {//Combination Filter根据kGPUImageBeautifyFragmentShaderString创建自定义的Shader.//在自定义的Shader中对三个输入进行处理(双边模糊的2D纹理,边缘检测的2D纹理,原始图像的2D纹理),见上面Shader代码if (self = [super initWithFragmentShaderFromString:kGPUImageBeautifyFragmentShaderString]) {smoothDegreeUniform = [filterProgram uniformIndex:@"smoothDegree"];}self.intensity = 0.5;return self;
}- (void)setIntensity:(CGFloat)intensity {_intensity = intensity;[self setFloat:intensity forUniform:smoothDegreeUniform program:filterProgram];
}@end@implementation GPUImageBeautifyFilter//美颜滤镜
-(instancetype)init {if (!(self = [super init])) {return nil;}//1.双边模糊bilateralFilter = [[GPUImageBilateralFilter alloc] init];bilateralFilter.distanceNormalizationFactor = 4.0;[self addFilter:bilateralFilter];//2.边缘探测cannyEdgeFilter = [[GPUImageCannyEdgeDetectionFilter alloc] init];[self addFilter:cannyEdgeFilter];//3.合并combinationFilter = [[GPUImageCombinationFilter alloc] init];[self addFilter:combinationFilter];//4.调整HSBhsbFilter = [[GPUImageHSBFilter alloc] init];[hsbFilter adjustBrightness:1.1];//亮度[hsbFilter adjustSaturation:1.1];//饱和度//双边模糊完成后,输出到组合滤镜[bilateralFilter addTarget:combinationFilter];//边缘探测完成后,输出到组合滤镜[cannyEdgeFilter addTarget:combinationFilter];//组合滤镜处理完成后,输出到hsb滤镜[combinationFilter addTarget:hsbFilter];//初始滤镜组self.initialFilters = [NSArray arrayWithObjects:bilateralFilter,cannyEdgeFilter,combinationFilter, nil];//最终处理的滤镜self.terminalFilter = hsbFilter;return self;
}
#pragma mark GPUImageInput protocol-(void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex {for (GPUImageOutput<GPUImageInput> *currentFilter in self.initialFilters) {if (currentFilter != self.inputFilterToIgnoreForUpdates) {if (currentFilter == combinationFilter) {textureIndex = 2;}[currentFilter newFrameReadyAtTime:frameTime atIndex:textureIndex];}}
}
-(void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex {for (GPUImageOutput<GPUImageInput> *currentFilter in self.initialFilters) {if (currentFilter != self.inputFilterToIgnoreForUpdates) {if (currentFilter == combinationFilter) {textureIndex = 2;}[currentFilter setInputFramebuffer:newInputFramebuffer atIndex:textureIndex];}}
}
@end/*1、GPUImageVideoCamera捕获摄像头图像调用newFrameReadyAtTime: atIndex:通知GPUImageBeautifyFilter;2、GPUImageBeautifyFilter调用newFrameReadyAtTime: atIndex:通知GPUImageBilateralFliter输入纹理已经准备好;3、GPUImageBilateralFliter 绘制图像后在informTargetsAboutNewFrameAtTime(),调用setInputFramebufferForTarget: atIndex:把绘制的图像设置为GPUImageCombinationFilter输入纹理,并通知GPUImageCombinationFilter纹理已经绘制完毕;4、GPUImageBeautifyFilter调用newFrameReadyAtTime: atIndex:通知 GPUImageCannyEdgeDetectionFilter输入纹理已经准备好;5、同3,GPUImageCannyEdgeDetectionFilter 绘制图像后,把图像设置为GPUImageCombinationFilter输入纹理;6、GPUImageBeautifyFilter调用newFrameReadyAtTime: atIndex:通知 GPUImageCombinationFilter输入纹理已经准备好;7、GPUImageCombinationFilter判断是否有三个纹理,三个纹理都已经准备好后调用GPUImageThreeInputFilter的绘制函数renderToTextureWithVertices: textureCoordinates:,图像绘制完后,把图像设置为GPUImageHSBFilter的输入纹理,通知GPUImageHSBFilter纹理已经绘制完毕;8、GPUImageHSBFilter调用renderToTextureWithVertices: textureCoordinates:绘制图像,完成后把图像设置为GPUImageView的输入纹理,并通知GPUImageView输入纹理已经绘制完毕;9、GPUImageView把输入纹理绘制到自己的帧缓存,然后通过[self.context presentRenderbuffer:GL_RENDERBUFFER];显示到UIView上。
*/
复制代码

如何使用这个美颜工具类? 在自己的控制器中ViewController.m

#import "ViewController.h"
#import <GPUImage/GPUImage.h>
#import "GPUImageBeautifyFilter.h"
#import <Masonry/Masonry.h>@interface ViewController ()
@property (strong, nonatomic) GPUImageVideoCamera *videoCamera;//视频相机对象
@property (strong, nonatomic) GPUImageView *filterView;//实时预览的view,GPUImageView是响应链的终点,一般用于显示GPUImage的图像。
@property (weak, nonatomic) UIButton *beautifyButton;
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.//相机self.videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionFront];self.videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;self.videoCamera.horizontallyMirrorRearFacingCamera = YES;//预览层self.filterView = [[GPUImageView alloc] initWithFrame:self.view.frame];self.filterView.center = self.view.center;[self.view addSubview:self.filterView];//添加滤镜到相机[self.videoCamera addTarget:self.filterView];[self.videoCamera startCameraCapture];//设置按钮UIButton *beautifyBtn = [UIButton buttonWithType:UIButtonTypeCustom];self.beautifyButton = beautifyBtn;[self.view addSubview:beautifyBtn];self.beautifyButton.backgroundColor = [UIColor whiteColor];[self.beautifyButton setTitle:@"开启" forState:UIControlStateNormal];[self.beautifyButton setTitle:@"关闭" forState:UIControlStateSelected];[self.beautifyButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];[self.beautifyButton addTarget:self action:@selector(beautify) forControlEvents:UIControlEventTouchUpInside];beautifyBtn.frame = CGRectMake(100, 20, 100, 40);
}
- (void)beautify {if (self.beautifyButton.selected) {//如果已经开启了美颜,则self.beautifyButton.selected = NO;[self.videoCamera removeAllTargets];//移除原有的[self.videoCamera addTarget:self.filterView];//添加普通预览层} else {//如果没有开启美颜self.beautifyButton.selected = YES;[self.videoCamera removeAllTargets];//移除原有的GPUImageBeautifyFilter *beautifyFilter = [[GPUImageBeautifyFilter alloc] init];[self.videoCamera addTarget:beautifyFilter];//添加美颜滤镜层[beautifyFilter addTarget:self.filterView];//美颜后再输出到预览层}
}
- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.
}@end
复制代码

项目代码github.com/XanderXu/Be…

基于GPUImage的美颜BeautifyFace详细注释相关推荐

  1. Python实现鸢尾花数据集分类问题——基于skearn的SVM(有详细注释的)

    Python实现鸢尾花数据集分类问题--基于skearn的SVM 代码如下: 1 # !/usr/bin/env python2 # encoding: utf-83 __author__ = 'Xi ...

  2. 基于GPUImage的多滤镜rtmp直播推流

    之前做过开源videocore的推流改进:1)加入了美颜滤镜; 2) 加入了librtmp替换原来过于简单的rtmpclient: 后来听朋友说,在videocore上面进行opengl修改,加入新的 ...

  3. createsamples.cpp中生成vec文件的实现及详细注释、图解——人脸识别的尝试系列(三)

    在我们开始训练我们的Haar分类器之前,首先要对样本进行处理. 人脸识别的尝试系列(一)中:http://blog.csdn.net/u011583927/article/details/446274 ...

  4. 数学建模常用算法:启发式优化算法合辑(内含多种智能优化算法,使用java实现算法、详细注释、并进行结果可视化)

    一.启发式算法介绍   启发式算法(heuristic algorithm)是相对于最优化算法提出的.一个问题的最优算法求得该问题每个实例的最优解.启发式算法可以这样定义:一个基于直观或经验构造的算法 ...

  5. SENet代码复现+超详细注释(PyTorch)

    在卷积网络中通道注意力经常用到SENet模块,来增强网络模型在通道权重的选择能力,进而提点.关于SENet的原理和具体细节,我们在上一篇已经详细的介绍了:经典神经网络论文超详细解读(七)--SENet ...

  6. 使用Python编写爬虫程序(代码详细注释),获取彼岸图网的图片

    文章目录 一.要求 二.设计 1.彼岸网站URL规则 2.程序流程图 三.代码(详细注释) 四.所遇到过的问题 一.要求 1.抓取目标 彼岸图网(http://pic.netbian.com)上的4K ...

  7. Nids.h详细注释

    Nids.h详细注释 #ifndef _NIDS_NIDS_H #define _NIDS_NIDS_H #define NIDS_MAJOR 1     /* 主版本号 */ #define NID ...

  8. android基于gpuimage和photoview的图片编辑(滤镜,饱和度,裁剪)

    android基于gpuimage和photoview的图片编辑(滤镜,饱和度,裁剪) 前言 此博客方便自己使用与他人交流,未经同意不允许他人转载 以前在项目中遇到图片处理的需求,滤镜.饱和度处理和裁 ...

  9. [嵌入式er笔记]大端小端详解(含代码及详细注释)

    link 之前文章< 浅谈ARM ABI,Android ABI >中有提到计划专门一篇文章讲下大小端,今天兑现一下. 1>"大端" "小端" ...

最新文章

  1. awk4.0 — awk格式化
  2. 一次打流过程的优化反思(iperf3的灵活运用)
  3. 我心中的核心组件(可插拔的AOP)~第十三回 实现AOP的拦截组件Unity.Interception...
  4. 鸽巢原理(抽屉原理)的详解
  5. python手机版下载3.7.3-QPython3手机版下载
  6. CIDetector 相册识别二维码出错
  7. python模块matplotlib.pyplot用法_python – 虽然使用pyplot.show(),但如何使用matplotlib保持图形大小不变?...
  8. logstic 回归
  9. 统计插件_CG Teamwork统计提交量插件制作思路
  10. js调试微博登录案例
  11. 超越用户embedding矩阵:用哈希对大型用户建模
  12. mac安装brew简单方法
  13. “睡服”面试官系列第三篇之变量的结构赋值(建议收藏学习)
  14. SQL Server:触发器详解
  15. 关于 mahout factorize-movielens-1M.sh 执行
  16. ubantu安装mysql卡住_ubuntu安装mysql遇到的问题
  17. solve stiffness matrix in matlab
  18. 实现人人网爬去数据(opener)
  19. 破解百度空间、新浪相册、网易、搜狐等博客图片防盗链的方法
  20. vue-父子组件传参以及无限级评论

热门文章

  1. 谁说女生不适合当程序员?
  2. C# mongodb 类库
  3. Linux--Ubuntu12.04下安装JDK
  4. Java面试题-javaweb篇七
  5. 开源 java CMS - FreeCMS2.8 数据对象 question
  6. 【贪心】【P5078】Tweetuzki 爱军训
  7. 谈谈HTTP1.0,HTTP1.1和HTTP2.0区别
  8. centos6.5环境安装zookeeper-3.4.5
  9. 阿里巴巴加大IT人才引进 只为捍卫云计算市场地位
  10. centos6.5用memcached 来作PHP 的session.save_handler