使用OpenGL或DirectX快速比较两张图片

时间:2012-05-22 07:24:21

标签: winapi opengl image-processing graphics cuda

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

所以我查看了delphi中的source,它看起来像这样:

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

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

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

对于在相当小的图像上进行如此简单的图像操作,3s意味着你正在做一些非常错误的事情。我的意思是:我的笔记本电脑可以实时将全高清视频编码为h264,这是你可以对图像做的最复杂的任务之一。

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

HLSL / GLSL。 使用它们,你可以执行大量的同步minithreads,其性能较低,但它对像素比较有好处。