当前位置:  开发笔记 > 编程语言 > 正文

QImage倾斜一些图像,但不倾斜其他图像

如何解决《QImage倾斜一些图像,但不倾斜其他图像》经验,为你挑选了1个好方法。

我正在使用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校正...(<==不是此解决方案的支持者)



1> onjre..:

非常感谢bnaecker提供的32位对齐提示,并提供了到源的链接。这是解决方案。

QImage需要知道数组每行有多少个字节,否则它只会猜测(在某些情况下会猜错)。因此,在loadImage()函数中使用以下命令将产生正确的输出。

# get the shape of the array
nframes, height, width = np.shape(self.dataUint8)

# calculate the total number of bytes in the frame 
totalBytes = self.dataUint8[0].nbytes

# divide by the number of rows
bytesPerLine = int(totalBytes/height)

# create a QImage object 
self.im = QImage(self.dataUint8[0], width, height, bytesPerLine, QImage.Format_Grayscale8)

其余代码相同。

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有