Подтвердить что ты не робот

Как вывести цветную сцену в сцену с помощью pyqt?

TL; DR: Вам нужно только прочитать раздел "Обновление".

Как вы выводите numpy.random.random((256, 256)) в качестве цветовой схемы для qt сцена?

Это резюме резюме.

Update:

Следующее получает мне colormap, который я хочу сохранить в файл.

scaled_image = Image.fromarray(np.uint8(self.image*255))
plt.savefig("/home/test.png")

self.image - массив 256x256 numpy, все его значения находятся в диапазоне от -1 до 1. введите описание изображения здесь

Как получить это изображение для вывода на сцену в Qt? Вы можете использовать self.image = numpy.random.random((256, 256)), чтобы иметь начальную точку, похожую на меня. Как вы получаете массив двумерных numpy случайных значений на сцену pyqt в качестве цветовой карты?


Обновление 24/02/1016

Так близко. Кажется, что это работает, но масштаб был инвертирован. Синий теперь горячий, а красный - холодный. Как переключить это вокруг так, чтобы оно выглядело как изображение выше?

    scene = QGraphicsScene(self)
    scaled_image = Image.fromarray(np.uint8(self.image*255))
    gcf().canvas.draw() # IMPORTANT!
    stringBuffer = gcf().canvas.buffer_rgba() # IMPORTANT!
    l, b, w, h = gcf().bbox.bounds
    qImage = QtGui.QImage(stringBuffer,
                  w,
                  h,
                  QtGui.QImage.Format_ARGB32)
    pixmap = QtGui.QPixmap.fromImage(qImage)
    pixmapItem = QtGui.QGraphicsPixmapItem(pixmap)
    scene.addItem(pixmapItem)
    self.graphicsView.setScene(scene)

введите описание изображения здесь

Что я пробовал 23/02/2016

Следующий экран показывает пустой экран

    scene = QGraphicsScene(self)
    scaled_image = Image.fromarray(np.uint8(self.image*255))
    pixMap = QPixmap(scaled_image)
    scene.addPixmap(pixMap)
    self.graphicsView.setScene(scene)

введите описание изображения здесь

Ниже вы получите оттенки серого, выделенные для сцены Qt. Почему это не цвет?

scene = QGraphicsScene(self)
scaled_image = Image.fromarray(np.uint8(self.image*255))
imgQ = ImageQt(scaled_image)
pixMap = QtGui.QPixmap.fromImage(imgQ)
scene.addPixmap(pixMap)
self.graphicsView.setScene(scene)

введите описание изображения здесь

Я переделал из решений проблем с цветовой схемой здесь и отобразил изображение здесь.

Используя совет из размещенного решения, я попытался сначала создать QGraphicsPixmapItem, а затем добавить элемент в сцену. Официальные документы были немного запутанными, поэтому я, наконец, получил то, что мне нужно, от более хрустящего pyside docs. К сожалению, я получаю те же оттенки серого, что и выше. Код ниже:

    scene = QGraphicsScene(self)
    scaled_image = Image.fromarray(np.uint8(self.image*255))
    imgQ = ImageQt(scaled_image)
    pixMap = QtGui.QPixmap.fromImage(imgQ)
    pixMapItem = QtGui.QGraphicsPixmapItem(pixMap)
    scene.addItem(pixMapItem)
    self.graphicsView.setScene(scene)

Другие вещи, которые я пробовал (старше):

self.image - это многомерный 2D-массив, все его значения находятся в диапазоне от -1 до 1.

Я масштабируюсь следующим образом и получаю изображение в градациях серого. Тем не менее, я хочу colourmap:

    scene = QGraphicsScene(self)
    scaled_image = (self.image + 1) * (255 / 2)    
    scene.addPixmap(QPixmap.fromImage(qimage2ndarray.array2qimage(scaled_image)))
    self.graphicsView.setScene(scene)

#min(self.image) = -0.64462
#max(self.image) = 1.0

введите описание изображения здесь

Если бы я сделал следующее, я бы получил цветовой пакет, который я хочу, например, на изображении ниже веб-приложения, которое я ранее разработал

>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> imgplot = ax.imshow(self.image)

введите описание изображения здесь

Как добавить цветную копию в сцену qt вместо того, чтобы иметь оттенки серого?

4b9b3361

Ответ 1

QPixmap поддерживает значения цвета больше 255 и несколько форматов изображений. Если бы это было неверно, все значки в Qt были бы серого (очевидно, не в том случае;)).

Вы можете сгенерировать свою цветовую карту любым способом, который вы хотите сделать (до (используя OpenCV и numpy) или после преобразования в QImage (используя Qt)), преобразуйте его в QPixmap и используя QGraphicsPixmapItem (не используйте QPixmap как часть QGraphicScene напрямую) присоедините его к своему QGraphicsScene.

EDIT: Я неправильно прочитал документацию. Фактически вы можете использовать QPixmap непосредственно в QGraphicScene, используя addPixmap(). Извини за это. В качестве извинения здесь есть какой-то код для вас.: P

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class ImageView(QGraphicsView):
  def __init__(self, pixmap=None, parent=None):
    '''
    QGraphicsView shows the image
    '''
    super(ImageView, self).__init__(parent)
    self.pixmap = pixmap


class Widget(QWidget):
  def __init__(self, parent=None):
    super(Widget, self).__init__(parent)
    layout = QVBoxLayout(self)
    pic = QPixmap('/home/-----/Pictures/7 Cat Sins - Wrath.jpg')
    grview = ImageView(pic, self)
    layout.addWidget(grview)
    self.setFixedSize(pic.size())

    scene = QGraphicsScene(self)
    scene.addPixmap(pic)

    grview.setScene(scene)
    self.show()

def main():
  app = QApplication(sys.argv)
  w = Widget()

  return sys.exit(app.exec_())

if __name__ == '__main__':
  main()

Он производит следующий результат:

введите описание изображения здесь

Источник изображения: найдите 7 кошачьих грехов - гнев на Google;)

В основном вы создаете средство просмотра изображений, создаете граф сцены, добавляете pixmap к графику сцены, устанавливаете сцену просмотра изображения на этот график и показываете карту pixmap на экране с помощью этого средства просмотра.

EDIT2: Хорошо, так что, похоже, у вас возникли проблемы с фактической интеграцией matplotlib. Вот как вы это делаете (взято из здесь с небольшим изменением для gcf().canvas.buffer_rgba()):

import numpy as np
from matplotlib import use
use('AGG')
from matplotlib.pylab import *
from PySide import QtCore,QtGui
# Following are used for the generation of the image but you have your own imports so you don't need them
from matplotlib.transforms import Bbox
from matplotlib.path import Path
from matplotlib.patches import Rectangle    

# Generation of the figure (you can skip all that and use your stuff)
rect = Rectangle((-1, -1), 2, 2, facecolor="#aaaaaa")
gca().add_patch(rect)
bbox = Bbox.from_bounds(-1, -1, 2, 2)

for i in range(12):
    vertices = (np.random.random((4, 2)) - 0.5) * 6.0
    vertices = np.ma.masked_array(vertices, [[False, False], [True, True], [False, False], [False, False]])
    path = Path(vertices)
    if path.intersects_bbox(bbox):
        color = 'r'
    else:
        color = 'b'
    plot(vertices[:,0], vertices[:,1], color=color)

# The conversion and display of the plot
app = QtGui.QApplication(sys.argv)
gcf().canvas.draw() # IMPORTANT!

stringBuffer = gcf().canvas.buffer_rgba() # IMPORTANT!
l, b, w, h = gcf().bbox.bounds

qImage = QtGui.QImage(stringBuffer, 
                      w,
                      h,
                      QtGui.QImage.Format_ARGB32)

scene = QtGui.QGraphicsScene()
view = QtGui.QGraphicsView(scene)
pixmap = QtGui.QPixmap.fromImage(qImage)
pixmapItem = QtGui.QGraphicsPixmapItem(pixmap)
scene.addItem(pixmapItem)
view.show()

app.exec_()

ИЗМЕНИТЬ 3: Для вашей проблемы с обратным отображением colourmap см. здесь (документация) и здесь (SO).

PS: Вместо использования дополнительной библиотеки, такой как qimage2ndarray для преобразования изображений OpenCV в QImage, я советую вам сделать это самостоятельно, чтобы увидеть, что именно нужно сделать. Такие библиотеки являются аккуратными, если у вас есть большой опыт работы с материалом, и вам просто нужно сэкономить время. Кроме того, держитесь подальше от них.

Ответ 2

Итак, это сработало... но я чувствую себя настолько грязным, делая это вот так:

    scene = QGraphicsScene(self)
    scaled_image = Image.fromarray(np.uint8(self.image*255))
    plt.savefig(".../Downloads/itworks.png")
    pixMap = QPixmap(".../Downloads/itworks.png")
    scene.addPixmap(pixMap)
    self.graphicsView.setScene(scene)

Должна ли быть зависимость от сохранения образа в файл, а затем перезагрузка его как QPixmap для этого? Разве это не очень безотпительный ответ на ленту, что я думаю, это довольно стандартный спрос на pyqt? Я обеспокоен необходимостью сохранять изображение в файл каждый раз, создавая узкое место, пока я расширяюсь, и, кроме того, просто раздражайтесь, поскольку мне придется управлять файловой системой.

Я оставляю щедрость открытой для всех, кто может предоставить средство вывода numpy.random.random((256, 256)) в сцену qt без промежуточного этапа сохранения в файл.

В то же время это решение для работы с канатной лентой работает:

введите описание изображения здесь

Обновление: Для справки, это то, что я закончил, работая отлично, используя код из rbaleksandar и imposeren. Спасибо всем!

    scene = self.QScene(self)
    scaled_image = Image.fromarray(255-np.uint8(self.image*255))
    plt.imshow(scaled_image, interpolation = "nearest")
    gcf().canvas.draw() # IMPORTANT!
    stringBuffer = gcf().canvas.buffer_rgba() # IMPORTANT!
    l, b, w, h = gcf().bbox.bounds
    qImage = QtGui.QImage(stringBuffer,
                  w,
                  h,
                  QtGui.QImage.Format_ARGB32)
    pixmap = QtGui.QPixmap.fromImage(qImage)
    pixmapItem = QtGui.QGraphicsPixmapItem(pixmap)
    scene.addItem(pixmapItem)
    self.graphicsView.setScene(scene)

Ответ 3

у вас уже есть код, который почти работает. Вы получаете изображение, используя:

scaled_image = Image.fromarray(np.uint8(self.image*255))

Чтобы инвертировать, вам нужно только вычесть текущие данные из 255.

scaled_image = Image.fromarray(255-np.uint8(self.image*255))

Здесь я предполагаю, что ваш текущий код работает правильно и имеет только инвертированные значения. Но если ваши данные действительно от -1 до 1, тогда текущий код будет закрывать половину результатов до нуля (поскольку минимальное значение для uint8 равно нулю). Правильный код для значений от -1 до 1 должен быть немного изменен:

scaled_image = Image.fromarray(255 - (self.image + 1)*127.5)

P.S. вы можете инвертировать цвета без какой-либо математики, используя другую цветочную карту (например, 'jet_r'). Но убедитесь, что ваши значения правильно масштабированы.

Ответ 4

Вы должны продолжить маршрут Matplotlib imshow (возможно, также с настройка цветовой схемы), используя matplotlib PyQt4 backend.

Я использовал эти инструменты mpl-PyQt4 до и, хотя сначала это может выглядеть громоздким, это то, что вы ищете (использование собственных инструментов, отсутствие перевода/моста) и большинство расширяемый. Такие свойства показаны в примере, выполняя анимацию вместе с расположением графиков QLayout