【问题标题】:Image analysis through GPU (with OpenGL ES) or CPU?通过 GPU(使用 OpenGL ES)或 CPU 进行图像分析?
【发布时间】:2012-08-16 15:19:38
【问题描述】:

我想分析来自 iPhone 摄像头的不断更新的图像馈送,以确定一般的“亮度系数”。含义:如果系数返回 0.0,则图像全黑,如果返回 1.0,则图像全白。当然,介于两者之间的所有值都是我最关心的(背景信息:我正在使用这个系数来计算片段着色器中某些混合效果的强度)。

所以我想知道是否应该在我的像素缓冲区上运行一个 for 循环并分析每帧 (30 fps) 的图像并将 coeff 作为统一发送到我的片段着色器,或者有没有办法在 OpenGL 中分析我的图像.如果是这样,我应该怎么做?

【问题讨论】:

标签: ios performance image-processing opengl-es


【解决方案1】:

还有更多的答案,每一个都有自己的长处和短处。

在 CPU 上,这相当简单:循环遍历像素,将它们相加,除以,仅此而已。这是一个五分钟的工作。良好的实现将需要几毫秒。

int i, sum = 0, count = width * height * channels;
for(i=0;i<count;i++)
    avg += buffer[i];
double avg = double(sum) / double(count);

在 GPU 上,它可能会快得多,但也有一些缺点:第一个是要完成所有工作所需的工作量。 GPUImage 框架将为您节省一些工作,但它也会添加大量代码。如果您只想对像素求和,那可能是一种浪费。第二个问题是,将像素发送到 GPU 可能比在 CPU 中汇总它们需要更多的时间。实际上,只有在您确实需要认真处理时,GPU 才会证明这项工作是合理的。

第三种选择,将 CPU 与库一起使用,其缺点是要添加大量代码来完成 10 行代码。但结果会很漂亮。同样,如果您也将 lib 用于其他任务,这也是合理的。这是 OpenCV 中的一个示例:

cv::Mat frame(buffer, width, height, channels, type);
double avgLuminance = cv::sum(frame)/(double(frame.total()*frame.channels()));

【讨论】:

  • 请注意,我正在研究基于 GPU 的全图像颜色平均实现(可以结合亮度转换来完成这里想要的操作)。迭代 CPU 上的每个像素是一个极其缓慢的过程,尽管 Accelerate 或更低级别的 NEON 指令可以在这里为您提供帮助。 Apple 在这里描述了一个基于 GPU 的迭代缩减过程:http.developer.nvidia.com/GPUGems3/gpugems3_ch26.html 应该比这快很多倍。我希望很快就会有这个功能。
  • 似乎对于您的需要,精确的总和是多余的。您可以在每个 10x10 块中仅使用 1 个像素。无需通过将图像发送到 OpenGL @30 fps 来破坏您糟糕的 iPhone 带宽。
  • 好的,我最终使用 OpenGL ES 完成了这个工作,我在这里描述了这个过程:stackoverflow.com/a/12169560/19679。使用 GPUImageLuminosity 类,您只需使用几行代码即可获得 iOS 相机的平均亮度。它最终比您上面描述的 CPU 迭代快 3 倍以上,所有图像上传和提取开销都被考虑在内。
【解决方案2】:

当然还有 OpenCL,它允许您使用 GPU 进行一般处理。

【讨论】:

  • 如目前所述,这是一个低劣的答案。这至少应该有一个指向 OpenCL 基础知识以及如何在 OpenGL 和 OpenCL 之间进行互操作的链接。
  • 另外,OpenCL 目前不适用于 iOS 设备。
猜你喜欢
  • 2011-06-25
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 2016-06-07
  • 2012-02-19
  • 1970-01-01
  • 2012-09-29
相关资源
最近更新 更多