访问像素值时的 BitmapData 与 Image<,>.Data - 性能

BitmapData vs Image<,>.Data when accessing to pixel value - performance

我正在开发一个图像处理工具(C#,使用 EmguCV) 我需要在像素的单个操作上获得最佳性能。

我已经阅读了很多关于 LockBit() 的线程,并将值从指针复制到字节数组作为最佳方法(当性能优先时)到 get/set 像素值。

我发现了一些这样的实现: http://www.codeproject.com/Tips/240428/Work-with-bitmap-faster-with-Csharp

我将它与更简单的方法进行了比较:

Image<Bgr, byte> image = new Image<Bgr, byte>(Bitmap);
byte[,,] data = image.Data;

//And then get r channel like:
byte rChannel = data[y,x,0];

//And set r channel like:
data[y,x,0] = color.R;

所以,我使用了上面 link 的实现,但我删除了一个像 Color.FromArgb(r, g, b); 这样的创建 Color 并假设图像深度 = 24,只是为了优化性能(我我正在返回一维字节数组作为颜色)

我的结果(图像 2048x2048 - 4194304 比较像素颜色的操作 Color.White - 完成 3 次):

Via `LockBit()` and pointer method:
00:00:00.7971876
00:00:00.7569262
00:00:00.7693977

Via `Image<,>.Data` method:
00:00:00.7957318
00:00:00.8136698
00:00:00.8010817

我没有发现不安全 LockBits() 和指针方法与非常清晰简单的 Image<,>.Data 方法之间有任何显着的性能差异。

谁能解释一下为什么 LockBits()/Pointer 方法被称为超快?也许我遗漏了一些东西(正如我所说 - 我使用了上面 link 的实现)。

你是在问为什么使用 LockBits() 是 "called a super fast"?我不太清楚 "first one" 在这里指的是什么。

也就是说,重要的问题是您的代码是否需要转换到图形驱动程序(处理位图操作)。转换非常昂贵,每次调用 GetPixel()SetPixel().

之类的方法时都会发生

因此 API 类似于 LockBits() 方法。在这种方法中,您将所有数据一次性复制到图形驱动程序,复制到您的程序可以直接访问的内存中。然后你直接对该内存进行操作。然后在另一个单一过渡中将其复制回位图(如有必要)。

与使用 GetPixel()SetPixel() 相比,LockBits() 之类的东西 非常快。但是 LockBits() 并不是实现这种性能的唯一方法。 任何避免进出图形驱动程序的 API 将是"super fast"。由于 EmguCV 与使用 LockBits() 类似,因为它不涉及代码和图形驱动程序之间的大量转换,所以速度同样快。


这样看:使用 GetPixel()SetPixel() 有点像骑自行车,而使用 LockBits() 和 EmguCV 更像是驾驶赛车。后两者并不相同。一辆赛车 and/or 其驾驶员将比另一辆赛车稍慢或稍快。但两者都比人力交通way快。