代码之家  ›  专栏  ›  技术社区  ›  Kyle Simek

GPU中的图像强度总和

  •  8
  • Kyle Simek  · 技术社区  · 14 年前

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

    有没有一种方法可以一蹴而就?或者我应该分解并使用CUDA/OpenCL吗?

    3 回复  |  直到 11 年前
        1
  •  4
  •   Kyle Simek    11 年前

    求和运算是“reduction”的一个特例,这是CUDA和OpenCL库中的标准运算。网站上有一个不错的文字说明 cuda demos page Thrust CUDPP 只是两个提供缩减的库的例子。我对OpenCL不太熟悉,但是 CLPP 似乎是一个很好的图书馆,提供减少。只需将颜色缓冲区复制到OpenGL像素缓冲区对象,并使用适当的OpenGL互操作性调用,使该像素缓冲区的内存可以在CUDA/OpenCL中访问。

    如果必须使用openglapi(正如最初的问题所要求的那样)来完成,那么解决方案是渲染到纹理,创建纹理的mipmap,然后读入1x1纹理。你必须设置正确的过滤(双线性是适当的,我认为),但它应该得到接近正确答案,模精度误差。

        2
  •  1
  •   Pater Cuilus    14 年前

    我的直觉告诉我尝试用OpenCL实现。通过将图像分解为定制的数据块,然后并行求和,可以优化图像大小和图形硬件。可能真的很快。

    片段着色器对于卷积非常有用,但是这个结果通常被写入gl\u FragColor,所以它是有意义的。最终你将不得不在纹理中的每个像素上循环,并对结果求和,然后在主程序中读回。生成图像统计信息可能不是片段着色器的设计目的,也不清楚主要的性能增益是什么,因为它不能保证特定的缓冲区位于GPU内存中。

        3
  •  1
  •   dronus    13 年前

    如果你想坚持GLSL,就不需要CUDA。就像在这里提到的CUDA解决方案中,它可以在一个片段着色器中完成。但是,您需要记录(解析)draw调用。 GL_FLOAT 亮度纹理(如果可用),以获得更精确的总和。使用 glViewport 在每个阶段中四分之一渲染区域。结果最终出现在帧缓冲区的左上角像素处。