And*_*nih 10 opengl-es image-processing matrix-multiplication ios accelerate-framework
我正在开发iOS应用程序,用户可以在其中应用一组特定的照片过滤器.每个过滤器基本上都是具有特定参数的Photoshop动作集.这些行动是:
我在代码中重复了所有这些操作,使用循环遍历图像中所有像素的算术表达式.但是当我在iPhone 4上运行我的应用程序时,每个过滤器需要大约3-4秒才能应用,这是用户等待的相当多的时间.图像尺寸为640 x 640像素,这是我视图尺寸的2倍,因为它显示在Retina显示屏上.我发现我的主要问题是每次需要调整gamma时调用pow()C函数的级别修改.我当然使用的浮动不是双打,因为ARMv6和ARMv7的双打速度很慢.尝试启用和禁用Thumb并获得相同的结果.
我的应用程序中最简单的过滤器示例,运行速度非常快(2秒).其他过滤器包含更多表达式和pow()调用,从而使它们变慢.
https://gist.github.com/1156760
我见过一些使用Accelerate Framework vDSP矩阵变换进行快速图像修改的解决方案.我也看过OpenGL ES解决方案.我不确定他们能满足我的需求.但可能只是将我的一组变化转换为一些好的卷积矩阵?
任何意见将是有益的.
谢谢,
安德烈.
Jas*_*n B 13
对于示例代码中的过滤器,您可以使用查找表使其更快.我假设您的输入图像是每种颜色8位,并且在将其传递给此函数之前将其转换为浮点数.对于每种颜色,这仅提供256个可能的值,因此只有256个可能的输出值.您可以预先计算这些并将它们存储在一个数组中.这将避免pow()计算和边界检查,因为您可以将它们纳入预计算.
它看起来像这样:
unsigned char table[256];
for(int i=0; i<256; i++) {
float tmp = pow((float)i/255.0f, 1.3f) * 255.0;
table[i] = tmp > 255 ? 255 : (unsigned char)tmp;
}
for(int i=0; i<length; ++i)
m_OriginalPixelBuf[i] = table[m_OriginalPixelBuf[i]];
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您只需要执行pow()256次而不是3*640*640次.您还可以避免由主图像循环中的边界检查导致的分支,这可能是昂贵的.您也不必转换为浮动.
甚至更快的方法可能是在程序外预先计算表,并将256个系数放在代码中.
你在那里列出的所有操作都不需要卷积甚至是矩阵乘法.它们都是逐像素操作,这意味着每个输出像素仅取决于单个相应的输入像素.对于多个输入像素影响单个输出像素的模糊或锐化等操作,您需要考虑卷积.
Bra*_*son 10
如果您正在寻找绝对最快的方法,那么您将需要使用GPU来处理.它是为大规模并行操作而构建的,例如对单个像素进行颜色调整.
正如我在其他答案中提到的,当使用OpenGL ES而不是CPU运行图像处理操作时,我测得性能提高了14X-28X.您可以使用Accelerate框架来更快地进行CPU图像处理(我相信Apple声称可以在这里进行大约4-5倍的提升),但它不会像OpenGL ES那样快.然而,它可以更容易实现,这就是为什么我有时在OpenGL ES上使用Accelerate.
iOS 5.0还带来了桌面上的Core Image,它为您提供了围绕这些GPU上图像调整的精美包装.但是,在直接使用OpenGL ES 2.0着色器时,您没有iOS Core Image实现的一些限制.
我在这里的文章中提供了一个OpenGL ES 2.0着色器图像过滤器的示例.进行这种处理最困难的部分是设置OpenGL ES脚手架. 在那里使用我的示例应用程序,您应该能够提取该设置代码并使用它来应用您自己的过滤器.为了简化这一过程,我创建了一个名为GPUImage的开源框架,它可以为您处理所有OpenGL ES交互.它几乎包含了您在上面列出的每个过滤器,并且大多数在iPhone 4上的640x480帧视频下运行时间不到2.5毫秒,因此它们比在CPU上处理的任何内容都要快得多.
| 归档时间: |
|
| 查看次数: |
11954 次 |
| 最近记录: |