自动增强图片效果
28 Mar 2014Core Image的自动强图片效果,会分析图像的直方图,图像属性,脸部区域,然后通过一组滤镜来改善图片效果。
自动增强滤镜
下面这些滤镜可以修正照片中的大部分问题:
Filter | Purpose |
---|---|
CIRedEyeCorrection | Repairs red/amber/white eye due to camera flash |
CIFaceBalance | Adjusts the color of a face to give pleasing skin tones |
CIVibrance | Increases the saturation of an image without distorting the skin tones |
CIToneCurve | Adjusts image contrast |
CIHighlightShadowAdjust | Adjusts shadow details |
自动增强API仅有2个方法:autoAdjustmentFilters
和 autoAdjustmentFiltersWithOptions:
. 多数情况下,我们使用带参数的方法。
- 图像的方向 :对于
CIRedEyeCorrection
和CIFaceBalance
滤镜,提供图像方向可以使Core Image
更精确的定位到脸的位置。 - 是否应用红眼校正把
kCIImageAutoAdjustEnhance
设置为false) - 是否使用红眼校正以外的全部其他滤镜。(把
kCIImageAutoAdjustRedEye
设置为false)
通过autoAdjustmentFiltersWithOptions我们会得到一个包含图像增强的所有的滤镜的数组。依次调用它们处理图像。
1 CIContext *context = [CIContext contextWithOptions:nil];
2 UIImage *baby = [UIImage imageNamed:@"1.jpg"];
3 CIImage *myImage = [CIImage imageWithCGImage:baby.CGImage];
4 NSArray *adjustments = [myImage autoAdjustmentFilters];
5 for (CIFilter *filter in adjustments) {
6 [filter setValue:myImage forKey:kCIInputImageKey];
7 myImage = filter.outputImage;
8 }
左图就是自动增强之后的效果。
负片滤镜
1 CIFilter *filter = [CIFilter filterWithName:@"CIColorMatrix" keysAndValues:
2 kCIInputImageKey, myImage,
3 @"inputRVector", [CIVector vectorWithX: -1 Y:0 Z:0],
4 @"inputGVector", [CIVector vectorWithX:0 Y:-1 Z:0 ],
5 @"inputBVector", [CIVector vectorWithX: 0 Y:0 Z:-1],
6 @"inputBiasVector", [CIVector vectorWithX:1 Y:1 Z:1],nil];
扣图滤镜
我们可以删除一幅图像中指定的颜色,然后填充一个背景。类似好莱坞大片的背景合成。
要实现上面图片的效果有下面几个步骤
- 首先我们要从图像中删除我们要删掉的颜色,通过创建一个颜色矩阵,将要删除的颜色变换成透明色。
- 用
CICOlorCube
滤镜删除图像中通过矩阵变换过的颜色。 - 最后用
CISourceOverCompositing
合成图片。
创建一个 color Cube Map
一个color cube是一个3D颜色查找表(lookup table)。Core Image 滤镜 CIColorCube 使用色值作为输入,并应用一个查找表到这些色值。
CIColorCube
从图像中删除所有的绿色。就是要把图中的把绿色的alpha
值设置为0.0(透明)。
“绿色”包括一定范围内的颜色。最直接的处理方式是把图像的色值从RGBA转为HSV。HSV把颜色描述在圆柱坐标系内的点。
要删除绿色,你需要定义围绕中心点的最小和最大的角度。之后,对于任何的绿色,将其alpha值设置为0.0。纯绿的相对角度是120º。最小值和最大值要以这个值为中心。
Cube map数据必须预乘alpha,所以创建cube map的最后一步是把RGB值乘以你刚刚计算出的alpha值(如果是绿色,就是0,如果不是就是1.0) 下面是例子代码。
1 CIContext *context = [CIContext contextWithOptions:nil];
2 UIImage *baby = [UIImage imageNamed:@"2.jpg"];
3 CIImage *myImage = [CIImage imageWithCGImage:baby.CGImage];
4 // Allocate memory
5 const unsigned int size = 64;
6 float *cubeData = (float *)malloc (size * size * size * sizeof (float) * 4);
7 float rgb[3], hsv[3], *c = cubeData;
8
9 // Populate cube with a simple gradient going from 0 to 1
10 for (int z = 0; z < size; z++){
11 rgb[2] = ((double)z)/(size-1); // Blue value
12 for (int y = 0; y < size; y++){
13 rgb[1] = ((double)y)/(size-1); // Green value
14 for (int x = 0; x < size; x ++){
15 rgb[0] = ((double)x)/(size-1); // Red value
16 // Convert RGB to HSV
17 // You can find publicly available rgbToHSV functions on the Internet
18 RGBtoHSV(rgb[0],rgb[1],rgb[2], &hsv[0],&hsv[1],&hsv[2]);
19
20 float alpha = (hsv[0] > 80 && hsv[0] < 130) ? 0.0f:1.0f;
21 // Calculate premultiplied alpha values for the cube
22 c[0] = rgb[0] * alpha;
23 c[1] = rgb[1] * alpha;
24 c[2] = rgb[2] * alpha;
25 c[3] = alpha;
26 c += 4;
27 }
28 }
29 }
30 // Create memory with the cube data
31 NSData *data = [NSData dataWithBytesNoCopy:cubeData length:(size * size * size * sizeof (float) * 4) freeWhenDone:YES];
32 CIFilter *colorCube = [CIFilter filterWithName:@"CIColorCube"];
33 [colorCube setValue:@(size) forKey:@"inputCubeDimension"];
34 [colorCube setValue:myImage forKey:@"inputImage"];
35 [colorCube setValue:data forKey:@"inputCubeData"];
36 myImage = colorCube.outputImage;
37
38 void RGBtoHSV( float r, float g, float b, float *h, float *s, float *v ){
39 float min, max, delta;
40 min = MIN( r, MIN(g, b) );
41 max = MAX( r, MAX(g, b) );
42 *v = max; // v
43 delta = max - min;
44 if( max != 0 )
45 *s = delta / max; // s
46 else {
47 // r = g = b = 0 // s = 0, v is undefined
48 *s = 0;
49 *h = -1;
50 return;
51 }
52 if( r == max )
53 *h = ( g - b ) / delta; // between yellow & magenta
54 else if( g == max )
55 *h = 2 + ( b - r ) / delta; // between cyan & yellow
56 else
57 *h = 4 + ( r - g ) / delta; // between magenta & cyan
58 *h *= 60; // degrees
59 if( *h < 0 )
60 *h += 360;
61 }
我们可以根据 HSV角度试试删除黄色
float alpha = (hsv[0] > 30 && hsv[0] < 55) ? 0.0f:1.0f;
删除指定的颜色后,我们可以填充一个背景图片。
1 UIImage *image2 = [UIImage imageNamed:@"5.png"];
2 CIImage *backgroundCIImage = [CIImage imageWithCGImage:image2.CGImage];
3 myImage = [[CIFilter filterWithName:@"CISourceOverCompositing" keysAndValues:kCIInputImageKey,myImage,kCIInputBackgroundImageKey,backgroundCIImage,nil] valueForKey:kCIOutputImageKey];
4 CGRect extent = [myImage extent];
5 CGImageRef cgImage = [context createCGImage:myImage fromRect:extent];