2012-03-20 35 views
16

Chciałbym przekonwertować obraz na tablicę NumPy na PySide QPixmap, więc mogę go wyświetlić (EDIT: w moim interfejsie PySide). Znalazłem to narzędzie: qimage2ndarray, ale działa ono tylko w PyQt4. Próbowałem go zmienić, aby działał z PySide, ale musiałbym zmienić część C narzędzia i nie mam doświadczenia z C. Jak mogę to zrobić, czy są jakieś alternatywy?Konwertuj tablicę numpy na PySide QPixmap

Odpowiedz

12

Jedną z alternatyw jest użycie biblioteki PIL.

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

Możesz przyjrzeć się konstruktorowi QPixmap pod numerem http://www.pyside.org/docs/pyside/PySide/QtGui/QImage.html.

Wygląda na to, powinieneś być w stanie korzystać z tablicy numpy bezpośrednio w konstruktorze:

klasa PySide.QtGui.QImage (dane, szerokość, wysokość, format)

gdzie Argument format jest jednym z następujących: http://www.pyside.org/docs/pyside/PySide/QtGui/QImage.html#PySide.QtGui.PySide.QtGui.QImage.Format.

Tak więc, na przykład można zrobić coś takiego:

>>> 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) 

nie mam PySide zainstalowany, więc nie testowałem tego. Prawdopodobnie nie zadziała tak jak jest, ale może cię poprowadzić we właściwym kierunku.

+0

Przepraszam, zapomniałem o tym wspomnieć. Chcę wyświetlić obraz w moim interfejsie PySide, więc niestety nie mogę tego zrobić w ten sposób. – AntonS

+0

Zmieniłem 2. linię na "b = (255 << 24 | a [:,:, 0] << 16 | a [:,:, 1] << 8 | a [:,:, 2])' i zadziałało. Dziękuję Ci bardzo! – AntonS

+0

Świetne rozwiązanie! Aby to działało, musiałem wprowadzić niewielką zmianę i użyć PySide.QtGui.QImage.Format_ARGB32. Reszta jest taka sama. –

4

Oprócz @ user545424 odpowiedź na temat korzystania z PIL, jeśli nie chcesz polegać na PIL, można ręcznie skonstruować swój obraz bezpośrednio z tablicy 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) 

Jestem pewien, używając PIL, istnieje sposób, aby odczytać rzeczywiste dane obrazu w QImage, ale pozwolę @ user545424 adresować tę część, ponieważ jest to jego odpowiedź. PIL jest dostarczany z modułem ImageQt, który jest wygodny do bezpośredniej konwersji Image -> QPixmap, ale niestety jest to PyQt4 QPixmap, która nie pomaga.

+1

Dzięki, to działa. Ale zajmuje to około 3 sekund, co jest zdecydowanie za wolne dla mojej aplikacji. – AntonS

+2

@AntonS Możliwe jest również użycie 'ImageQt' z' PySide'. Możesz napisać 'sys.modules ['PyQt4'] = PySide' przed' import ImageQt'. Przykładowy kod: http://pastebin.com/DX2pbdpV. Ale nie wiem, co jest szybsze. – reclosedev

+0

Dziękuję bardzo! To zadziałało, ale kod user545425s jest trochę szybszy i nie zależy od PIL – AntonS

10

Jeśli samodzielnie tworzysz dane, używając np. Numpy, myślę, że najszybszą metodą jest bezpośredni dostęp do QImage. Możesz utworzyć ndarray z obiektu buforowego QImage.bits(), wykonać trochę pracy za pomocą metod numpy i utworzyć QPixmap z QImage, kiedy skończysz. W ten sposób możesz również odczytać lub zmodyfikować istniejący 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) 

Upewnij się, że tablica nie przebije obiektu obrazu. Jeśli chcesz, możesz użyć bardziej wyrafinowanego dtype, takiego jak tablica rekordów dla indywidualnego dostępu do bitów alfa, czerwieni, zieleni i błękitu (uważaj jednak na niekorzyść).

Jeśli nie ma skutecznego sposobu obliczania wartości pikseli za pomocą numpy, można również użyć scipy.weave do wstawienia kodu C/C++, który działa na tablicy img.bits() wskazuje na.

Jeśli masz już obraz w formacie ARGB, tworzenie QImage z danych, jak sugerowano wcześniej, jest prawdopodobnie łatwiejsze.

Powiązane problemy