GPU中的图像强度总和

时间:2010-09-15 22:26:11

标签: opengl image-processing gpu glsl

我有一个应用程序,我需要拍摄大约100万张图像的平均图像强度。它“感觉”就像GPU片段着色器的工作,但片段着色器用于每像素本地计算,而图像平均是全局操作。

我考虑的一种方法是将图像加载到纹理中,应用2x2框模糊,将结果加载回N / 2 x N / 2纹理并重复直到输出为1x1。但是,这将采用着色器的log n应用程序。

有没有办法一次性完成?或者我应该分解并使用CUDA / OpenCL?

3 个答案:

答案 0 :(得分:4)

求和操作是“简化”的一个特定情况,这是CUDA和OpenCL库中的标准操作。 cuda demos page上提供了一个很好的文章。在CUDA中,ThrustCUDPP只是提供缩减的​​两个库的示例。我对OpenCL不太熟悉,但CLPP似乎是一个提供减少的好库。只需将颜色缓冲区复制到OpenGL像素缓冲区对象,并使用适当的OpenGL互操作性调用,以便在CUDA / OpenCL中访问该像素缓冲区的内存。

如果必须使用opengl API(需要原始问题)来完成,解决方案是渲染到纹理,创建纹理的mipmap,并读入1x1纹理。你必须设置正确的过滤(我认为双线性是合适的),但它应该接近正确的答案,模数精度误差。

答案 1 :(得分:1)

我的直觉告诉我尝试在OpenCL中实施。您可以通过将图像分解为定制的数据块然后并行求和来优化图像大小和图形硬件。可能非常快。

片段着色器非常适合卷积,但结果通常写入gl_FragColor,因此它是有意义的。最终,您必须遍历纹理中的每个像素并对结果求和,然后在主程序中读回。生成图像统计信息可能不是片段着色器的设计目的,并且不清楚是否需要获得主要的性能增益,因为它不能保证特定的缓冲区位于GPU内存中。

听起来您可能正在将此算法应用于实时运动检测场景或其他一些自动功能检测应用程序。从像素样本而不是整个图像计算一些统计数据可能会更快,然后构建机器学习分类器。

无论如何,祝你好运!

答案 2 :(得分:1)

如果你想坚持使用GLSL,它不需要CUDA。就像在这里提到的CUDA解决方案一样,它可以在片段着色器中向前进行。但是,您需要关于日志(分辨率)绘制调用。 只需设置一个着色器,从原始图像中获取2x2像素样本,然后输出它们的平均总和。结果是两个轴都具有半分辨率的图像。重复此操作直到图像为1x1像素。 一些注意事项:使用GL_FLOAT亮度纹理(如果可用),以获得更精确的总和。使用glViewport对每个阶段中的渲染区域进行四分之一。然后结果会出现在帧缓冲区的左上角像素中。