【问题标题】:Fast comparing two pictures using OpenGL or DirectX使用 OpenGL 或 DirectX 快速比较两张图片
【发布时间】:2012-05-28 16:19:03
【问题描述】:

我需要比较 2 张图片并找到与指定阈值不同的像素。 现在我只是在 for 循环中以编程方式进行操作,对于 600x400 的小图片大约需要 3 秒。 我想知道是否有办法使用 OpenGL、DirectX、CUDA 或类似的东西更快地做到这一点?所以它将使用 GPU 而不仅仅是 CPU。 请注意,在输出中我需要一个不同像素的数组,而不仅仅是布尔值,具体取决于它是否相同。

所以我在 delphi 中查看了源代码,它看起来像这样:

function TCanvas.GetPixel(X, Y: Integer): TColor;
begin
  RequiredState([csHandleValid]);
  GetPixel := Windows.GetPixel(FHandle, X, Y);
end;

似乎每次都调用 WinAPI 函数 GetPixel()。可能这就是它如此缓慢的原因。 所以现在我的问题是:有没有办法通过 WinAPI 获取整个像素数组?我正在使用具有 HBITMAP 的屏幕截图,因此将它与 WinAPI 一起使用不会有问题。

【问题讨论】:

  • "现在我只是在 for 循环中以编程方式进行操作,对于 600x400 的小图片大约需要 3 秒。"用什么语言?这是调试版本吗? 解释的脚本语言可能会比这更快。
  • Nicol Bolas,我使用的是 delphi 7。不,我不认为这是一个调试版本。为什么你认为解释型语言会更快?我一直认为编译语言更快。
  • 他们是(在这里挥舞着表演火焰战:P)。 Nicol Bolas(含蓄地)暗示您当前的代码非常未经优化。在考虑迁移到 GPU 之前,您可能应该首先优化您的 CPU 版本。
  • 详细地说,对于大多数简单的算法和合理大小的图像,在 CPU 上执行这样的增量可能比将图像加载到 GPU 上更快。要详细了解,请停止使用 canvas.Pixels[]。
  • @user860478:对缓冲区的原始操作。中间没有一些抽象。可能所有访问像素值的函数调用都会影响您的性能。

标签: winapi opengl image-processing graphics cuda


【解决方案1】:

由于您使用的是 delphi ,您可以在 TBitmap 中加载图像,然后使用 ScanLine 属性快速访问位图的像素。

【讨论】:

    【解决方案2】:

    虽然使用 OpenGL 或 Direct3D 进行此类图像操作在技术上是可行的,但这并不是它们的本意。他们正在绘制 API。 CUDA 或 OpenCL 会更适合,但对于比较图像这样简单的事情来说,它们完全是矫枉过正。此外,上传开销也会对性能产生负面影响。

    3s 对一个相当小的图像进行如此简单的图像操作意味着你做错了什么。我的意思是:我的笔记本电脑可以将全高清视频实时编码为 h264,这是您可以对图像执行的最复杂的任务之一。

    【讨论】:

      【解决方案3】:

      该死的!您可以使用 CUDA/OpenCL 在 GPU 上执行此操作,而您的案例说明了您可以在 GPU 上实现的并行性。例如,在 CUDA 中,您将在 GPU 上启动 600x400 线程,同时计算两个图像在每个点的像素差。

      换句话说,600 和 400 次迭代计数的两个嵌套 for 循环将被 GPU 上的 240,000 个线程移除。线程 0 将计算点 0 处的像素差,线程 1 将计算点 1 处的像素差,依此类推。所有线程理论上都会在 GPU 上并行执行。

      缺点: 虽然在 GPU 上的计算会比在 CPU 上快很多,但是您还需要先将图像数据上传到 GPU 内存,然后将计算后的结果传回 CPU 内存。如果整体 GPU 时间(包括计算和内存传输)小于 CPU 计算时间,那么您就赢了。

      【讨论】:

      • GPU 不是这样工作的。 GPU 有着色器单元,因为有着色器单元,所以并行处理的片段永远不会更多。在单个缓冲的 OpenGL 上下文中,使用非常复杂的着色器,您实际上可以看到以块为单位写入的像素。
      • 我指的是软件级别的 CUDA 和 OpenCL 架构,而不是 OpenGL。
      • 即使在软件级别上,CUDA 或 OpenCL 也不是这样工作的。线程一个独立的操作序列。然而 CUDA 和 OpenCL 是 SIMD 编程模型,即所有内核最终都按照称为“内核”的顺序执行相同的指令。
      【解决方案4】:

      HLSL/GLSL。 有了它们,你可以同时执行很多小线程,其中一个的性能很低,但它有利于像素比较。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多