Я хочу преобразовать изображение в массив NumPy в PySide QPixmap, поэтому я могу его отобразить (EDIT: в моем пользовательском интерфейсе PySide). Я уже нашел этот инструмент: qimage2ndarray, но он работает только для PyQt4. Я попытался изменить его, чтобы заставить его работать с PySide, но мне пришлось бы изменить часть C инструмента, и у меня нет опыта работы с C. Как я могу это сделать или есть альтернативы?
Преобразование массива numpy в PySide QPixmap
Ответ 1
Один из вариантов - просто использовать библиотеку 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, поэтому я не тестировал это. Скорее всего, он не будет работать так, как есть, но он может помочь вам в правильном направлении.
Ответ 2
Если вы создаете данные самостоятельно, используя, например, numpy, я считаю, что самым быстрым методом является прямой доступ к QImage. Вы можете создать ndarray из объекта-буфера QImage.bits(), выполнить некоторую работу с использованием методов numpy и создать QPixmap из QImage, когда вы закончите. Вы также можете читать или изменять существующие 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, например массив записей для индивидуального доступа к альфа-и красным, зеленым и синим битам (но будьте осторожны с endianess).
Если нет эффективного способа вычисления значений пикселей с помощью numpy, вы также можете использовать scipy.weave для вставки некоторого кода C/С++, который работает с массивом img.bits().
Если у вас уже есть изображение в формате ARGB, создание QImage из данных, как было предложено ранее, возможно, проще.
Ответ 3
В дополнение к @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, который удобен для прямого преобразования изображения → QPixmap, но, к сожалению, это PyQt4 QPixmap, который вам не поможет.