使用OpenGL修改图像?

5
我有一台用于获取X射线图像的设备。由于一些技术限制,探测器由异质像素大小和多个倾斜且部分重叠的瓷砖组成,因此图像会被扭曲。但是,探测器几何形状已经精确确定。
我需要一个函数将这些扭曲的图像转换为具有均匀像素大小的平面图像。我已经通过CPU完成了这项工作,但我想尝试使用OpenGL来以便携的方式使用GPU进行处理。
对于OpenGL编程,我没有任何经验,并且我在网络上找到的大部分信息都对此无帮助。我该如何继续呢?我该如何做到这一点呢?
图像大小为560 x 860像素,我们有720个图像批次需要处理。我使用的操作系统是Ubuntu。

你的OpenGL版本是哪个? - Danvil
这听起来有点像微软的PhotoSynth“东西”。http://photosynth.net/ - epatel
5个回答

4

OpenGL用于渲染多边形。您可能需要多次通过使用着色器来实现所需效果,但最好还是在OpenCL中重新编写算法。这样的好处是,即使没有图形加速卡,它也可以使用多核CPU,并且具有可移植性。


OpenGL比OpenCL更易于移植,尤其是在Ubuntu上。 - chmike
OpenCL在Ubuntu上运行得非常完美。我已经在Ubuntu 9.04-10.04和NVIDIA的OpenCL SDK上做了很多工作。 - Danvil
@danvil 你如何安装驱动程序?我是“手动”安装的驱动程序,但每次内核更新时,我都会发现自己处于VGA状态,并且不得不重新安装驱动程序。我在我的工作电脑上这样做,但在生产环境中这是不可接受的。 - chmike
驱动内核模块必须重新编译以匹配新的内核版本。对于其他一些模块,这已经自动完成了。Nvidia模块必须手动添加。(这是驱动程序重新安装中唯一必要的步骤)。 - Danvil
这就是我不能在生产电脑上使用它的原因。每次内核更新时,用户都会得到VGA屏幕。这就是为什么我寻找了一个OpenGL解决方案,但我甚至不确定是否可以在没有专有驱动程序的情况下使用OpenGL。 - chmike
我终于在这里找到了这个页面http://www.sucka.net/2010/04/how-to-install-nvidia-video-driver-in-10-04-lucid-lynx/,它解释了如何安装驱动程序。有一个小错误,请看我在页面下面的评论,但它可以工作。现在我将尝试CUDA和OpenCL。 - chmike

2
与OpenGL不同,这似乎是一个CUDA问题,或者更普遍地说,是GPGPU问题。
如果您已经有了用于执行此操作的C或C ++代码,则CUDA应该只需确定要在GPU上使用的类型以及如何将算法分块即可。

我已经使用CUDA编程,但是正在寻找OpenGL应该能够提供的可移植解决方案。另一件事是Ubuntu不友好地支持CUDA。 - chmike
CUDA在Ubuntu上运行得非常完美。我已经在Ubuntu 9.04/9.10/10.04和NVIDIA的CUDA SDK上做了很多工作。当然,CUDA只限于Nvidia硬件... - Danvil
是的... CUDA和OpenCL在Ubuntu上运行良好。OpenCL可能是更好的选择,因为它更具可移植性。 - Andrew McGregor
你如何安装OpenCL兼容的驱动程序?我在生产计算机上有一张NVIDIA 8800GT显卡,可以换成更强大的显卡(例如GTX285)。 - chmike
请确保您拥有最新版本的视频驱动程序。 OpenCL和CUDA会在整个库中自行安装,但它们可以与标准的NVidia专有视频驱动程序一起使用。 8800GT是一款相当强大的GPU,其计算能力大约比您的CPU高15倍,即使它是四核心的。 - Andrew McGregor

1

如果您想使用OpengGL完成这个任务,通常会将当前数据作为纹理提供,并编写一个处理该数据的片段着色器,并设置它以渲染到纹理。一旦输出纹理完全渲染,您就可以将其检索回CPU并将其作为文件写出。

恐怕在不知道更多关于您正在执行的操作的情况下,很难做更详细的概述 - 但是如果(如您所说),您已经使用CUDA完成了这项任务,那么您显然已经对大部分细节有了相当好的了解。


这就是我想要做的。如果有一个更详细的解释和示例代码,那将非常有帮助。至少能够提供一个指向教程或完整可用的代码示例的好的指引。 - chmike

1
你所询问的本质是“如何使用GPU来解决这个问题?”
现代GPU基本上是线性代数引擎,因此你的第一步是将问题定义为将输入坐标转换为其在齐次空间中的输出的矩阵:

alt text

例如,要表示将 x 缩放一半、将 y 缩放 1.2 倍以及向上和向左平移两个单位的转换,您可以这样写:

alt text

而且,你可以对旋转剪切等进行类似的转换。

一旦你将变换表示为矩阵-向量乘法,你所需要做的就是将源数据加载到纹理中,将你的变换指定为投影矩阵,然后将其渲染到结果中。GPU每个像素执行乘法运算。(你还可以编写更复杂的着色器等,涉及多个向量和矩阵等等,但这是基本思路。)

话虽如此,一旦您将问题表达为线性变换,您也可以通过利用例如SIMD或其中一个许多线性代数 在CPU上使其运行得更快。除非您需要实时性能或需要处理真正巨大的数据量,否则使用CUDA/GL/shaders等可能会比它的价值更麻烦,因为在初始化库、设置渲染目标、学习图形开发的细节等方面涉及到一些笨拙的机制。

仅仅将您的内部循环从特定的数学转换为经过优化的线性代数子程序可能会给您足够的CPU性能提升,以便您可以在那里完成。


我开始认为你的建议使用CPU而不是GPU可能是正确的。对于我的用例,我必须对许多图像应用完全相同的校正。因此,映射函数参数可以预先计算,以便每个像素值可以计算输入图像像素的简单加权和。我已经实现了这样一个程序。 - chmike

0

你可能会发现这个教程有用(它有点旧,但请注意,在Cg部分之后它确实包含一些OpenGL 2.x GLSL)。如果你正在寻找图像处理的捷径,我不认为GLSL有任何捷径...你需要了解很多3D光栅化方面和历史负担才能有效地使用它,尽管一旦你建立了输入和输出的框架,你就可以忘记这些并且在着色器代码中轻松地玩弄自己的算法。

作为一个做了多年这种事情的人(最初使用Direct3D着色器,但最近更多地使用CUDA),我必须说我完全同意这里推荐CUDA/OpenCL的帖子。它使生活变得简单,并且通常运行得更快。我必须非常绝望才会回到非图形算法的图形API实现。


好的。我会看看新版本的Ubuntu是否有进展,使使用CUDA启用的驱动程序更简单。请注意,我将使用纹理来存储输入像素线性组合的权重。 CUDA确实令人印象深刻。我的层析重建程序在GTX280上比CPU版本快了600倍! - chmike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接