【发布时间】:2017-05-26 14:26:42
【问题描述】:
我正在使用 tif 堆栈,QImage 似乎将一些图像倾斜到 45 度角。 Matplotlib 能够在两个测试用例中毫无问题地显示图像(下面提供了两个 tif 堆栈的链接),所以我认为我没有在某个地方搞砸了我的数组。
这是一个工作示例:(注意:为简单起见,此示例仅显示 tif 堆栈中的第一个图像)
import matplotlib.pyplot as plt
import sys
from PIL import Image
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import (QMainWindow, QApplication, QVBoxLayout,
QWidget, QFileDialog, QGraphicsPixmapItem, QGraphicsView,
QGraphicsScene)
import numpy as np
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# set up a widget to hold a pixmap
wid = QWidget(self)
self.setCentralWidget(wid)
self.local_grview = QGraphicsView()
self.local_scene = QGraphicsScene()
vbox = QVBoxLayout()
self.local_grview.setScene( self.local_scene )
vbox.addWidget(self.local_grview)
wid.setLayout(vbox)
# load and display the image
self.loadImage()
# display the widget
self.show()
# also use matplotlib to display the data as it should appear
plt.imshow(self.dataUint8[0], cmap='gray')
plt.show()
def loadImage(self):
fname = QFileDialog.getOpenFileName(self, 'Open file', '/home')[0]
# use the tif reader to read in the tif stack
self.data = self.readTif(fname)
# convert to uint8 for display
self.dataUint8 = self.uint8Convert(self.data)
###############################################################################################################################
# I suspect this is where something goes wrong
###############################################################################################################################
# create a QImage object
self.im = QImage(self.dataUint8[0], self.dataUint8[0].shape[1], self.dataUint8[0].shape[0], QImage.Format_Grayscale8)
# if we save using self.im.save() we also have a skewed image
###############################################################################################################################
# send the QImage object to the pixmap generator
self.pixmap = QPixmap(self.im)
self.pixMapItem = QGraphicsPixmapItem(self.pixmap, None)
self.local_scene.addItem(self.pixMapItem)
def readTif(self, filename): # use this function to read in a tif stack and return a 3D numpy array
# read in the file
stack = Image.open(filename)
# extract each frame from the file and store in the frames variable
frames = []
i = 0
while True:
try:
stack.seek(i) # move to the ith position in the stack
frames.append(np.array(stack) )
i += 1
except EOFError:
# end of stack
break
del stack # probably unnecessary but this presumably saves a bit of memory
return frames
def uint8Convert(self, frames): # use this function to scale a 3D numpy array of floats to 0-255 so it plays well with Qt methods
# convert float array to uint8 array
if np.min(frames)<0:
frames_uint8 = [np.uint8((np.array(frames[i]) - np.min(frames[i]))/np.max(frames[i])*255) for i in range(np.shape(frames)[0])]
else:
frames_uint8 = [np.uint8(np.array(frames[i])/np.max(frames[i])*255) for i in range(np.shape(frames)[0])]
return frames_uint8
if __name__=='__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
这是输出的截图:
Qimage 与 matplotlib
这是一个正确显示的 tif 堆栈的链接:
https://drive.google.com/uc?export=download&id=0B9EG5AHWC9qzX3NrNTJRb2toV2c
这里有一个 tif 堆栈的链接,它在显示时会倾斜:
https://drive.google.com/uc?export=download&id=0B9EG5AHWC9qzbFB4TDU4c2x1OE0
任何帮助理解为什么QImage 歪曲这张图片将不胜感激。两个 tif 堆栈之间的唯一主要区别在于,倾斜显示的堆栈在图像周围有一个填充的黑色区域(零),这使得数组更大。
更新:我现在发现,如果我将有问题的图像裁剪为 1024x1024 或 512x512 或 1023x1024 QImage 会正确显示,但按 1024x1023 裁剪会显示倾斜。所以看起来 x(水平)长度必须是 2 的幂,以便QImage 按预期处理它。这是一个可笑的限制!一定有什么我不明白的。它肯定有办法处理任意形状的数组。
...我想,原则上,一个人可以先对图像应用倾斜,然后让QImage 将其倾斜回来...(
【问题讨论】:
-
@ekhumoro 我同意!那是我第一次使用该文件托管网站。我不会再使用它们了。我已将链接更新为直接下载。我也没有意识到这些文件有多大,这些新文件要轻得多。下载应该只需要一两秒钟。
-
谢谢。 FWIW,我可以重现该问题,但恐怕我目前对原因没有任何见解。
-
使用 QImage(fname)。 QImage 支持 Tiff。
-
@eyllanesc 使用
self.im = QImage(fname)确实可以正常显示!但是我如何访问堆栈中的其他图像?QImage似乎只读取了第一张图片。 -
另外,如果我每次都必须从 tif 文件中读取以使
QImage正确显示,那么这意味着我必须将数据写入磁盘并在每次我想要的时候读回更新图像。
标签: python matplotlib python-3.5 pyqt5 qimage