Brad Larson
http://www.sunsetlakesoftware.com
GPUImage 框架是一个 BSD 许可的 iOS 库,它允许您将 GPU 加速的滤镜和其他效果应用于图像、实时相机视频和电影。与 Core Image(iOS 5.0 的一部分)相比,GPUImage 允许您编写自己的自定义滤镜,支持部署到 iOS 4.0,并且拥有更简单的界面。然而,它目前缺少 Core Image 的一些更高级功能,如面部检测。
对于像处理图像或实时视频帧这样的大规模并行操作,GPU 相比 CPU 拥有一些显著的性能优势。在iPhone 4上,简单的图像滤镜在 GPU 上执行的速度可以比基于 CPU 的相同滤镜快 100 倍以上。
然而,在 GPU 上运行自定义滤镜需要大量的代码来设置和维护这些滤镜的 OpenGL ES 2.0 渲染目标。我创建了这样一个示例项目来做这件事
http://www.sunsetlakesoftware.com/2010/10/22/gpu-accelerated-video-processing-mac-and-ios
并发现我在其创建过程中不得不写很多的样板代码。因此,我将这个框架汇集起来,它封装了处理图像和视频时遇到的许多常见任务,并确保您不需要关心 OpenGL ES 2.0 的底层。
当处理视频时,该框架与 Core Image 相比表现良好,iPhone 4 在将相机帧上传、应用伽玛滤镜和显示时只需 2.5 毫秒,而使用 Core Image 进行相同操作需要 106 毫秒。基于 CPU 的处理需要 460 毫秒,这使得 GPUImage 在此硬件上相对于 Core Image 的此操作贵了 40 倍,相对于基于 CPU 的处理贵了 184 倍。然而,对于像大半径高斯模糊这样的更复杂操作,Core Image 目前超过了 GPUImage。
BSD 风格,完整的许可证可在框架的 License.txt 文件中找到。
GPUImage使用OpenGL ES 2.0着色器进行图像和视频处理,速度比CPU处理要快得多。然而,它通过简化的Objective-C接口隐藏了与OpenGL ES API交互的复杂性。此接口允许您为图像和视频定义输入源,附加过滤器序列,并将处理后的图像或视频发送到屏幕,UIImage或磁盘上的电影。
图像或视频帧从源对象上载,这些源对象是GPUImageOutput的子类。这些包括GPUImageVideoCamera(用于来自iOS摄像机的实时视频)、GPUImageStillCamera(用于拍照)、GPUImagePicture(用于静态图像)和GPUImageMovie(用于电影)。源对象将静态图像帧作为纹理上传到OpenGL ES,然后将这些纹理交给处理链中的下一个对象。
过滤器和其他处理链中的后续元素符合GPUImageInput协议,这允许它们从链中的前一个链接接收提供或处理的纹理并进行某些操作。链中更下游的对象被视为目标,可以通过向单个输出或过滤器添加多个目标来分支处理。
例如,一个从相机获取实时视频,将其转换为棕色调,然后显示视频在屏幕上的应用程序将设置如下所示的处理链
GPUImageVideoCamera -> GPUImageSepiaFilter -> GPUImageView
注意:如果您想在Swift项目中使用此框架,则需要使用“将此作为框架添加”部分中的步骤,而不是以下步骤。Swift需要第三方代码的模块。
一旦您获得框架的最新源代码,将其添加到应用程序中就相当简单。首先,将GPUImage.xcodeproj文件拖到您的应用Xcode项目中以嵌入框架。然后,转到您的应用程序目标,并将GPUImage添加为Target Dependency。最后,您需要将GPUImage框架产品文件夹中的libGPUImage.a库拖到您的应用程序目标的“Link Binary With Libraries”构建阶段中。
GPUImage需要将几个其他框架链接到您的应用程序中,因此您需要在应用程序目标中添加以下作为链接库
您还需要找到框架头文件,因此请将您的项目构建设置中的Header Search Paths设置为从您的应用到GPUImage源目录中框架/子目录的相对路径。将此头搜索路径设置为递归。
要在您的应用程序中使用GPUImage类,请使用以下方式包括核心框架头文件
#import "GPUImage.h"
作为备注:如果您在尝试使用Interface Builder构建界面时遇到“未知的类GPUImageView”错误或类似错误,您可能需要在项目构建设置的其他链接器标志中添加-ObjC。
此外,如果您需要将该应用程序部署到iOS 4.x上,当前版本的Xcode(4.3)要求您在最终应用程序中使用弱连接Core Video框架,否则在为上传到App Store或随机分发创建存档时可能会看到崩溃信息“找不到符号:_CVOpenGLESTextureCacheCreate”。为此,请转到项目的“构建阶段”选项卡,展开“与二进制链接库”组,并在列表中找到CoreVideo.framework。将该设置更改为列表右侧的“必需”为“可选”。
此外,这是一个支持自动引用计数(ARC)的框架,因此如果您想在针对iOS 4.x的手动引用计数应用程序中使用它,您还需要在“其他链接器标志”中添加-fobjc-arc。
如果您不想将项目包括在应用程序的Xcode项目中作为依赖项,可以为iOS模拟器或设备构建通用的静态库。为此,请在命令行中运行build.sh
。生成的库和头文件将位于build/Release-iphone
。您还可以通过更改build.sh
中的IOSSDK_VER
变量来更改iOS SDK的版本(所有可用版本可以使用xcodebuild -showsdks
找到)。
Xcode 6和iOS 8支持使用完整框架,同样Mac也支持,这简化了将其添加到应用程序的过程。要将此添加到您的应用程序中,我建议将.xcodeproj项目文件拖动到您的应用程序项目中(就像在静态库目标中做的那样)。
对于您的应用程序,请转到其目标构建设置并选择“构建阶段”选项卡。在“目标依赖关系”分组中,在iOS上添加GPUImageFramework(不是构建静态库的GPUImage)或在Mac上添加GPUImage。在“与二进制链接库”部分中添加GPUImage.framework。
这将导致GPUImage作为框架进行构建。在Xcode 6中,这还将作为模块进行构建,这将允许您在Swift项目中使用它。当设置为上述内容时,您只需要使用
import GPUImage
来包含它。
然后您需要添加一个新的“复制文件”构建阶段,将目标设置为“框架”,并将GPUImage.framework构建产品添加到其中。这将允许框架与应用程序捆绑(否则,在执行时您将看到难以理解的“dyld:找不到库:@rpath/GPUImage.framework/GPUImage”错误)。
文档是通过使用appledoc从头文件注释生成的。要生成文档,请在Xcode中切换到“文档”方案。您应确保“APPLEDOC_PATH”(一个用户定义的构建设置)指向一个appledoc二进制文件,它可在GitHub或通过Homebrew获取。它还将构建并安装一个.docset文件,您可以用您喜欢的文档工具打开它。
要从iOS设备的相机过滤实时视频,您可以使用以下代码:
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
GPUImageFilter *customFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"CustomShader"];
GPUImageView *filteredVideoView = [[GPUImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, viewWidth, viewHeight)];
// Add the view somewhere so it's visible
[videoCamera addTarget:customFilter];
[customFilter addTarget:filteredVideoView];
[videoCamera startCameraCapture];
这配置了一个由iOS设备的后置摄像头提供的视频源,使用预设尝试以640x480分辨率捕捉视频。视频是在 portrait 模式下捕捉的,此时需要将横向左挂的摄像头的视频帧在显示前进行旋转。然后,使用来自文件CustomShader.fsh的代码的定制过滤器的代码被设置为来自摄像头的视频帧的目标。这些滤波后的视频帧最后在协助下通过一个能够呈现从这一流程生成的过滤Open GL ES纹理的UIView子类在屏幕上显示。
可以通过设置GPUImageView的fillMode属性来改变GPUImageView的填充模式,因此如果源自视频的宽高比与视图的不同,视频将被拉伸、边框黑条居中或放大以填充。
对于需要接收多张图像的混合过滤器等,可以创建多个输出并将一个过滤器作为这两个输出的目标。将输出添加为目标的顺序将影响图像混合或处理的顺序。
此外,如果您想启用麦克风音频捕捉以录制电影,您需要将相机的audioEncodingTarget设置为您的电影编解码器,如下所示
videoCamera.audioEncodingTarget = movieWriter;
要捕捉和过滤静态照片,可以使用与过滤视频类似的过程。您使用GPUImageStillCamera代替GPUImageVideoCamera
stillCamera = [[GPUImageStillCamera alloc] init];
stillCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
filter = [[GPUImageGammaFilter alloc] init];
[stillCamera addTarget:filter];
GPUImageView *filterView = (GPUImageView *)self.view;
[filter addTarget:filterView];
[stillCamera startCameraCapture];
这将为您提供一个实时过滤的静态相机的预览视频流。请注意,此预览视频仅在iOS 4.3及更高版本上提供,因此如果您希望使用此功能,可能需要将部署目标设置为那个版本。
一旦您想捕捉一张照片,您可以使用以下类似的回调块
[stillCamera capturePhotoProcessedUpToFilter:filter withCompletionHandler:^(UIImage *processedImage, NSError *error){
NSData *dataForJPEGFile = UIImageJPEGRepresentation(processedImage, 0.8);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSError *error2 = nil;
if (![dataForJPEGFile writeToFile:[documentsDirectory stringByAppendingPathComponent:@"FilteredPhoto.jpg"] options:NSAtomicWrite error:&error2])
{
return;
}
}];
上面的代码捕获由与预览视图中使用相同过滤链处理的完整大小照片,并将其作为JPEG保存到应用的文档目录磁盘上。
请注意,由于纹理大小限制,该框架目前无法处理大于2048像素宽或高的图像(iPhone 4S、iPad 2或Retina iPad之前的老式设备)。这意味着iPhone 4,其相机输出的静态照片大于此,将无法捕捉此类照片。实施一个拼贴机制来解决这个问题。所有其他设备应能够使用此方法捕捉和过滤照片。
有两种方式来处理静态图像并创建一个结果。第一种方法是创建一个静态图像源对象并手动创建一个过滤链
UIImage *inputImage = [UIImage imageNamed:@"Lambeau.jpg"];
GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:inputImage];
GPUImageSepiaFilter *stillImageFilter = [[GPUImageSepiaFilter alloc] init];
[stillImageSource addTarget:stillImageFilter];
[stillImageFilter useNextFrameForImageCapture];
[stillImageSource processImage];
UIImage *currentFilteredVideoFrame = [stillImageFilter imageFromCurrentFramebuffer];
请注意,对于从过滤器手动捕获的图像,您需要设置-useNextFrameForImageCapture以便告诉过滤器您将来需要从它那里捕获。默认情况下,GPUImage会重用过滤器内的帧缓冲区以节省内存,所以如果您需要保留一个过滤器的帧缓冲区以手动捕获图像,您需要提前通知它。
对于您想要对一个图像应用的单个过滤器,您可以简单地这样做
GPUImageSepiaFilter *stillImageFilter2 = [[GPUImageSepiaFilter alloc] init];
UIImage *quickFilteredImage = [stillImageFilter2 imageByFilteringImage:inputImage];
与iOS的Core Image(截至iOS 5.0)相比,此框架的一个显著优势是您可以编写自己的自定义图像和视频处理过滤器。这些过滤器作为OpenGL ES 2.0片段着色器提供,使用类似的C语言OpenGL着色语言编写。
自定义过滤器可以通过以下代码进行初始化
GPUImageFilter *customFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"CustomShader"];
片段着色器使用的扩展名是 .fsh。此外,您还可以使用 -initWithFragmentShaderFromString: 初始化器将片段着色器作为字符串提供,如果不想将片段着色器打包到应用程序包中。
片段着色器在每个要在该滤镜阶段渲染的像素上进行计算。它们使用 OpenGL 着色语言(GLSL)、一种类似于 C 的语言,增加了针对 2D 和 3D 图形的特定功能。以下是一个片段着色器的示例:以下 Sepia 灰度滤镜
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 outputColor;
outputColor.r = (textureColor.r * 0.393) + (textureColor.g * 0.769) + (textureColor.b * 0.189);
outputColor.g = (textureColor.r * 0.349) + (textureColor.g * 0.686) + (textureColor.b * 0.168);
outputColor.b = (textureColor.r * 0.272) + (textureColor.g * 0.534) + (textureColor.b * 0.131);
outputColor.a = 1.0;
gl_FragColor = outputColor;
}
为了在 GPUImage 框架中使用图像滤镜,需要前两条语句,用于接收纹理坐标变量(当前纹理中的坐标,标准化到 1.0)和输入图像纹理(实际输入图像帧纹理)。
着色器的其余部分获取在传入纹理中此位置的像素颜色,以产生 Sepia 灰度,并将该像素颜色写入下一次处理管道使用。
当将片段着色器添加到 Xcode 项目时,需要注意的是 Xcode 认为它们是源代码文件。为了解决这个问题,需要手动将着色器从编译源文件构建阶段移动到复制包资源构建阶段,以便将着色器包含在应用程序包中。
可以通过 GPUImageMovie 类将电影加载到框架中,过滤它们,然后使用 GPUImageMovieWriter 写入。GPUImageMovieWriter 速度足够快,可以从 iPhone 4 的摄像头实时录制 640x480 的视频,因此可以直接将已过滤的视频源输入其中。目前,GPUImageMovieWriter 可以在 iPhone 4 上实时录制高达 20 FPS 的直播 720p 视频,在 iPhone 4S 上(以及新 iPad)以 30 FPS的速度录制 720p 和 1080p 视频。
以下是如何加载一个示例电影,通过像素化滤镜传递它,然后将其记录为 480x640 的 h.264 电影的示例
movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL];
pixellateFilter = [[GPUImagePixellateFilter alloc] init];
[movieFile addTarget:pixellateFilter];
NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([pathToMovie UTF8String]);
NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(480.0, 640.0)];
[pixellateFilter addTarget:movieWriter];
movieWriter.shouldPassthroughAudio = YES;
movieFile.audioEncodingTarget = movieWriter;
[movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter];
[movieWriter startRecording];
[movieFile startProcessing];
录制完成后,需要从滤镜链中删除电影录制器,并使用如下代码关闭录制
[pixellateFilter removeTarget:movieWriter];
[movieWriter finishRecording];
电影完成前不能使用,所以如果在这之前中断,将丢失录制。
GPUImage 可以通过其 GPUImageTextureOutput 和 GPUImageTextureInput 类导出和导入 OpenGL ES 中的纹理。这允许您从渲染到具有绑定纹理的帧缓冲对象的光栅化 OpenGL ES 场景中录制电影,或者对视频或图像进行过滤,然后将它们作为纹理输入到 OpenGL ES 以在场景中显示。
使用这种方法的一个警告是,在这些过程中使用的纹理必须在 GPUImage 的 OpenGL ES 上下文和其他任何类似共享组的上下文之间共享。
目前有 125 个内置滤镜,分为以下类别
GPUImageBrightnessFilter:调整图像亮度
GPUImageExposureFilter:调整图像曝光度
GPUImageContrastFilter:调整图像对比度
GPUImageSaturationFilter:调整图像的饱和度
GPUImageGammaFilter:调整图像的伽马值
GPUImageLevelsFilter:类似于Photoshop的级别调整。min, max, minOut和maxOut参数的范围是[0, 1]。如果您有来自Photoshop的范围为[0, 255]的参数,您必须首先将它们转换为[0, 1]。gamma/mid参数是一个大于等于0的浮点数。这与Photoshop中的值匹配。如果要同时将级别应用于RGB以及单独的通道,需要使用此过滤器两次 - 首先用于单个通道,然后用于所有通道。
GPUImageColorMatrixFilter:通过应用矩阵来转换图像的颜色
GPUImageRGBFilter:调整图像的单独RGB通道
GPUImageHueFilter:调整图像的色调
GPUImageVibranceFilter:调整图像的活力
GPUImageWhiteBalanceFilter:调整图像的白平衡。
GPUImageToneCurveFilter:根据每个颜色通道的样条曲线调整图像的颜色。
GPUImageHighlightShadowFilter:调整图像的阴影和高光
GPUImageHighlightShadowTintFilter:允许您使用颜色和强度独立地为图像的阴影和高光着色
{1.0f, 0.0f, 0.0f, 1.0f}
(红色){0.0f, 0.0f, 1.0f, 1.0f}
(蓝色)GPUImageLookupFilter:使用RGB颜色查找图像重新映射图像中的颜色。首先,使用您喜欢的照片编辑应用程序将过滤器应用于GPUImage/framework/Resources中的lookup.png。为了正确工作,每个像素的颜色必须不依赖于其他像素(例如,模糊将不起作用)。如果您需要更复杂的过滤器,可以创建任意数量的查找表。一旦准备就绪,使用您的新lookup.png文件作为GPUImageLookupFilter的第二输入。
GPUImageAmatorkaFilter:基于Amatorka的Photoshop动作的照片过滤器:http://amatorka.deviantart.com/art/Amatorka-Action-2-121069631。如果要使用此效果,您必须将GPUImage Resources文件夹中的lookup_amatorka.png添加到您的应用程序包中。
GPUImageMissEtikateFilter:基于Miss Etikate的Photoshop动作的照片过滤器:http://miss-etikate.deviantart.com/art/Photoshop-Action-15-120151961。如果要使用此效果,您必须将GPUImage Resources文件夹中的lookup_miss_etikate.png添加到您的应用程序包中。
GPUImageSoftEleganceFilter:另一个基于查找表的色彩重新映射过滤器。如果要使用此效果,您必须将GPUImage Resources文件夹中的lookup_soft_elegance_1.png和lookup_soft_elegance_2.png添加到您的应用程序包中。
GPUImageSkinToneFilter:一种皮肤色调调整过滤器,影响独特的浅色皮肤色调范围,并相应地调整粉红色/绿色或粉红色/橙色范围。默认值针对的是浅色白人皮肤,但可以根据需要进行调整。
GPUImageSkinToneUpperColorGreen
或GPUImageSkinToneUpperColorOrange
GPUImageColorInvertFilter:反转图像中的颜色
GPUImageGrayscaleFilter:将图像转换为灰度(饱和度过滤器的一种稍微快一点的实现,但没有能力变换颜色贡献)
GPUImageMonochromeFilter:根据每个像素的亮度将图像转换为单色版本
GPUImageFalseColorFilter:使用图像的亮度在两个用户指定的颜色之间混合
GPUImageHazeFilter:用于添加或去除雾气(类似于UV滤镜)
GPUImageSepiaFilter:简单的棕褐色滤镜
GPUImageOpacityFilter:调整输入图像的alpha通道
GPUImageSolidColorGenerator:输出具有单一颜色的生成图像。您需要使用-forceProcessingAtSize定义图像大小
GPUImageLuminanceThresholdFilter:亮度高于阈值的像素将显示为白色,低于阈值的将显示为黑色
GPUImageAdaptiveThresholdFilter:根据像素周围的局部亮度判断,如果低于该局部亮度则将该像素变为黑色,如果高于则变为白色。这在不同光照条件下提取文本时可能很有用。
GPUImageAverageLuminanceThresholdFilter:这种操作会对场景的平均亮度进行阈值调整。
GPUImageHistogramFilter:分析输入的图像并创建一个包含各颜色值发生频率的输出直方图。该过滤器的输出是一个3像素高、256像素宽的图像,中心的像素(垂直)包含与各种颜色值发生频率相对应的像素。每个颜色值占用256个宽度位置中的一个,从左边的0到右边的255。该直方图可以为单个颜色通道(kGPUImageHistogramRed、kGPUImageHistogramGreen、kGPUImageHistogramBlue)、图像的亮度(kGPUImageHistogramLuminance)或同时为三个颜色通道(kGPUImageHistogramRGB)生成。
GPUImageHistogramGenerator:这是一个特殊的过滤器,其主要目的是配合GPUImageHistogramFilter使用。它生成由GPUImageHistogramFilter生成的颜色直方图的输出表示,但它也可以重新用于显示其他类型的值。它接受一个图像并检查中心(垂直)像素。然后它分别在输出纹理中的不同颜色图中绘制RGB分量的数值。您可能需要强制设置该过滤器的尺寸以使其输出可见。
GPUImageAverageColor:处理输入图像并确定场景的平均颜色,通过平均图像中每个像素的RGBA分量。使用降采样过程在GPU上逐渐的下采样源图像,然后进行CPU上的短期平均计算。this filter的输出没有意义,但需要设置colorAverageProcessingFinishedBlock属性为一个块,它接受四个颜色分量和一帧时间并对其进行处理。
GPUImageLuminosity:与GPUImageAverageColor类似,它将图像降低到其平均亮度。您需要设置luminosityProcessingFinishedBlock以处理该过滤器的输出,它只返回亮度和帧时间。
GPUImageChromaKeyFilter:给图像中的给定颜色设置alpha通道为0。这与GPUImageChromaKeyBlendFilter类似,但不同的是它不接受第二个图像混入匹配的颜色,只是将给定的颜色变为透明。
GPUImageTransformFilter:对图像应用任意的2D或3D变换
GPUImageCropFilter:将图像裁剪到指定的区域,然后将该区域传递到过滤器的下一阶段。
GPUImageLanczosResamplingFilter:允许使用Lanczos重采样上采样或下采样图像,与标准线性或三线性插值相比,效果显著更好。只需使用-forceProcessingAtSize:来设置目标输出分辨率,图像将为此新大小进行重采样。
GPUImageSharpenFilter:锐化图像
GPUImageUnsharpMaskFilter:应用非锐化掩码
GPUImageGaussianBlurFilter:硬件优化的、可变半径的高斯模糊
GPUImageBoxBlurFilter:硬件优化的、可变半径的箱形模糊
GPUImageSingleComponentGaussianBlurFilter:GPUImageGaussianBlurFilter的一种修改,仅对红色组件进行操作
GPUImageGaussianSelectiveBlurFilter:高斯模糊,在圆形区域内保留焦点
GPUImageGaussianBlurPositionFilter:GPUImageGaussianSelectiveBlurFilter的逆操作,只在特定的圆形内应用模糊
GPUImageiOSBlurFilter:尝试复制iOS 7在控制中心等地方使用的背景模糊
GPUImageMedianFilter:对3x3区域的三个颜色成分取中值
GPUImageBilateralFilter:双边模糊,试图模糊相似颜色值同时保留清晰边缘
GPUImageTiltShiftFilter: 模拟倾斜移轴镜头效果
GPUImage3x3ConvolutionFilter: 在图像上运行 3x3 卷积核
GPUImageSobelEdgeDetectionFilter: Sobel 边缘检测,边缘以白色突出显示
GPUImagePrewittEdgeDetectionFilter: Prewitt 边缘检测,边缘以白色突出显示
GPUImageThresholdEdgeDetectionFilter: 执行 Sobel 边缘检测,但应用阈值而不是给出逐渐增加的强度值
GPUImageCannyEdgeDetectionFilter: 使用完整 Canny 过程来突出显示宽度为一像素的边缘
GPUImageHarrisCornerDetectionFilter: 在输入图像上运行 Harris 角点检测算法,产生一个白色像素表示角点,其余黑色像素的图像。可以设置 cornersDetectedBlock,你将在此回调中提供一个角点列表(在 0..1 的归一化 X,Y 坐标内),你可以针对你想要执行的任何其他操作。
GPUImageNobleCornerDetectionFilter: 在 Harris 角点检测器上运行 Noble 变体。它的行为与上述 Harris 检测器描述的类似。
GPUImageShiTomasiCornerDetectionFilter: 运行 Shi-Tomasi 特征检测器。它的行为与上述 Harris 检测器描述的类似。
GPUImageNonMaximumSuppressionFilter:目前仅作为Harris角点检测滤波器的一部分使用,将在每个像素周围采样1像素大小的框,并确定中心像素的红色通道是否是该区域的最大值。如果是,则保持不变。如果不是,则将所有颜色分量设置为0。
GPUImageXYDerivativeFilter:Harris角点检测滤波器内部的一个组件,计算这个像素左右像素的平方差、上下像素的平方差以及这两个差的乘积。
GPUImageCrosshairGenerator:在图像上绘制一系列十字线,通常用于识别机器视觉特征。它不接受其他滤波器那样的标准图像,而是接受其 -renderCrosshairsFromArray:count: 方法中的一系列点,实际进行绘图。您需要强制该过滤器以所需的特定输出大小进行渲染。
GPUImageDilationFilter:执行图像膨胀操作,其中使用矩形邻域中红色通道的最大强度作为该像素的强度。在初始化时指定采样矩形区域的半径,范围为1-4像素。此操作用于灰度图像,并扩展明亮区域。
GPUImageRGBDilationFilter:这与 GPUImageDilationFilter 相同,但此操作作用于所有颜色通道,而不仅仅是红色通道。
GPUImageErosionFilter:执行图像腐蚀操作,其中使用矩形邻域中红色通道的最小强度作为该像素的强度。在初始化时指定采样矩形区域的半径,范围为1-4像素。此操作用于灰度图像,并扩展暗区域。
GPUImageRGBErosionFilter:这与 GPUImageErosionFilter 相同,但此操作作用于所有颜色通道,而不仅仅是红色通道。
GPUImageOpeningFilter:在图像的红色通道上执行腐蚀,然后执行相同半径的膨胀。在初始化时设置半径,范围为1-4像素。此过滤器可以去除较小的明亮区域。
GPUImageRGBOpeningFilter:这与 GPUImageOpeningFilter 相同,但此操作作用于所有颜色通道,而不仅仅是红色通道。
GPUImageClosingFilter:在图像的红色通道上执行膨胀,然后执行相同半径的腐蚀。在初始化时设置半径,范围为1-4像素。此过滤器可以去除较小的暗区域。
GPUImageRGBClosingFilter:这与 GPUImageClosingFilter 相同,但此操作作用于所有颜色通道,而不仅仅是红色通道。
GPUImageLocalBinaryPatternFilter:对周围8个像素和中央像素的红色通道强度进行比较,将比较结果编码为位字符串,该位字符串成为该像素的强度。最低有效位是右上比较,逆时针结束于最右比较作为最高有效位。
GPUImageLowPassFilter:对传入的视频帧应用低通滤波器。这基本上是将前一个帧的加权滚动平均值与当前帧相加。这可以用于降噪视频、添加运动模糊或用于创建高通滤波器。
GPUImageHighPassFilter:该滤镜对输入的视频帧应用高通滤波器。这是低通滤波器的逆操作,显示当前帧与先前加权滚动平均之间的差异。这对运动检测非常有用。
GPUImageMotionDetector:这是一个基于高通滤波器的运动检测器。您设置motionDetectionBlock,对于每个输入帧,它将提供场景中检测到的任何运动的质心(在归一化的X,Y坐标中),以及场景的运动强度。
GPUImageHoughTransformLineDetector:使用霍夫变换检测图像中的线。这种方法完全基于布拉格工业大学Graph@FIT研究组开发的PC线处理过程,并在其出版物中进行了描述:M. Dubská, J. Havel, and A. Herout. 实时使用平行坐标和OpenGL检测线。SCCG 2011会议论文集,斯洛伐克布达佩斯,p.7 (http://medusa.fit.vutbr.cz/public/data/papers/2011-SCCG-Dubska-Real-Time-Line-Detection-Using-PC-and-OpenGL.pdf) 和 M. Dubská, J. Havel, and A. Herout. PClines — 使用平行坐标进行线检测。2011 IEEE计算机视觉和模式识别会议(CVPR),p.1489- 1494 (http://medusa.fit.vutbr.cz/public/data/papers/2011-CVPR-Dubska-PClines.pdf)。
GPUImageLineGenerator:一个辅助类,它可以生成可覆盖场景的直线。可以使用-setLineColorRed:green:blue调整这些线的颜色。
GPUImageMotionBlurFilter:对图像应用定向运动模糊。
GPUImageZoomBlurFilter:对图像应用定向运动模糊。
GPUImageChromaKeyBlendFilter:选择性地用第二幅图替换第一幅图中的颜色
GPUImageDissolveBlendFilter:应用两个图像的溶解混合
GPUImageMultiplyBlendFilter:应用两个图像的乘法混合
GPUImageAddBlendFilter:应用两个图像的加法混合
GPUImageSubtractBlendFilter:应用两个图像的减法混合
GPUImageDivideBlendFilter:应用两个图像的除法混合
GPUImageOverlayBlendFilter:应用两个图像的叠加混合
GPUImageDarkenBlendFilter:通过取图像之间每个颜色分量的最小值来混合两个图像
GPUImageLightenBlendFilter:通过取图像之间每个颜色分量的最大值来混合两个图像
GPUImageColorBurnBlendFilter:应用两个图像的颜色燃烧混合
GPUImageColorDodgeBlendFilter:将两种图像进行颜色跳跃混合
GPUImageScreenBlendFilter:将两种图像进行屏幕混合
GPUImageExclusionBlendFilter:将两种图像进行排除混合
GPUImageDifferenceBlendFilter:将两种图像进行差异混合
GPUImageHardLightBlendFilter:将两种图像进行硬光混合
GPUImageSoftLightBlendFilter:将两种图像进行柔光混合
GPUImageAlphaBlendFilter:基于第二种图像的透明度通道,将第二种图像混合到第一种图像上
GPUImageSourceOverBlendFilter:将两种图像进行源上混合
GPUImageColorBurnBlendFilter:应用两个图像的颜色燃烧混合
GPUImageColorDodgeBlendFilter:将两种图像进行颜色跳跃混合
GPUImageNormalBlendFilter:将两种图像进行正常混合
GPUImageColorBlendFilter:将两种图像进行颜色混合
GPUImageHueBlendFilter:将两种图像进行色调混合
GPUImageSaturationBlendFilter:将两种图像进行饱和度混合
GPUImageLuminosityBlendFilter:将两种图像进行亮度混合
GPUImageLinearBurnBlendFilter:将两种图像进行线性燃烧混合
GPUImagePoissonBlendFilter:将两种图像进行泊松混合
GPUImageMaskFilter:使用另一张图像遮罩一张图像
GPUImagePixellateFilter:对图像或视频应用像素化效果
GPUImagePolarPixellateFilter:基于极坐标而不是笛卡尔坐标,在图像或视频上应用像素化效果
GPUImagePolkaDotFilter:将图像分割成规则网格中的彩色点
GPUImageHalftoneFilter:将图像应用网点效果,类似于新闻印刷
GPUImageCrosshatchFilter:将图像转换为黑白网状图案
GPUImageSketchFilter:将视频转换为素描效果。这仅仅是逆色的索贝尔边缘检测滤波器
GPUImageThresholdSketchFilter:与素描滤镜相同,只是边缘被阈值化而不是变为灰度
GPUImageToonFilter:使用索贝尔边缘检测在对象周围放置黑色边框,然后对图像中存在的颜色进行量化,以给图像带来卡通效果。
GPUImageSmoothToonFilter:这使用与GPUImageToonFilter类似的过程,只是在色调效果之前使用高斯模糊来平滑噪声。
GPUImageEmbossFilter:对图像应用浮雕效果
GPUImagePosterizeFilter:将颜色动态范围减少到指定的步骤数,使图像呈现出类似卡通的简单着色。
GPUImageSwirlFilter:在图像上创建涡流扭曲
GPUImageBulgeDistortionFilter:在图像上创建膨胀扭曲
GPUImagePinchDistortionFilter:创建图像的捏合扭曲
GPUImageStretchDistortionFilter:创建图像的拉伸扭曲
GPUImageSphereRefractionFilter:模拟通过玻璃球体的折射
GPUImageGlassSphereFilter:与GPUImageSphereRefractionFilter相同,只是图像没有反转,玻璃边缘有一点雾蒙蒙的感觉
GPUImageVignetteFilter:执行渐晕效果,使边缘图像褪色
GPUImageKuwaharaFilter:Kuwahara图像抽象,源于Kyprianidis等人在GPU Pro系列出版物《Anisotropic Kuwahara Filtering on the GPU》中的工作。这会生成类似油画的图像,但它非常计算密集,所以在iPad 2上渲染一帧可能需要几秒钟。这最好用于静态图像。
GPUImageKuwaharaRadius3Filter:Kuwahara过滤器的修改版,优化为仅在工作在三个像素的半径内工作
GPUImagePerlinNoiseFilter:生成充满Perlin噪声的图像
GPUImageCGAColorspaceFilter:模拟CGA显示器的颜色空间
GPUImageMosaicFilter:此过滤器接受一个输入瓦片集,瓦片必须按亮度顺序升序。它查看输入图像,并根据该瓦片的亮度用输入瓦片替换每个显示瓦片。最初的想法是复制在其他应用程序中看到的ASCII视频过滤器,但瓦片集可以是任何内容。
GPUImageJFAVoronoiFilter:生成Voronoi图,供后续阶段使用。
GPUImageVoronoiConsumerFilter:接受Voronoi图,并使用该图对传入的图像进行过滤。
您还可以像上面描述的那样,使用与C语言类似的OpenGL着色器语言轻松编写自己的自定义过滤器。
框架源代码中包含几个示例应用程序。大多数与iPhone和iPad类设备兼容。它们试图展示框架的各个方面,应在框架开发期间用作API的最佳例证。这些包括
在应用程序启动时,将捆绑的JPEG图像加载到应用程序中,对其应用过滤器,并将结果渲染到屏幕上。此外,此示例还展示了两种获取图像、过滤它并将其保存到磁盘的方法。
将马赛克过滤器应用于实时视频流,并使用UISlider控件调整实时视频的像素大小。
从磁盘加载电影文件,对其进行未锐化蒙版过滤,并将过滤后的结果重新编码为另一个电影文件。
从单个摄像机流中,使用实时滤镜填充了四个视图。一个是直接的摄像机视频,一个是预编程的棕褐色,另外两个是基于着色器程序的定制过滤器。
这展示了GPUImage中提供的每个过滤器。
这通过测试它与CPU密集型程序和Core Image的性能,用于测试整个框架的性能。涉及静态图像和视频的基准测试针对所有三个运行,结果在应用程序中显示。
这展示了GPUImage与OpenGL ES渲染交互的能力。从摄像机捕获帧,对它们应用棕褐色滤镜,然后将它们输入到一个可以通过手指旋转的立方体的纹理中。这个立方体然后被渲染到一个基于纹理的帧缓冲区对象上,然后这个纹理被再次喂给GPUImage,在渲染到屏幕之前对它应用马赛克滤镜。
换句话说,该应用程序的路径是摄像机 -> 棕褐色滤镜 -> 立方体 -> 马赛克滤镜 -> 显示。
我的ColorTracking示例版本之一来自 http://www.sunsetlakesoftware.com/2010/10/22/gpu-accelerated-video-processing-mac-and-ios,已移植到使用GPUImage,该应用程序使用场景中的颜色来跟踪实时摄像头馈送中的对象。您可以在四个视图之间切换,包括原始摄像头馈送、与白阈匹配的像素的摄像头馈送、经过处理的视频(位置编码为通过阈值测试的像素中的颜色)、以及最后带有跟踪所选颜色的点的实时视频馈送。轻触屏幕会更改要跟踪的颜色,以匹配手指下的像素颜色。在屏幕上轻触并拖动会使得颜色阈值更加宽松或紧张。这在第二个颜色阈值视图中尤为明显。
目前,最后一步中的颜色平均值处理都是在CPU上进行的,因此这部分非常慢。