【问题标题】:How to update QLabel image correctly? [duplicate]如何正确更新 QLabel 图像? [复制]
【发布时间】:2021-03-19 21:03:55
【问题描述】:

我有一个名为 ImageLabel 的自定义 QLabel 类来显示图像和视频流。我想用setPixmap() 方法更新图像,但它不能正确更新图像。

注意:StreamThread 方法与视频流有关,我暂时不使用它来更新图像。

这是扭曲的图像:

主类:

import sys

from PyQt5.QtCore import Qt, pyqtSlot
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton, QHBoxLayout


from ImageLabel import ImageLabel
from Stream_Thread import Stream_Thread

import cv2

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.init_UI()


    def init_UI(self):
        self.setFixedSize(690, 530)
        self.image_lbl = ImageLabel()

        # start the video stream of selected camera
        th = Stream_Thread()
        th.set_index(1)
        th.changePixmap.connect(self.setImage, Qt.QueuedConnection)
        th.start()


        btn_cnt = QPushButton("Continue")
        btn_pa = QPushButton("Pause")

        hbox = QHBoxLayout()
        hbox.addWidget(btn_cnt)
        hbox.addWidget(btn_pa)

        vbox = QVBoxLayout()
        vbox.addWidget(self.image_lbl)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

        btn_pa.clicked.connect(lambda: self.btn_pa_clicked(th))

        self.show()


    @pyqtSlot(QImage)
    def setImage(self, image):
       self.image_lbl.pixmap = QPixmap.fromImage(image).scaled(720, 540)
       self.image_lbl.setPixmap(QPixmap.fromImage(image).scaled(720, 540))

    def btn_pa_clicked(self, th):
        th.terminate()                                                    # terminates the video stream

        image = cv2.imread("img/49.jpg", cv2.COLOR_BGR2RGB)  # self.image_lbl.pixmap
        # image = image.toImage()
        if image is not None:
            (h, w, c) = image.shape
            qimage = QImage(image.data, h, w, 3 * h, QImage.Format_RGB888)
            self.image_lbl.pixmap = QPixmap.fromImage(qimage)
            #self.image_lbl.setPixmap(QPixmap.fromImage(qimage))
            self.image_lbl.repaint()


def main():
    app = QApplication(sys.argv)
    main_form = MainWindow()
    sys.exit(app.exec_())



if __name__ == '__main__':
    main()

StreamThread 类:

import cv2
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtGui import QImage

#https://stackoverflow.com/a/44404713/13080899
class Stream_Thread(QThread):
    changePixmap = pyqtSignal(QImage)

    def __init__(self):
        super(Stream_Thread, self).__init__()
        self.ref = False        #refresh flag

    def set_index(self, index = 0):
        self.index = int(index)

    def refresh(self):
        self.ref = True
        self.capt.open(self.index)


    def run(self):
        self.capt = cv2.VideoCapture(self.index, cv2.CAP_DSHOW)

        while(True):
            ret, frame = self.capt.read()

            if ret:
                rbgImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                h, w, ch = rbgImage.shape
                bytesPerLine = ch*w
                convertToQtFormat = QImage(rbgImage.data, w, h, bytesPerLine, QImage.Format_RGB888)
                p = convertToQtFormat.scaled(640, 480, Qt.KeepAspectRatio)
                self.changePixmap.emit(p)

ImageLabel 类:

from PyQt5 import QtGui, QtCore
from PyQt5.QtCore import Qt, QSize, pyqtSignal, QObject, QPoint, pyqtSlot
from PyQt5.QtWidgets import QLabel

class Communicate(QObject):
    cor_update = pyqtSignal()
    cor_curr = pyqtSignal()

class ImageLabel(QLabel):
    def __init__(self, width=720, height=540):
        super(ImageLabel, self).__init__()
        self.setMouseTracking(True)
        self.pixmap = QtGui.QPixmap("img/im.jpg")

        #### initialize coordinates ####
        self.x1 = 0
        self.y1 = 0

        self.x_curr = 0
        self.y_curr = 0

        self.x2 = 0
        self.y2 = 0

        ##### enable state to allow user for drawing
        self.enable_labelling = False

        ##### enable state to track coordinates for drawing
        self.enable_cor = False

        ################################
        self.source = Communicate()

    def paintEvent(self, event):
        qp = QtGui.QPainter(self)
        qp.drawPixmap(self.rect(), self.pixmap)
        if self.enable_labelling == True:
            self.paintRect(event, qp)
            qp.end()

    def paintRect(self, event, qp):
        br = QtGui.QBrush(QtGui.QColor(50, 255, 255, 40))
        qp.setBrush(br)

        if self.enable_cor == True:
            qp.drawRect(QtCore.QRect(QPoint(self.x1, self.y1), QSize(self.x_curr - self.x1, self.y_curr - self.y1)))
        else:
            qp.drawRect(QtCore.QRect(QPoint(self.x1, self.y1), QSize(self.x2 - self.x1, self.y2 - self.y1)))

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton and self.enable_labelling == True:
            self.x1 = event.x()
            self.y1 = event.y()

            self.enable_cor = True

            self.source.cor_update.emit()

    def mouseMoveEvent(self, event):
        self.x_curr = event.x()
        self.y_curr = event.y()

        self.source.cor_curr.emit()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.enable_labelling == True:
            self.x2 = event.x()
            self.y2 = event.y()

            self.source.cor_update.emit()

            self.enable_cor = False

【问题讨论】:

    标签: python pyqt5


    【解决方案1】:

    不是通过 Imread 打开图像并将其转换为 QImage,而是通过 QImage 打开它并转换应该可以解决您的问题的格式。用途:

    image = QImage("img/49.jpg");
    image = image.convertToFormat(QImage.Format_RGB888);
    

    这是伪代码,未经测试,可能需要修改。

    【讨论】:

    • 这行得通,但我实际上有 NumPy 图像。所以问题是转换部分。如何正确地将图像 numpy 转换为 QImage?
    • 代码的哪一部分是转换部分?
    • (h, w, c) = image.shape qimage = QImage(image.data, h, w, 3 * h, QImage.Format_RGB888) 该部分在主类中,但现在可以使用。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2012-05-31
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多