我正在开发一个图像处理工具(C#,使用EmguCV) 我需要在像素上的单个操作上获得最佳性能。
我已经阅读了很多关于LockBit()
的线程,并将指针复制到字节数组作为BEST方法(当性能优先时)来获取/设置像素值。
我发现了一些像这样的实现: 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;
所以,我使用了上面链接的实现,但我删除了一个创建Color
,如Color.FromArgb(r, g, b);
并假设图像深度= 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
方法被称为超级快速?也许我错过了一些东西(正如我所说 - 我使用了上面链接的实现)。
答案 0 :(得分:1)
您是否在问为什么使用LockBits()
&#34;称为超级快速&#34;?我并不完全清楚&#34;第一个&#34;指这里。
也就是说,重要的问题是你的代码是否需要转换到图形驱动程序(处理位图操作)。过渡非常昂贵,每次调用GetPixel()
或SetPixel()
等方法时都会发生此过渡。
因此API就像LockBits()
方法一样。在这种方法中,您将所有数据在一次转换中复制到图形驱动程序,复制到程序可直接访问的内存中。然后直接操作该内存。然后在另一个单一转换中将其复制回位图(如有必要)。
与使用GetPixel()
和SetPixel()
相比,LockBits()
之类的内容非常快。但LockBits()
并不是实现这种表现的唯一方法。 任何 API都可以避免与图形驱动程序之间的过渡,超快速#34;由于EmguCV类似于使用LockBits()
,因为它不会涉及代码和图形驱动程序之间的大量转换,因此它也会同样快速。
这样看:使用GetPixel()
和SetPixel()
有点像骑自行车,而使用LockBits()
和EmguCV更像是驾驶赛车。后两者并不相同;一辆赛车和/或其驾驶员将比另一辆更慢或更快。但两者都比人力交通更快方式。