Преобразование массива numpy в PySide QPixmap - программирование
Подтвердить что ты не робот

Преобразование массива numpy в PySide QPixmap

Я хочу преобразовать изображение в массив NumPy в PySide QPixmap, поэтому я могу его отобразить (EDIT: в моем пользовательском интерфейсе PySide). Я уже нашел этот инструмент: qimage2ndarray, но он работает только для PyQt4. Я попытался изменить его, чтобы заставить его работать с PySide, но мне пришлось бы изменить часть C инструмента, и у меня нет опыта работы с C. Как я могу это сделать или есть альтернативы?

4b9b3361

Ответ 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, который вам не поможет.