布拉德·拉斯勒
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-bound 处理快 184 倍。在 iPhone 4S 上,GPUImage 在此场景中比 Core Image 快 4 倍,比 CPU-bound 处理快 102 倍。然而,对于更复杂的操作,如在大半径上的高斯模糊,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作为目标依赖项。最后,您还需要将GPUImage框架的Products文件夹中的libGPUImage.a库拖到您的应用程序的目标中,添加到“链接二进制与库”构建阶段。
GPUImage需要在您的应用程序中链接几个其他框架,因此您需要在应用程序的目标中添加以下作为链接库:
您还需要找到框架头文件,因此请在您的项目构建设置中将“头文件搜索路径”设置为从您的应用程序到GPUImage源目录中的框架/子目录的相对路径。请使此头文件搜索路径递归。
要使用应用程序中的GPUImage类,只需使用以下方式包含核心框架头文件:
#import "GPUImage.h"
作为注记:如果您在尝试使用Interface Builder构建界面时遇到“Interface Builder中未知的类GPUImageView”或类似错误,您可能需要将-ObjC添加到项目构建设置中的“其他链接器标志”。
另外,如果要将此功能部署到iOS 4.x,则当前版本的Xcode(4.3)要求您在最终应用程序中弱链接Core Video框架,或者如果您为上传到App Store或进行_outline_发行版本创建存档时看到消息“Symbol not found: _CVOpenGLESTextureCacheCreate”,则会出现崩溃。要执行此操作,请转到项目的“构建 phases”选项卡,展开“链接二进制与库”组合,然后在列表中找到CoreVideo.framework。将其在列表最右侧的设置从“Required”更改为“Optional”。
此外,此框架是支持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 支持使用完整的框架,例如 macOS,这简化了将此添加到您应用程序的过程。要将此添加到您的应用程序中,我建议将 .xcodeproj 项目文件拖放到您的应用程序项目中(就像在静态库目标中做的那样)。
对于您的应用程序,转到其目标构建设置并选择构建阶段选项卡。在目标依赖关系组中,为 iOS 添加 GPUImageFramework(而不是构建静态库的 GPUImage)或在 macOS 上添加 GPUImage。在“链接二进制文件与库”部分,添加 GPUImage.framework。
这将导致 GPUImage 以框架的形式构建。在 Xcode 6 中,它还会作为模块构建,这将允许您在 Swift 项目中使用它。按照上述设置,您只需使用
import GPUImage
将其引入。
然后,您需要添加一个新的拷贝文件构建阶段,将目标设置为 Frameworks,并将 GPUImage.framework 构建产品添加到该阶段。这样,框架就可以与应用程序捆绑在一起(否则,您将在执行时看到神秘的“dyld:Library not loaded:@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 分辨率下捕获。在这个界面为纵向模式的情况下捕获视频,其中横向左侧安装的摄像头需要在其视频帧显示之前将其旋转。然后,将一个自定义过滤器作为捕获的视频帧的目标,该过滤器使用来自 CustomShader.fsh 文件的代码。最后,使用能够显示通过此管道得到的过滤后的 OpenGL ES 纹理的 UIView 子类将过滤后的视频帧显示在屏幕上。
可以通过设置 GPUImageView 的 fillMode 属性来更改其填充模式,这样如果源视频的宽高比与视图的不同,视频将拉伸、居中显示黑色条带或缩放以填充。
对于混合过滤器和其他需要多个图像的过滤器,您可以创建多个输出并将单个过滤器作为这两个输出的目标。输出的添加顺序将影响输入图像的混合或其他处理的顺序。
此外,如果您想要启用麦克风音频捕获以录制到电影,您需要设置摄像头的 audioEncodingTarget 为您的电影编写器,如下所示
videoCamera.audioEncodingTarget = movieWriter;
要捕获和过滤静止照片,可以使用与过滤视频相似的过程。而不是使用 GPUImageVideoCamera,您可以使用 GPUImageStillCamera。
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 在过滤器中重复使用帧缓冲区以节省内存,因此如果需要保存过滤器 experiência para之后手动图像捕获,您需要提前告知。
对于希望应用于图像的单个过滤器,您可以简单地做以下操作
GPUImageSepiaFilter *stillImageFilter2 = [[GPUImageSepiaFilter alloc] init];
UIImage *quickFilteredImage = [stillImageFilter2 imageByFilteringImage:inputImage];
与 iOS(截至 iOS 5.0)上的 Core Image 相比,此框架的一个显著优点是可以编写您自己的自定义图像和视频处理过滤器。这些过滤器作为 OpenGL ES 2.0 片段着色器提供,使用类似于 C 的 OpenGL 着色语言编写。
自定义过滤器可以使用如下代码初始化
GPUImageFilter *customFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"CustomShader"];
其中使用的片段着色器扩展名为 .fsh。此外,如果您不希望在应用程序捆绑包中提供片段着色器,可以使用 -initWithFragmentShaderFromString: 初始化器将片段着色器作为字符串提供。
片段着色器为每个在该过滤阶段要渲染的像素进行计算。它们使用类似 C 的OpenGL 着色语言(GLSL),一种具有特定于 2-D 和 3-D 图形的添加的语言。以下是一个 sepia-tone 过滤器的片段着色器示例
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_tone,并将该像素颜色写出来用于下一阶段的处理管道。
当将片段着色器添加到您的 Xcode 项目时,需要记住的是 Xcode 会认为它们是源代码文件。为了解决问题,您需要手动将您的着色器从编译源代码阶段移动到复制捆绑资源阶段,以便将着色器包含在您的应用程序捆绑包中。
电影可以通过GPUImageMovie类加载到框架中,进行过滤后再使用GPUImageMovieWriter输出。GPUImageMovieWriter处理速度足够快,可以实时从iPhone 4的摄像头记录视频(分辨率640x480),因此可以直接将过滤后的视频源输入。目前,GPUImageMovieWriter足以在iPhone 4上以高达20 FPS的帧率录制720p视频,以及在iPhone 4S上以30 FPS的帧率录制720p和1080p视频(也包括新iPad)。
以下是如何加载一个示例电影,通过像素化滤镜处理后,将其作为480 x 640的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];
电影在使用前必须完成,如果在此过程中中断,记录将丢失。
通过使用GPUImageTextureOutput和GPUImageTextureInput类,GPUImage既可以导出也可以导入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:调整图像色调
GPUImageToneCurveFilter:根据每个颜色通道的双曲线曲线调整图像颜色
GPUImageHighlightShadowFilter:调整图像的阴影和高光
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 添加到您的应用程序包中。
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上进行短暂的平均计算。该滤镜的输出毫无意义,但需要设置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:索贝尔边缘检测,边缘以白色高亮显示
GPUImagePrewittEdgeDetectionFilter:普雷维特边缘检测,边缘以白色高亮显示
GPUImageThresholdEdgeDetectionFilter:执行索贝尔边缘检测,但应用阈值而不是提供渐变的强度值
GPUImageCannyEdgeDetectionFilter:使用完整的Canny过程来突出显示一像素宽的边缘
GPUImageHarrisCornerDetectionFilter:在输入图像上运行哈里斯角点检测算法,并生成一个图像,其中那些角点以白色像素显示,其余部分为黑色。可以设置cornersDetectedBlock,并在该回调中提供一个角落列表(在0..1的标准化X,Y坐标中),以便执行任何其他操作。
GPUImageNobleCornerDetectionFilter:在哈里斯角点检测器上运行Noble变体。它具有与哈里斯检测器类似的行为。
GPUImageShiTomasiCornerDetectionFilter:运行Shi-Tomasi特性检测器。它具有与哈里斯检测器类似的特性。
GPUImageNonMaximumSuppressionFilter:目前仅作为Harris角点检测过滤器的一部分使用,此滤镜将围绕每个像素采样一个1像素的方块,并确定该区域的中心像素的红色通道是否是该区域的最大值。如果是,则保留。如果不是,将所有颜色通道设置为0。
GPUImageXYDerivativeFilter:Harris角点检测过滤器内部的组件,此组件计算像素左右两侧像素的平方差以及像素上下两侧像素的平方差,并计算这两个差的乘积。
GPUImageCrosshairGenerator:在图像上绘制一系列十字线,通常用于识别机器视觉特征。它不接收标准的图像,而是一系列点(在它的-rendCrosshairsFromArray: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:这是一个基于高通滤波器的运动检测器。您设置运动检测块,在每个传入帧中,它将为您提供场景中任何检测到的运动的质心(以归一化的X,Y坐标表示),以及场景的运动强度。
GPUImageHoughTransformLineDetector:通过将Hough变换到平行坐标空间来检测图像中的线条。这种方法完全基于布拉格工业大学Graph@FIT研究小组开发的PC线过程,并在他们的出版物中描述:M. Dubská,J. Havel,和A. Herout。使用平行坐标和OpenGL实时检测线条。2011 SCCG会议论文集,斯洛伐克的布拉提斯拉瓦,第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,和A. Herout。PClines——使用平行坐标的线条检测。2011年IEEE计算机视觉和模式识别(CVPR)会议论文,第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:基于第二个图像的alpha通道,将第二个图像混合在第一个图像之上
GPUImageSourceOverBlendFilter:应用源覆盖混合两个图像
GPUImageColorBurnBlendFilter:应用两个图像的颜色燃烧混合
GPUImageColorDodgeBlendFilter:应用两个图像的颜色跳跃混合
GPUImageNormalBlendFilter:应用两个图像的正常混合
GPUImageColorBlendFilter:应用两个图像的颜色混合
GPUImageHueBlendFilter:应用两个图像的色调混合
GPUImageSaturationBlendFilter:应用两个图像的饱和度混合
GPUImageLuminosityBlendFilter:应用两个图像的亮度混合
GPUImageLinearBurnBlendFilter:应用两个图像的线性烧焦混合
GPUImagePoissonBlendFilter:应用两个图像的泊松混合
GPUImageMaskFilter:使用另一个图像来蒙蔽一个图像
GPUImagePixellateFilter:在一个图像或视频上应用像素化效果
GPUImagePolarPixellateFilter:基于极坐标而不是笛卡尔坐标来在图像或视频上应用像素化效果
GPUImagePolkaDotFilter:将图像分割成彩色圆点,在一个规则的网格中
GPUImageHalftoneFilter:将图像应用到半调效果中,类似于新闻印刷
GPUImageCrosshatchFilter:这会将图像转换为黑白交叉网纹图案
GPUImageSketchFilter:将视频转换为草图效果。这仅仅是Sobel边缘检测滤波器,颜色被反转
GPUImageThresholdSketchFilter:与草图滤镜相同,只是边缘被阈值化而不是变为灰度
GPUImageToonFilter:此滤镜使用Sobel边缘检测在对象周围放置黑色边框,然后将图像中存在的颜色量化,以给图像带来卡通风格的质感
GPUImageSmoothToonFilter:此滤镜使用与GPUImageToonFilter类似的过程,只是在色调效果之前添加高斯模糊来去除噪声。
GPUImageEmbossFilter:对图像应用浮雕效果
GPUImagePosterizeFilter:将颜色动态范围降低到指定的步数,从而使图像具有类似卡通的简单着色。
GPUImageSwirlFilter:在图像上创建漩涡扭曲。
GPUImageBulgeDistortionFilter:在图像上创建膨胀扭曲。
GPUImagePinchDistortionFilter:创建图像的挤压扭曲。
GPUImageStretchDistortionFilter:创建图像的拉伸扭曲。
GPUImageSphereRefractionFilter:模拟玻璃球体中的折射。
GPUImageGlassSphereFilter:与GPUImageSphereRefractionFilter相同,但图像不会倒置,并在玻璃边缘有一些轻度雾化。
GPUImageVignetteFilter:执行晕影效果,使图像边缘渐变。
GPUImageKuwaharaFilter:基于Kyprianidis等人发表的“Anisotropic Kuwahara Filtering on the GPU”(发表在GPU Pro系列的出版物中)的Kuwahara图像抽象化,受Kyprianidis等人的工作启发。这会产生类似油画的图像,但计算成本极高,因此在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中,在渲染到屏幕之前对其应用像素化滤镜。
换句话说,这个应用的路径是相机 -> 棕褐色滤镜 -> 立方体 -> 像素化滤镜 -> 显示。
这是我从 http://www.sunsetlakesoftware.com/2010/10/22/gpu-accelerated-video-processing-mac-and-ios 中的ColorTracking示例迁移而来,使用GPUImage,这个应用使用场景中的颜色来追踪来自实时摄像头流的物体。您可以在以下四个视图中切换:原始摄像头流、带有与颜色阈值匹配的像素的摄像头流(以白色显示)、编码为颜色且在像素内通过阈值测试的位置的视频处理结果,以及带有跟踪选定颜色的点的实时视频流。轻击屏幕会更改要跟踪的颜色以匹配手指下像素的颜色。在屏幕上轻击并拖动会使颜色阈值更加或更少宽容。这在对阈值化视图中最为明显。
当前,最后一轮中的颜色平均值处理仍然是CPU上的处理,因此这部分非常慢。