如何在 iOS 平台上实现快速图像过滤器 [英] How to implement fast image filters on iOS platform

查看:17
本文介绍了如何在 iOS 平台上实现快速图像过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发 iOS 应用程序,用户可以在其中应用一组特定的照片过滤器.每个滤镜基本上都是一组带有特定参数的 Photoshop 动作.这些操作是:

I am working on iOS application where user can apply a certain set of photo filters. Each filter is basically set of Photoshop actions with a specific parameters. This actions are:

  • 级别调整
  • 亮度/对比度
  • 色相/饱和度
  • 单层和多层叠加层

我在我的代码中重复了所有这些操作,使用算术表达式循环遍历图像中的所有像素.但是当我在 iPhone 4 上运行我的应用程序时,每个过滤器需要大约 3-4 秒才能应用,这对于用户来说是相当长的等待时间.图像大小为 640 x 640 像素,这是我的视图大小的 2 倍,因为它显示在 Retina 显示屏上.我发现我的主要问题是每次需要调整伽玛时都会调用 pow() C 函数的级别修改.当然,我使用的是浮点数而不是双精度数,因为 ARMv6 和 ARMv7 使用双精度数很慢.尝试启用和禁用 Thumb 并得到相同的结果.

I've repeated all this actions in my code using arithmetic expressions looping through the all pixels in image. But when I run my app on iPhone 4, each filter takes about 3-4 sec to apply which is quite a few time for the user to wait. The image size is 640 x 640 px which is @2x of my view size because it's displayed on Retina display. I've found that my main problem is levels modifications which are calling the pow() C function each time I need to adjust the gamma. I am using floats not doubles of course because ARMv6 and ARMv7 are slow with doubles. Tried to enable and disable Thumb and got the same result.

我的应用程序中最简单的过滤器示例,但运行速度非常快(2 秒).其他过滤器包括更多的表达式和 pow() 调用,从而使它们变慢.

Example of the simplest filter in my app which is runs pretty fast though (2 secs). The other filters includes more expressions and pow() calls thus making them slow.

https://gist.github.com/1156760

我见过一些使用 Accelerate Framework vDSP 矩阵转换来快速修改图像的解决方案.我还看到了 OpenGL ES 解决方案.我不确定他们是否能够满足我的需求.但可能只是将我的一组更改转换为一些好的卷积矩阵?

I've seen some solutions which are using Accelerate Framework vDSP matrix transformations for fast image modifications. I've also seen OpenGL ES solutions. I am not sure that they are capable of my needs. But probably it's just a matter of translating my set of changes into some good convolution matrix?

任何建议都会有所帮助.

Any advice would be helpful.

谢谢,
安德烈.

Thanks,
Andrey.

推荐答案

对于示例代码中的过滤器,您可以使用查找表使其更快.我假设您的输入图像是每种颜色 8 位,并且您在将其传递给此函数之前将其转换为浮点数.对于每种颜色,这只给出 256 个可能的值,因此只有 256 个可能的输出值.您可以预先计算这些并将它们存储在一个数组中.这将避免 pow() 计算和边界检查,因为您可以将它们纳入预计算.

For the filter in your example code, you could use a lookup table to make it much faster. I assume your input image is 8 bits per color and you are converting it to float before passing it to this function. For each color, this only gives 256 possible values and therefore only 256 possible output values. You could precompute these and store them in an array. This would avoid the pow() calculation and the bounds checking since you could factor them into the precomputation.

看起来像这样:

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]];

在这种情况下,您只需执行 pow() 256 次,而不是 3*640*640 次.您还可以避免由于在主图像循环中检查边界而导致的分支,这可能会很昂贵.您也不必转换为浮动.

In this case, you only have to perform pow() 256 times instead of 3*640*640 times. You would also avoid the branching caused by the bounds checking in your main image loop which can be costly. You would not have to convert to float either.

更快的方法可能是在程序之外预先计算表格,然后将 256 个系数放入代码中.

Even a faster way may be to precompute the table outside the program and just put the 256 coefficients in the code.

您在此处列出的所有操作都不需要卷积甚至矩阵乘法.它们都是逐像素操作,这意味着每个输出像素只依赖于单个对应的输入像素.对于多个输入像素影响单个输出像素的模糊或锐化等操作,您需要考虑卷积.

None of the operations you have listed there should require a convolution or even a matrix multiply. They are all pixel-wise operations, meaning that each output pixel only depends on the single corresponding input pixel. You would need to consider convolution for operations like blurring or sharpening where multiple input pixels affect a single output pixel.

这篇关于如何在 iOS 平台上实现快速图像过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆