iOS图像处理管道,与核心图像库相比,GPUImage仍然强大吗?

5

我是一名新手,正在开发iOS上的图像处理应用程序。我对OpenCV有很多经验,但在iOS甚至OSX上,所有东西都是新的。

因此,我发现常规图像处理工作主要使用核心图像库和GPUImage库。我对于在iOS平台上应该选择哪一个感到好奇?我看到在iPhone 6上的iOS 8上进行了一些测试,结果表明Core Image比GPUImage更快。

实际上,我正在寻找整个图像处理开发的解决方案,

  1. 使用什么语言?Swift、Objective-C或Clang和C++?
  2. 使用什么库?GPUImage还是Core Image还是OpenCV还是GEGL?
  3. 是否有示例应用程序?

我的目标是开发一些高级颜色校正功能,并希望尽可能地提高速度,这样将来我可以将图像处理变为视频处理而不会出现太多问题。

谢谢

3个回答

16
我是GPUImage的作者,因此你可能会更加重视我的话。我在这里提供了对该框架与Core Image的设计思路进行详细描述,但我可以再次重申。

基本上,我设计GPUImage是为了方便地包装OpenGL / OpenGL ES图像处理。它建立在iOS上没有Core Image的时候,即使Core Image推出后,它也缺乏自定义内核,并且存在一些性能问题。

与此同时,Core Image团队在性能方面做出了令人印象深刻的工作,导致现在Core Image在几个领域略微优于GPUImage。我仍然在其他方面击败他们,但比以前要接近得多。

我认为决定取决于您为应用程序赋予的价值。整个GPUImage源代码都可供您使用,因此您可以自定义或修复任何部分。您可以查看任何操作运行的实际情况。管道设计中的灵活性让我尝试了目前无法在Core Image中完成的复杂操作。

Core Image是iOS和OS X的标配。它被广泛使用(有大量的代码可用),性能高,易于设置,并且(最新的iOS版本)可以通过自定义内核进行扩展。它可以进行CPU端处理,除了GPU加速处理外,还可以让您在后台处理图像(尽管在iOS 8中应该能够在后台进行有限的OpenGL ES工作)。我在编写GPUImage之前一直使用Core Image。

要获取示例应用程序,请下载GPUImage源代码并查看examples/目录。您将找到框架的每个方面的示例,适用于Mac和iOS,以及Objective-C和Swift。我特别推荐在iOS设备上构建和运行FilterShowcase示例,因为它演示了每个滤镜从实时视频中得出的结果。这是一件有趣的事情。

关于语言选择,如果你追求视频/图像处理的性能,语言几乎不会有太大的影响。性能瓶颈将不是由于语言,而是由于GPU上的着色器性能以及图像和视频上传/下载速度造成的。
GPUImage用Objective-C编写,但它仍然可以在支持的最古老的iOS设备上以60 FPS处理视频帧。通过对代码进行分析,很少发现消息发送开销或内存分配(与C或C ++相比,这种语言中最慢的地方)是显著的。如果这些操作在CPU上执行,情况可能会有所不同,但这完全是由GPU驱动的。
使用最适合和最容易满足开发需求的语言。Core Image和GPUImage都与Swift、Objective-C++或Objective-C兼容。OpenCV可能需要从Swift中使用一个shim,但如果你考虑性能,OpenCV可能并不是一个很好的选择。它的速度要比Core Image或GPUImage慢得多。
个人而言,为了使用方便,使用Swift可能更加合适,因为我可以仅用23行非空白代码编写整个视频过滤应用程序。

我很高兴你能亲自回答 : )。我读了你关于转换到Swift的文章,我想我会认真考虑使用Swift + GPUImage管道。 - tomriddle_1234
我可以问一下,您是否认为节点图架构是创建图像处理移动应用程序的可访问方式?我想尝试这种架构,但它非常复杂,所以我希望得到建议。 - tomriddle_1234
@tomriddle_1234 - 我知道有几个应用程序使用这种架构来过滤和处理视频和图像,其中一些基于GPUImage。然而,它们是由大型、资金充足的团队设计的,因此对于个人开发者来说并不是特别容易实现的事情。如果需要的话,您可以从更简单的设计开始构建。 - Brad Larson

2
我刚刚开源了VideoShader,它可以让你使用基于JSON的脚本语言描述视频处理管道。例如,“卡通滤镜”可以用12行代码来描述。请查看以下链接以获取更多信息:https://github.com/snakajima/videoshader
{
    "title":"Cartoon I",
    "pipeline":[
        { "filter":"boxblur", "ui":{ "primary":["radius"] }, "attr":{"radius":2.0} },
        { "control":"fork" },
        { "filter":"boxblur", "attr":{"radius":2.0} },
        { "filter":"toone", "ui":{ "hidden":["weight"] } },
        { "control":"swap" },
        { "filter":"sobel" },
        { "filter":"canny_edge", "attr":{ "threshold":0.19, "thin":0.50 } },
        { "filter":"anti_alias" },
        { "blender":"alpha" }
    ]
}

它会在运行时将此脚本编译为GLSL(GPU的OpenGL着色语言),并且所有的像素操作都将在GPU上完成。


你认为在C++中创建这样的库并为iOS和Android编写一个包装器容易吗? - Rafael Sanches

1

谢谢!使用纯OpenGL似乎有些过度了。我认为我可以使用一些建立在OpenGL之上的东西,因为我这里没有使用任何3D功能。 - tomriddle_1234
你可以使用OpenGL+GPUImage,如http://indieambitions.com/idevblogaday/learning-opengl-gpuimage/中所述。OpenGL不仅适用于3D,还可以通过使用OpenGL来提高图像处理的速度。 - Dipen Patel
2
GPUImage是基于OpenGL / OpenGL ES构建的,因此它不是真正的“二选一”。这就是框架的全部意义所在。它在这样做时引入了可忽略的开销,因此在图像处理方面自己编写OpenGL / OpenGL ES渲染代码并没有太大的优势。 - Brad Larson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接