2012-03-20 219 views
16

我想將圖像轉換爲一個NumPy數組作爲PySide QPixmap,這樣我就可以顯示它(編輯:在我的PySide UI中)。我已經找到了這個工具:qimage2ndarray,但它只適用於PyQt4。我試圖改變它以使它與PySide一起工作,但是我將不得不改變該工具的C部分,並且我沒有使用C的經驗。我該怎麼做,或者有什麼替代方法?將numpy數組轉換爲PySide QPixmap

回答

12

另一種方法是隻使用PIL庫。

>>> import numpy as np 
>>> import Image 
>>> im = Image.fromarray(np.random.randint(0,256,size=(100,100,3)).astype(np.uint8)) 
>>> im.show() 

你可以看一下在QPixmap的構造在http://www.pyside.org/docs/pyside/PySide/QtGui/QImage.html

看起來你應該能夠直接在構造函數中使用一個numpy的數組:

類PySide.QtGui.QImage(數據,寬度,高度,格式)

其中格式參數是其中之一:http://www.pyside.org/docs/pyside/PySide/QtGui/QImage.html#PySide.QtGui.PySide.QtGui.QImage.Format

因此,例如,你可以這樣做:

>>> a = np.random.randint(0,256,size=(100,100,3)).astype(np.uint32) 
>>> b = (255 << 24 | a[:,:,0] << 16 | a[:,:,1] << 8 | a[:,:,2]).flatten() # pack RGB values 
>>> im = PySide.QtGui.QImage(b, 100, 100, PySide.QtGui.QImage.Format_RGB32) 

我沒有安裝PySide所以我沒有測試過這一點。它有可能不會按原樣工作,但它可能會引導您朝着正確的方向前進。

+0

對不起,我忘了提及。我想在PySide用戶界面中顯示圖像,所以不幸的是我不能這樣做。 – AntonS 2012-03-21 15:57:33

+0

我把第二行改成了'b =(255 << 24 | a [:,:0] << 16 | a [:,:1] << 8 | a [:,:2])'它的工作。非常感謝你! – AntonS 2012-03-22 19:23:20

+0

偉大的解決方案!爲了使它適用於我,我需要做一些小改動,並使用PySide.QtGui.QImage.Format_ARGB32。其餘的都是一樣的。 – 2013-09-26 20:42:21

4

除了@ user545424有關使用PIL,如果你不想依賴於PIL的回答,您可以手動直接從您的NP陣列構建圖片:

width = 100 
height = 100 
data = np.random.randint(0,256,size=(width,height,3)).astype(np.uint8) 

img = QtGui.QImage(width, height, QtGui.QImage.Format_RGB32) 
for x in xrange(width): 
    for y in xrange(height): 
     img.setPixel(x, y, QtGui.QColor(*data[x][y]).rgb()) 

pix = QtGui.QPixmap.fromImage(img) 

我敢肯定,使用PIL,有一種方法可以將實際的圖像數據讀入QImage中,但是我會讓@ user545424從它的答案中解決該部分。 PIL帶有ImageQt模塊,它可以方便地直接轉換Image - > QPixmap,但不幸的是,這是一個PyQt4 QPixmap,它不會幫助你。

+1

謝謝,這工作。但大約需要3秒鐘,對我的應用來說太慢了。 – AntonS 2012-03-21 15:44:51

+2

@AntonS也可以在'PySide'中使用'ImageQt'。你可以在'import ImageQt'前寫'sys.modules ['PyQt4'] = PySide'。示例代碼:http://pastebin.com/DX2pbdpV。但我不知道什麼更快。 – reclosedev 2012-03-21 17:58:22

+0

非常感謝!這工作,但user545425s代碼是更快一點,並不依賴於PIL – AntonS 2012-03-22 19:35:40

10

如果您自己創建數據,例如使用numpy,我認爲最快的方法是直接訪問QImage。您可以從緩衝區對象QImage.bits()創建一個ndarray,使用numpy方法做一些工作,並在完成後從QImage創建一個QPixmap。您也可以通過這種方式讀取或修改現有的QImages。

import numpy as np 
from PySide.QtGui import QImage 

img = QImage(30, 30, QImage.Format_RGB32) 
imgarr = np.ndarray(shape=(30,30), dtype=np.uint32, buffer=img.bits()) 

# qt write, numpy read 
img.setPixel(0, 0, 5) 
print "%x" % imgarr[0,0] 

# numpy write, qt read 
imgarr[0,1] = 0xff000006 
print "%x" % img.pixel(1,0) 

確保數組不超過圖像對象。如果你願意,你可以使用一個更復雜的dtype,就像一個記錄陣列一樣,可以單獨訪問alpha,red,green和blue位(儘管要小心endianess)。

如果沒有有效的方法使用numpy計算像素值,也可以使用scipy.weave來內聯一些運行在數組img.bits()指向的數組上的C/C++代碼。

如果你已經有一個ARGB格式的圖像,那麼根據前面的建議從數據創建QImage可能會更容易。