gpt4 book ai didi

python - 将 numpy 数组转换为 QImage 时的内存顺序行为问题

转载 作者:行者123 更新时间:2023-11-28 18:30:10 24 4
gpt4 key购买 nike

我在 PyQt4 中有一个简单的查看器,在从 numpy 数组(8 位灰度)转换为 QImage 进行显示时,我遇到了一些奇怪的行为。在我看来,当我尝试从转置数组构建 QImage 时,似乎有些事情变得一团糟,即使内存顺序应该已经更新(即它不仅仅是一个具有不同步幅的 View )。

下面是查看器的大幅缩减版本:

import numpy as np
from PyQt4 import QtGui

class SimpleViewer(QtGui.QMainWindow):

def __init__(self, data, parent=None):
super(SimpleViewer, self).__init__(parent=parent)

hgt, wid = data.shape

dmin = data.min()
dmax = data.max()
bdata = ((data - dmin)/(dmax - dmin)*255).astype(np.uint8)

img = QtGui.QImage(bdata, wid, hgt, QtGui.QImage.Format_Indexed8)

self.scene = QtGui.QGraphicsScene(0, 0, wid, hgt)
self.px = self.scene.addPixmap(QtGui.QPixmap.fromImage(img))

self.view = QtGui.QGraphicsView(self.scene)
self.setCentralWidget(self.view)


if __name__ == "__main__":

app = QtGui.QApplication.instance()
if app is None:
app = QtGui.QApplication(['python'])

xx, yy = np.meshgrid(np.arange(-100,100), np.arange(350))
zz = xx * np.cos(yy/350.*6*np.pi)

viewer = SimpleViewer(zz)
viewer.show()
app.exec_()

现在,按原样产生这样的东西,这很好:

vertical-is-okay

但是,我需要查看我的真实图像,第一维为“x”,第二维为“y”,因此需要转置(加上 y 翻转,所以原点在左下角,但这是不在此范围内)。

如果我将 hgt, wid = data.shape 更改为 wid, hgt = data.shape 并且什么都不做(这是错误的),我会得到以下结果。这是有道理的,因为 QImage 只是在读取内存。

bad-memory-order

但是,如果我传入bdata.T.copy()而不是bdata,我希望数组将被转置并且内存通过复制操作重新排序。但我得到的是:

problem

非常接近,但由于某种原因只差了一根头发。另外,我注意到如果尺寸恰好是彼此的整数倍(例如 200x100),那么它就可以了。到底是怎么回事? 我是不是错过了一些非常愚蠢的事情?

我不知道这是 PyQt 问题还是 numpy 问题……转置数组使用 matplotlib 可以很好地绘图,但 matplotlib 处理跨步,所以这可能没有任何意义。

我在 Python 2.7 和 Python 3.5 中得到相同的行为。 PyQt4版本为4.11.4,使用Qt版本4.8.7。 Numpy 版本为 1.10.1。

最佳答案

问题源于 QImage 的创建。

img = QtGui.QImage(bdata, wid, hgt, QtGui.QImage.Format_Indexed8)

documentation对于您正在使用的构造函数的签名,

... data must be 32-bit aligned, and each scanline of data in the image must also be 32-bit aligned.

如果您更改数组的维度以使其为 32 位对齐(例如使用 xx, yy = np.meshgrid(np.arange(-128,128), np.arange(384))) 那么你的代码就可以正常工作了。

要在不需要每行 32 字节的倍数的情况下更正此问题,您需要稍微使用 different constructor对于 QImage:

QImage(data, width, height, bytesPerLine, format)

在您的情况下,这很简单:

img = QtGui.QImage(bdata, wid, hgt, wid, QtGui.QImage.Format_Indexed8)

因为每个像素包含 1 个字节的信息。

关于python - 将 numpy 数组转换为 QImage 时的内存顺序行为问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38107493/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com