2

我需要比较 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 一起使用不会有问题。

4

4 回答 4

2

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

于 2012-05-22T16:09:20.213 回答
1

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

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

于 2012-05-22T09:07:55.640 回答
1

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

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

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

于 2012-05-22T10:15:08.650 回答
0

HLSL/GLSL。使用它们,您可以同时执行许多微型线程,其中一个性能较低,但它有利于像素比较。

于 2012-05-22T09:17:51.360 回答