Je travaille avec des piles de tif et QImage
semble déformer certaines images à un angle de 45 degrés. Matplotlib est capable d'afficher les images sans problème dans les deux cas de test (les liens vers les deux piles tif sont fournis ci-dessous), donc je ne pense pas que je me sois trompé de tableau quelque part.
Voici un exemple de travail : (NOTE : cet exemple ne montre que la première image de la pile tif pour plus de simplicité)
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_())
Voici une capture d'écran de la sortie :
Qimage vs matplotlib
Voici un lien vers une pile tif qui s'affiche correctement :
https://drive.google.com/uc?export=download&id=0B9EG5AHWC9qzX3NrNTJRb2toV2c
Et voici un lien vers une pile tif qui devient oblique lorsqu'elle est affichée :
https://drive.google.com/uc?export=download&id=0B9EG5AHWC9qzbFB4TDU4c2x1OE0
Une aide pour comprendre pourquoi QImage
fausse cette image serait très appréciée. La seule différence majeure entre les deux piles tif est que celle qui s'affiche de travers a une zone noire (zéros) autour de l'image, ce qui rend le tableau plus grand.
MISE À JOUR : J'ai découvert que si je recadre l'image en question à 1024x1024 ou 512x512 ou 1023x1024 QImage
s'affiche correctement mais le recadrage en 1024x1023 s'affiche de manière biaisée. Il apparaît donc que la longueur x (horizontale) doit être une puissance de 2 afin que QImage
pour le traiter comme prévu. C'est une limitation ridicule ! Il doit y avoir quelque chose que je ne comprends pas. Il y a sûrement un moyen de gérer des tableaux de forme arbitraire.
...Je suppose qu'en principe, on pourrait d'abord appliquer une inclinaison à l'image et simplement laisser QImage
le redresser... (<== pas fan de cette solution)