由于最近需要做一些美顏相關(guān)的工作,在百度上面進(jìn)行一番搜索發(fā)現(xiàn)關(guān)于美顏磨皮的相關(guān)資料很少。本人對(duì)美顏相關(guān)的算法一點(diǎn)都不會(huì)。只能研究相關(guān)的三方框架。下面介紹一下開源框架GPUimage如何實(shí)現(xiàn)我們的人臉磨皮功能
首先我們?cè)陧?xiàng)目中導(dǎo)入 生成好的包 GUPimage.framework? 下載地址:http://download.csdn.net/download/conslee/8386145
下面是我們的主要類容 GPUImageBeautifyFilter類 ?是一個(gè)自定義的美顏濾鏡,可以用來處理實(shí)時(shí)視頻流或者是靜態(tài)圖片主要原理是雙邊濾波、Canny邊緣檢測(cè)和膚色檢測(cè)
GPUImageBeautifyFilter.h文件
#import<GPUImage/GPUImage.h>
@class GPUImageCombinationFilter;
@interface GPUImageBeautifyFilter : GPUImageFilterGroup {
GPUImageBilateralFilter *bilateralFilter;
GPUImageCannyEdgeDetectionFilter *cannyEdgeFilter;
GPUImageCombinationFilter *combinationFilter;
GPUImageHSBFilter *hsbFilter;
}
@end
GPUImageBeautifyFilter.m文件
#import "GPUImageBeautifyFilter.h"
#import "GPUImageThreeInputFilter.h"
// Internal CombinationFilter(It should not be used outside)
@interface GPUImageCombinationFilter : GPUImageThreeInputFilter{? ? GLint smoothDegreeUniform;}@property (nonatomic, assign) CGFloat intensity;@endNSString *const kGPUImageBeautifyFragmentShaderString = SHADER_STRING( varying highp vec2 textureCoordinate; varying highp vec2 textureCoordinate2; varying highp vec2 textureCoordinate3;? uniform sampler2D inputImageTexture; uniform sampler2D inputImageTexture2; uniform sampler2D inputImageTexture3; uniform mediump float smoothDegree;? void main() {? ? highp vec4 bilateral = texture2D(inputImageTexture, textureCoordinate);? ? highp vec4 canny = texture2D(inputImageTexture2, textureCoordinate2);? ? highp vec4 origin = texture2D(inputImageTexture3,textureCoordinate3);? ? 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- (id)init {? ? 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- (id)init;{? ? if (!(self = [super init]))? ? {? ? ? ? return nil;? ? }? ? ? ? // First pass: face smoothing filter? ? bilateralFilter = [[GPUImageBilateralFilter alloc] init];? ? bilateralFilter.distanceNormalizationFactor = 4.0;? ? [self addFilter:bilateralFilter];? ? ? ? // Second pass: edge detection? ? cannyEdgeFilter = [[GPUImageCannyEdgeDetectionFilter alloc] init];? ? [self addFilter:cannyEdgeFilter];? ? ? ? // Third pass: combination bilateral, edge detection and origin? ? combinationFilter = [[GPUImageCombinationFilter alloc] init];? ? [self addFilter:combinationFilter];? ? ? ? // Adjust HSB? ? hsbFilter = [[GPUImageHSBFilter alloc] init];? ? [hsbFilter adjustBrightness:1.1];? ? [hsbFilter adjustSaturation:1.1];? ? ? ? [bilateralFilter addTarget:combinationFilter];? ? [cannyEdgeFilter addTarget:combinationFilter];? ? ? ? [combinationFilter addTarget:hsbFilter];? ? ? ? self.initialFilters = [NSArray arrayWithObjects:bilateralFilter,cannyEdgeFilter,combinationFilter,nil];? ? self.terminalFilter = hsbFilter;? ? ? ? return self;? ? }#pragma mark -#pragma mark GPUImageInput protocol- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;{? ? for (GPUImageOutput*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*currentFilter in self.initialFilters)
{
if (currentFilter == combinationFilter) {
textureIndex = 2;
}
[currentFilter setInputFramebuffer:newInputFramebuffer atIndex:textureIndex];
}
}
@end
有了我們的核心模塊 下面再介紹一下另外一個(gè)類 GPUImageThreeInputFilter ?這個(gè)類在我們的GPUimage.framwork包里面有問題,在外面調(diào)用不上(親測(cè))但是我們必須要使用到這個(gè)類 我們就需要在Gpuimage開源項(xiàng)目中將這個(gè)類單獨(dú)提出來

準(zhǔn)備好了這兩步之后 我就不啰嗦了 直接上代碼?
UIImage? *image=[UIImage imageNamed:@"LSS.jpg"];
UIImageView *image1=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
image1.image=image;
[self.view addSubview:image1];
NSLog(@"%@",image);
// GPUImageBrightnessFilter *filter = [[GPUImageBrightnessFilter alloc] init];
// filter.brightness=0.2;
//磨皮
GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:image];
GPUImageBeautifyFilter *filter = [[GPUImageBeautifyFilter alloc] init];
[filter forceProcessingAtSize:image.size];
[pic addTarget:filter];
[pic processImage];
[filter useNextFrameForImageCapture];
image =[filter imageFromCurrentFramebuffer];
//image=[self filteredImage:image withFilterName:@"CILinearToSRGBToneCurve" ];
UIImageView *image2=[[UIImageView alloc]initWithFrame:CGRectMake(0,200, 200, 200)];
image2.image=image;
[self.view addSubview:image2];
NSLog(@"%@",image);
最后的效果圖 附上女神一張 漂亮吧 自己再配上濾鏡吧
