【问题标题】:Modifying an image with OpenGL?用OpenGL修改图像?
【发布时间】:2010-04-29 10:09:06
【问题描述】:

我有一个设备来获取 X 射线图像。由于一些技术限制,检测器由异质像素大小和多个倾斜和部分重叠的瓦片组成。图像因此失真。探测器的几何形状是精确已知的。

我需要一个函数将这些扭曲的图像转换为像素大小均匀的平面图像。我已经通过 CPU 完成了这项工作,但我想尝试使用 OpenGL 以便携式方式使用 GPU。

我没有使用 OpenGL 编程的经验,而且我可以在网上找到的大部分信息对于此用途毫无用处。我应该如何进行?我该怎么做呢 ?

图像大小为 560x860 像素,我们有 720 个图像批次需要处理。我在 Ubuntu 上。

【问题讨论】:

  • 您的目标是哪个 OpenGL 版本?
  • 这听起来有点像微软的 PhotoSynth“东西”。 photosynth.net

标签: c++ opengl


【解决方案1】:

OpenGL 用于渲染多边形。您可能可以进行多次传递并使用着色器来获得您想要的结果,但您最好在 OpenCL 中重新编写算法。如果没有可用的图形加速卡,那么您将拥有一些可移植的东西,甚至可以使用多核 CPU。

【讨论】:

  • OpenGL 比 OpenCL 更便携,尤其是在 Ubuntu 上。
  • OpenCL 在 Ubuntu 上完美运行。我在 Ubuntu 9.04-10.04 和 NVIDIA 的 OpenCL SDK 上做了很多工作。
  • @danvil 你如何安装驱动程序?我“手动”安装了驱动程序,但每次更新内核时,我发现自己在 VGA 中,必须重新安装驱动程序。我在工作 PC 上执行此操作,但这在生产机器上是不可接受的。
  • 驱动内核模块必须重新编译以匹配新的内核版本。对于其他一些模块,这已经自动完成。必须手动添加 nvidia 模块。 (这是重新安装驱动程序的唯一必要步骤)。
  • 这就是我不能在生产 PC 上使用它的原因。每次更新内核时,用户都会看到 VGA 屏幕。这就是我寻找 OpenGL 解决方案的原因,但我什至不确定是否可以在没有专有驱动程序的情况下使用 OpenGL。
【解决方案2】:

这听起来像是 CUDA,或者更普遍的 GPGPU 问题,而不是 OpenGL。

如果您已经有 C 或 C++ 代码来执行此操作,那么 CUDA 应该只是弄清楚您想在 GPU 上使用的类型以及如何平铺算法。

【讨论】:

  • 我已经在 CUDA 中编程,但正在寻找 OpenGL 应该能够提供的可移植解决方案。另一件事是 Ubuntu 对 CUDA 不友好。
  • CUDA 在 Ubuntu 上完美运行。我对 Ubuntu 9.04/9.10/10.04 和 NVIDIA 的 CUDA SDK 做了很多工作。当然,CUDA 仅限于 Nvidia 硬件......
  • 是的... CUDA 和 OpenCL 在 Ubuntu 上运行良好。 OpenCL 可能是更好的主意,它更便携。
  • 如何安装 OpenCL 兼容的驱动程序?我在生产计算机上有一个 NVIDIA 8800GT,并且可以获得更强大的卡(即 GTX285)。
  • 只要确保您拥有最新版本的视频驱动程序即可。 OpenCL 和 CUDA 将自己安装在所有库中,但它们使用标准的 NVidia 专有视频驱动程序。 8800GT 是一个非常强大的 GPU,它的计算能力大约是 CPU 的 15 倍,即使它是四核。
【解决方案3】:

如果您想使用 OpengGL 执行此操作,您通常可以通过将当前数据作为纹理提供,并编写一个片段着色器来处理该数据,并将其设置为渲染到纹理。输出纹理完全渲染后,您可以将其取回 CPU 并将其作为文件写入。

恐怕很难在不知道更多关于你在做什么的情况下做一个非常笼统的整体流程草图 - 但是如果(如你所说)你已经用 CUDA 完成了这个,你显然已经对大部分细节有了相当的了解。

【讨论】:

  • 这就是我想做的。使用示例代码进行更详细的解释将非常有帮助。至少是我可以遵循的完整功能代码示例教程的一个很好的指针。
【解决方案4】:

您在这里问的本质是“我如何使用 GPU 来解决这个问题?”

现代 GPU 本质上是线性代数引擎,因此您的第一步是将您的问题定义为一个矩阵,该矩阵将输入坐标 转换为其在同质空间中的输出:

例如,您可以将 x 缩放 ½、y 缩放 1.2 以及向上和向左平移两个单位的变换表示为:

您也可以对rotationshear 等进行类似的转换。

将变换表示为矩阵向量乘法后,您只需将源数据加载到纹理中,将变换指定为projection matrix,然后将其渲染为结果。 GPU 执行每个像素的乘法运算。 (你也可以编写着色器等,做更复杂的数学运算,考虑多个向量和矩阵等等,但这是基本思想。)

也就是说,一旦您将问题表达为线性变换,您也可以通过利用 SIMD 或many linear algebra libraries 之一使其在 CPU 上运行得更快。除非您需要实时性能或有大量数据要处理,否则使用 CUDA/GL/着色器等可能比它的严格价值更麻烦,因为在初始化库、设置渲染时涉及一些笨拙的机器目标,学习图形开发细节等。

只需将您的内部循环从临时数学转换为优化良好的线性代数子例程,就可以为您在 CPU 上提供足够的性能提升,就像您在那里完成的那样。

【讨论】:

  • 我开始认为您使用 CPU 而不是 GPU 的建议可能是正确的。对于我的用例,我必须对许多图像应用完全相同的校正。因此可以预先计算映射函数参数,以便每个像素值都可以通过输入图像像素的简单加权和来计算。我已经实现了这样的程序。
【解决方案5】:

您可能会发现this tutorial 很有用(它有点旧,但请注意它在 Cg 部分之后确实包含一些 OpenGL 2.x GLSL)。我不相信 GLSL 中的图像处理有任何捷径,如果那是您正在寻找的……您确实需要了解很多 3D 光栅化方面和历史包袱才能有效地使用它,尽管一旦您这样做了设置好输入和输出框架后,您可以忘记这一点,并相对轻松地在着色器代码中使用自己的算法。

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

【讨论】:

  • 好的。我会看看新版本的 Ubuntu 是否在使用启用 CUDA 的驱动程序更简单方面取得了任何进展。请注意,然后我将使用纹理来存储输入像素的线性组合的权重。 CUDA 确实令人印象深刻。我的断层重建程序比 GTX280 上的 CPU 版本快 600 倍!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-20
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多