Преобразовать массив NumPy в PySide QPixmap - PullRequest
17 голосов
/ 21 марта 2012

Я хочу преобразовать изображение в массив NumPy в PySide QPixmap, чтобы я мог его отобразить (РЕДАКТИРОВАТЬ: в моем PySide UI).Я уже нашел этот инструмент: qimage2ndarray , но он работает только для PyQt4.Я попытался изменить его, чтобы заставить его работать с PySide, но мне пришлось бы изменить часть C инструмента, и у меня нет опыта работы с C. Как я могу это сделать или есть какие-то альтернативы?

Ответы [ 3 ]

12 голосов
/ 21 марта 2012

Один из вариантов - просто использовать библиотеку 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, поэтому я не проверял это.Скорее всего, он не будет работать как есть, но он может направить вас в правильном направлении.

10 голосов
/ 04 апреля 2012

Если вы создаете данные самостоятельно, например, используя 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)

Убедитесь, что массив не переживает объект изображения.Если вы хотите, вы можете использовать более сложный тип d, например массив записей для индивидуального доступа к альфа-каналу, красным, зеленым и синим битам (хотя остерегайтесь порядка).

В случае, если нет эффективного способавычислить значения пикселей, используя numpy, вы также можете использовать scipy.weave, чтобы встроить некоторый код C / C ++, который работает с массивом, на который указывает img.bits ().

Если у вас уже есть изображение в формате ARGB,создание QImage из данных, как предлагалось ранее, возможно, проще.

4 голосов
/ 21 марта 2012

В дополнение к @ 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, который вам не помогает.

...