2016-12-15 57 views
1

是否有可能在Python中執行不安全的圖像處理?不安全的圖像處理在Python中像LockBits在C#

與C#一樣,我在Python中使用像素處理遇到困難,因爲Image中的getPixel方法運行速度太慢。

是否有可能像c#中的LockBits一樣直接訪問內存中的圖像?這將使我的程序運行得更快。

感謝,

馬克

回答

2

沒有什麼 「不安全」 這個問題。

一旦你明白了Python的工作原理,調用一種方法來檢索每個像素的信息會變得很慢,這就變成了專利。首先,雖然你沒有提供任何信息,但我認爲你使用的是「Pillow」 - Python圖像庫(PIL),它是使用Python進行圖像處理的最知名的庫。由於它是第三方軟件包,因此沒有義務使用該軟件包。 (PIL確實對圖像的getpixel方法,但不是一個getPixel一個)

一種直接的方法,有在一個可操作的方式,所有的數據是創建該圖像數據的一個字節陣列對象 - 在一個img變量給定圖像您可以這樣做:

data = bytearray(img.tobytes()) 

就是這樣,您可以線性訪問圖像上的所有數據。要獲得某個特定像素,您需要獲取圖像寬度,高度和每像素字節數。後者不是PIL中的直接Image屬性,因此您必須根據圖像的mode來計算它。最常見的圖片類型爲RGB,RGBA和L.

所以,如果你想在圖像寫出來的「X,Y,寬度,大小」的矩形,你可以這樣做:

def rectangle(img, x,y, width, height): 
    data = bytearray(img.tobytes()) 
    blank_data = (255,) * witdh * bpp 
    bpp = 3 if data.mode == 'RGB' else 4 if data.mode == 'RGBA' else 1 
    stride = img.width * bpp 
    for i in range(y, y + height): 
     data[i * stride + x * bpp: i * stride + (x + width) * bpp)] = blank_data 
    return Image.frombytes(img.mode, (img.width, img.height), bytes(data)) 

這並沒有多大用處,但對於簡單的操作。需要使用Python在圖像中應用濾鏡和其他更復雜的算法的用戶通常使用numpy-python高性能數據處理軟件包來訪問圖像,這與許多其他包含特定圖像的軟件包緊密結合在一起 - 通常安裝爲scipy

因此,有圖像作爲ndarray,它已經完成了所有上述座標 - 你>字節轉換,你可以使用:

import scipy.misc 
data = scipy.misc.imread(<filename>) 

(檢查文檔在https://docs.scipy.org/doc/scipy/reference/

+0

這可能是一個關於基礎知識的問題,但在數據[i * stride + x * bpp:i * stride +(x + width)* bpp)]之前我從未遇到過這種表達式。「那是什麼」這是一本字典嗎?我無法繞過它 –

+0

它是一個使用數字切片索引的數字的簡單序列 - 表達式只是計算圖像線上矩形的第一個像素的地址(以字節爲單位) line(x,i)和最後一個像素(在(x + width,i))。如果你從來沒有看到過Python切片索引,那麼最好學習它們:https://docs.python.org/3 /tutorial/introduction.html#lists – jsbueno

+0

哦,我明白了,我並不熟悉Python的切片運算符,現在一切都合情合理,謝謝! –