我在PyQt4中有一个简单的查看器,当从numpy数组(8位灰度)转换为要显示的QImage时,我有一些奇怪的行为。在我看来,当我试图从一个转置的数组构造一个QImage时,似乎有些事情正在变得混乱,即使内存顺序应该已经更新(也就是说,它不仅仅是一个具有不同步幅的视图)。在
下面是一个严重削减版本的查看器:
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_()
现在,这会产生这样的结果,很好:
但是,我需要查看我的真实图像,第一个维度是“x”,第二个维度是“y”,所以它需要被转置(加上一个y-flip,原点在左下角,但这超出了这里的范围)。在
如果我将hgt, wid = data.shape
更改为wid, hgt = data.shape
,而不做任何其他操作(这是错误的),我得到以下结果。这是有道理的,因为QImage只是在读记忆。在
但是,如果我还传入bdata.T.copy()
而不是bdata
,那么我预计数组将被转置,内存将被复制操作重新排序。但我得到的是:
它离得太近了,但出于某种原因只差了一根头发。另外,我注意到,如果尺寸恰好是彼此的整数倍(例如200x100),那么结果就可以了。怎么回事?我是不是错过了一些非常愚蠢的事情?
我不知道这是PyQt问题还是numpy问题。。。转置后的数组使用matplotlib可以很好地绘制,但是matplotlib处理跨步,因此这可能没有任何意义。在
我在Python2.7和Python3.5中得到了相同的行为。PyQt4的版本是4.11.4,使用的是Qt版本4.8.7。Numpy版本是1.10.1。在
这个问题源于
QImage
的创建。在您正在使用的构造函数的签名的documentation表示
如果您更改数组的维数,使其与32位对齐(例如使用
xx, yy = np.meshgrid(np.arange(-128,128), np.arange(384))
),则代码可以正常工作。在要更正此问题而不需要每行32个字节的倍数,您需要对
^{pr2}$QImage
使用稍微different constructor:在您的情况下,这很简单:
^{3}$因为每个像素包含1个字节的信息。在
相关问题 更多 >
编程相关推荐