如何使用pyqt在场景中输出色彩映射?

时间:2016-02-17 00:18:07

标签: python qt matplotlib pyqt4

TL; DR:您只需阅读“更新”部分。

  

如何将numpy.random.random((256, 256))作为色彩映射输出到   qt场景?

这是摘要摘要。

更新

以下是我想要保存到文件的色彩映射。

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

self.image是256x256 numpy数组,它的所有值都在-1和1之间。 enter image description here

如何将此图像输出到Qt中的场景?您可以使用self.image = numpy.random.random((256, 256))来获得与我类似的起点。你如何将你的2D numpy随机值数组作为colormap放到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)

enter image description here

我在2016年2月23日尝试了什么

下面给我一个空白的屏幕

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

enter image description here

下面给我一个输出到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)

enter image description here

我从解决方案逆向设计色彩映射问题here并显示图像here

使用发布的解决方案中的建议我首先尝试创建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是numpy 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

enter image description here

如果我做了以下操作,我会得到我想要的色彩图,例如我之前开发的网络应用程序的下图中

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

enter image description here

如何将色彩映射添加到qt场景,而不仅仅是灰度?

3 个答案:

答案 0 :(得分:1)

所以这很有效......但我觉得这样做很脏:

    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场景的方法的人,而无需保存到文件的中间步骤。

与此同时,这种胶带 - 胶带解决方案有效:

enter image description here

更新:作为参考,我最终使用rbaleksandarimposeren中的代码完成了这项工作。大家好!

    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)

答案 1 :(得分:1)

你已经拥有几乎正常工作的代码。您可以使用以下方式获取图像:

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')来反转颜色而无需任何数学运算。但请确保您的值已正确缩放

答案 2 :(得分:0)

您应该使用Matplotlib's imshow继续沿着colormap customisation路线(可能还伴随着matplotlib's PyQt4 backend)。

我之前使用过这个mpl-PyQt4工具,虽然起初看起来很麻烦但是你正在寻找它(使用本机工具,没有技术翻译/桥接)和大多数可扩展。通过动画以及绘图的QLayout排列

,在示例中显示了这些属性