【问题标题】:Fastest way to calculate OpenGL texture similarity/distance?计算OpenGL纹理相似度/距离的最快方法?
【发布时间】:2011-12-30 02:24:04
【问题描述】:

这是我所拥有的:

  1. 我从磁盘加载纹理,比如 256x256,比如企鹅图片
  2. 我创建了另一个具有相同尺寸的纹理并在其上绘制了一些东西

我想尽可能快地找到两个 openGL 纹理之间的距离(距离函数的准确性是最不重要的)。

实际上,它们可能一开始就不是纹理。 我不妨将帧缓冲区的一个区域与加载的纹理进行比较,或者做一些其他的“魔术”。

如何做到这一点超快?

【问题讨论】:

  • 如何定义两张图片之间的“距离”?
  • 这样说:距离 = (sR-dR)*(sR-dR)+(sG-dG)*(sG-dG)+(sB-dB)*(sB-dB)

标签: opengl image-processing graphics computer-vision


【解决方案1】:

这实际上与 OpenGL 无关。 OpenGL 只是一个 3D 光栅化“驱动程序”。

主要思想是获得距离/相似度算法,这是一项棘手的任务。一开始你可以做一个Root Mean Square Deviation 算法。它会告诉你像素值有多远。

当您在 CPU 上实现它时,您可以根据需要对它进行基准测试,并可能转换为 OpenCL。我不认为将“企鹅”加载到 GPU 只是为了将其与您准备的其他形状进行比较,这本身就是一个超快速的过程。

下一个问题尽量具体一点,避免出现“我有一个很好的显微镜,我怎么能用它超快击中钉子?”的态度?

【讨论】:

  • +1 虽然应该注意 RMSD 非常适用于“噪声”差异的技术图形,但不太适合例如两张在其他方面完全相同的图片,它们偏移了几个像素,并且有时会为 视觉上 完全相同的图片提供不合理的错误值。尽管如此,这可能是最好、最简单和最快的解决方案(除了可能生成 mipmap 并在 mip 级别 3 或 4 处进行差异求和)。这也真的取决于一个人想要什么。
  • 我会说它与 OpenGL 有很大关系,因为最大的性能损失来自 glReadPixels 并将每个像素的像素与 CPU 上的源图像进行比较。我很确定,如果这种相似度计算以某种方式在 GPU 上完成,性能至少会好 10 倍。
  • 这很大程度上取决于您的应用程序。我们不知道您渲染的哪些内容需要与“企鹅”图像进行比较。
  • 没关系,渲染部分在这里花费的时间可以忽略不计。然而,在 cpu 上按像素比较图像需要很多时间。使用什么样的图像相似度函数并不重要,只要它给出的值可以半准确地表示距离。
  • 而且图像距离计算似乎非常适合 GPU,您基本上对每个像素进行一些操作,例如 len(src_color-dst_color),然后将其总结并作为相似度结果返回。
【解决方案2】:

您可以使用 Pearson-Product 来匹配不同的图像。你可以在我的answer 上找到它。您可以直接关联两个图像,而不是匹配比原始图像更少的模板。

很快,你会得到每个文本与平均值的偏差,给你一个相关因子。

但是通过使用着色器改进该算法可能有点困难。首先,您必须计算 textel 平均值:也许一些 OpenGL 扩展(如直方图)可以帮助您完成这项任务。

然后,您可以使用片段着色器执行单分量计算(每个文本与先前计算的平均文本之间的差异。平均文本必须作为统一传递,并且结果应存储在浮点纹理中(您可以在帧缓冲区对象上渲染它)。

然后,您应该对生成的纹理的所有 textel 进行求和,以获得两个源纹理之间的相关性。

如果图像非常大,这可能值得。否则我认为最好在 CPU 上执行算法,使用 SIMD 指令集(如 MMX、SSE、AVX)。

【讨论】:

    猜你喜欢
    • 2011-12-26
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 2021-05-29
    • 2013-11-07
    • 1970-01-01
    相关资源
    最近更新 更多