我需要比较 2 张图片并找到与指定阈值不同的像素。现在我只是在 for 循环中以编程方式执行此操作,对于 3x3 的小图片大约需要 400 秒。我想知道是否有办法使用OpenGL,DirectX,CUDA或类似的东西更快地做到这一点?因此,它将使用GPU,而不仅仅是CPU。请注意,在输出中,我需要不同像素的数组,而不仅仅是布尔值,具体取决于它是否相同的图片。
所以我在德尔福查看了源代码,它看起来像这样:
function TCanvas.GetPixel(X, Y: Integer): TColor;
begin
RequiredState([csHandleValid]);
GetPixel := Windows.GetPixel(FHandle, X, Y);
end;
似乎它每次都调用WinAPI函数GetPixel((。可能这就是它如此缓慢的原因。所以现在我的问题是:有没有办法通过 WinAPI 获取整个像素数组?我正在使用具有HBITMAP的屏幕截图,因此将其与WinAPI一起使用不会有问题。
由于您使用的是 delphi ,因此可以在 TBitmap 中加载图像,然后使用 ScanLine
属性快速访问位图的像素。
虽然在技术上可以使用OpenGL或Direct3D进行此类图像操作,但这不是它们的用途。他们正在绘制 API。CUDA 或 OpenCL 会更适合,但对于像比较图像这样简单的事情来说,它们完全是矫枉过正的。此外,上传开销也会对性能产生负面影响。
对于在相当小的图像上进行如此简单的图像操作,3s 意味着您正在做一些非常错误的事情。我的意思是:我的笔记本电脑可以实时将全高清视频编码为h264,这是您可以对图像执行的最复杂的任务之一。
的!您可以使用 CUDA/OpenCL 在 GPU 上执行此操作,相反,您的案例体现了您可以在 GPU 上实现的并行性。例如,在 CUDA 中,您将在 GPU 上启动 600x400 线程,该线程将同时计算每个点两个图像的像素差异。
换句话说,嵌套的 for 循环为 600 和 400 次迭代计数的两个将在 GPU 上被 240,000 个线程删除。线程 0 将计算点 0 处的像素差异,线程 1 点 1 处的像素差异,依此类推。理论上,所有线程都将在 GPU 上并行执行。
缺点:虽然 GPU 上的计算速度会比 CPU 上的计算快得多,但您还需要先将图像数据上传到 GPU 内存,然后将计算后的结果传回 CPU 内存。如果整体 GPU 时间(包括计算和内存传输(少于 CPU 计算时间,那么您就赢了。
HLSL/GLSL.有了它们,您可以同时执行许多微线程,这些微线程的性能很低,但它有利于像素比较。