【问题标题】:Unable to Display Image in my PyQt program无法在我的 PyQt 程序中显示图像
【发布时间】:2022-02-21 17:19:51
【问题描述】:

我正在尝试编写一个程序,将 2 个图像与一个函数(使用 cv2)混合在一起,然后使用 PyQT 编写的 GUI 将其显示在屏幕上,所以我的第一次尝试是执行以下操作

imgComb = self.mergeimages(img1,img2)
self.label.setPixmap(QtGui.QPixmap(imgComb))

但是以下代码不起作用,因为 setPixMap 不采用 Numpy Arrays 对象,因此建议我改用 setpixmap.fromimage 并将 Numpy Array 转换为 Image,并将 Image 转换为 QTImage ,如下所示代码

imgComb = self.mergeimages(img1,img2)
img3 = Image.fromarray(imgComb)
img4 = ImageQt(img3)
self.label.setPixmap(QtGui.QPixmap.fromImage(img4))

但是,以下代码使 python 彻底崩溃,而没有给出任何错误代码并给出退出代码:3221225477 如果我将图像保存到我的 HDD 中然后加载它,代码就可以工作,但是我想避免这样做,当我试图弄清楚为什么会有这样的差异时,我注意到我创建的图像是 PIL 类型的对象.Image.Image 但是当从我的硬盘加载时它变成了 PIL.PngImagePlugin.PngImageFile 类型 在寻找解决方案时,我发现了一个似乎有类似问题的人,尽管他的问题没有令人满意的答案 Why can't I make a GIF from PIL.Image.Image files but can with PIL.PngImagePlugin.PngImageFile? 我该怎么做才能解决这个问题?

编辑:完整代码

from PyQt5 import QtCore, QtGui, QtWidgets
import random
import cv2
from PIL import Image
from PIL.ImageQt import ImageQt



class Ui_MainWindow(object):
    
    def mergeimages(self,img1,img2):

        img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
        ret, mask = cv2.threshold(img2_gray, 245, 255, cv2.THRESH_BINARY)
        mask_inv = cv2.bitwise_not(mask)
        Attack = cv2.bitwise_and(img1, img1, mask=mask)
        Defense = cv2.bitwise_and(img2, img2, mask=mask_inv)
        result = cv2.add(Defense,Attack)
        return result
    
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1000, 900)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(190, 20, 674, 478))
        self.label.setStyleSheet("ImageCombined.png")
        self.label.setText("")
        img1 = cv2.imread("Image1.png")
        img2 = cv2.imread("Image2.png")
        img2 = cv2.flip(img2,1)
        imgComb = self.mergeimages(img1,img2)
        img3 = Image.fromarray(imgComb)
        img4 = ImageQt(img3)
        self.label.setPixmap(QtGui.QPixmap.fromImage(img4))
        self.label.setScaledContents(True)
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralwidget)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

我要做的就是在我的 GUI 中心显示生成的 imgComb

【问题讨论】:

  • 请提供minimal reproducible example。你不是在尝试使用线程,是吗?
  • 添加了完整代码
  • 我已经在mergeimages 函数中收到来自opencv 的错误,特别是第一行bitwise_and。在任何情况下,从终端或提示符运行您的代码以查看完整的回溯。
  • 我能够找到解决方案,方法是使用此处描述的代码将 numpy 数组转换为 QPixmap stackoverflow.com/questions/34232632/…

标签: python image opencv pyqt


【解决方案1】:

以下是如何将 cv2 图像转换为像素图

h, w, ch = cv2_image.shape

bytes_per_line = ch * w
converted = QtGui.QImage(imgComb.data, w, h, bytes_per_line, QtGui.QImage.Format_RGB888)

converted = converted.scaled(target_width, target_height, Qt.KeepAspectRatio) # Only if you want to scale image

pic = QtGui.QPixmap.fromImage(converted)
#pic is pixmap which can directly be set to QLabel

这是您的更新代码

from PyQt5 import QtCore, QtGui, QtWidgets
import random
import cv2



class Ui_MainWindow(object):

    def mergeimages(self, img1, img2):
        img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
        ret, mask = cv2.threshold(img2_gray, 245, 255, cv2.THRESH_BINARY)
        mask_inv = cv2.bitwise_not(mask)
        Attack = cv2.bitwise_and(img1, img1, mask=mask)
        Defense = cv2.bitwise_and(img2, img2, mask=mask_inv)
        result = cv2.add(Defense, Attack)
        return result

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1000, 900)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(190, 20, 674, 478))
        self.label.setStyleSheet("ImageCombined.png")
        self.label.setText("")
        img1 = cv2.imread("Image1.png")
        img2 = cv2.imread("Image2.png")
        img2 = cv2.flip(img2, 1)
        imgComb = self.mergeimages(img1, img2)
# Change Start
        h, w, ch = imgComb.shape

        bytes_per_line = ch * w
        converted = QtGui.QImage(imgComb.data, w, h, bytes_per_line, QtGui.QImage.Format_RGB888)

        pic = QtGui.QPixmap.fromImage(converted)


        self.label.setPixmap(pic)
# Change End
        self.label.setScaledContents(True)
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralwidget)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

【讨论】:

    猜你喜欢
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 2017-10-11
    相关资源
    最近更新 更多