Dan*_*ell 2 cocoa core-image cifilter
我目前正在 CPU 上运行代码,该代码对灰度NSImage 的列和行进行求和(即只有 1 个 samplePerPixel)。我想我会尝试将代码移动到 GPU(如果可能)。我发现了一个 CoreImage 过滤器CIRowAverage和CIColumnAverage,它们看起来很相似。
在关于编写自定义核心图像过滤器的 Apple Docs 中,他们指出,
请记住,您的代码无法逐个像素地积累知识。编写代码时的一个好策略是将尽可能多的不变计算从实际内核中移出,并将其放置在过滤器的 Objective-C 部分中。
这暗示可能无法使用滤波器内核对像素求和。如果是这样,上述函数如何设法获得一个区域的平均值?
所以我的问题是,实现对图像的行或列求和以获得像素总值的最佳方法是什么。我应该坚持使用CPU吗?
核心图像过滤器通过一系列减少来执行这种平均。团队中的一位前工程师在此 GPU Gems 章节(在第 26.2.2 节“查找质心”下)描述了如何为 CIAreaAverage 过滤器完成此操作。
我在这里通过减少我的答案来谈论类似的平均。我在 iOS 上需要这种功能,所以我编写了一个片段着色器,将图像在水平和垂直维度上缩小了四倍,在像素之间进行采样,以便在每一步将 16 个像素平均为一个。一旦图像缩小到足够小的尺寸,剩余的像素被读出并平均以产生单个最终值。
这种减少在 GPU 上执行的速度仍然非常快,我能够在 iPhone 4 上在大约 6 毫秒内从 640x480 视频帧中提取平均颜色。当然,您将有更多的马力可以玩在 Mac 上。
您可以采取类似的方法,通过在每一步只向一个方向或另一个方向减少。如果您有兴趣获得像素值的总和,则需要注意 GPU 上使用的像素格式的精度限制。默认情况下,RGBA 颜色值存储为 8 位值,但某些 GPU 上的 OpenGL (ES) 扩展可以让您渲染为 16 位甚至 32 位浮点纹理,从而扩展您的动态范围。我不确定,但我相信 Core Image 允许您在 Mac 上使用 32 位浮点组件。