访问像素值时的 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快。
我正在开发一个图像处理工具(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快。