2016-03-01 15 views
1

我正在研究圖像處理工具(C#,使用EmguCV) 我需要在像素上執行單一操作時獲得最佳性能。BitmapData vs Image <,>。訪問像素值時的數據 - 性能

我已經讀了很多關於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; 

所以,我從上面的鏈接使用的實現,但我切出一個創建ColorColor.FromArgb(r, g, b);,並假設圖像深度= 24,只是爲了優化性能(我返回一個字節的一維數組作爲顏色)

我的結果(圖片2048×2048 - 與Color.White比較像素的顏色的4194304操作 - 做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方法被稱爲超快?也許我錯過了一些東西(正如我所說 - 我已經使用了上面鏈接的實現)。

回答

1

你問爲什麼使用LockBits()被稱爲「超級快」?這並不完全清楚「第一個」在這裏指的是什麼。

也就是說,重要的問題是您的代碼是否需要轉換到圖形驅動程序(它處理位圖操作)或不。轉換非常昂貴,並且每次調用類似GetPixel()SetPixel()的方法時都會發生。

因此API如LockBits()方法。在這種方法中,您將所有數據以單一轉換的形式複製到圖形驅動程序中,並存儲到程序可直接訪問的內存中。然後你直接在內存上操作。然後在另一個單獨的轉換中將其複製回位圖(如有必要)。

與使用GetPixel()SetPixel(),像LockBits()速度極快。但LockBits()不是實現這種性能的唯一方法。 任何避免過渡到圖形驅動程序的API將是「超級快」。由於EmguCV與使用LockBits()類似,因爲它不涉及代碼和圖形驅動程序之間的大量轉換,所以它將類似地快速。


看它是這樣的:使用GetPixel()SetPixel()是有點像騎自行車,同時採用LockBits()和EmguCV更喜歡駕駛賽車。後兩者並不相同;一輛賽車和/或其駕駛員將會比另一輛賽車稍慢或更快。但都是方式比人力運輸快。

+0

我在問:「使用這兩種方法應該有什麼明顯的區別嗎?也許我錯過了什麼會有所作爲」但最後2段完全清楚了我:)謝謝 – ilovkatie