如何正确地将大小调整后的图像从opencv转换为pyqt5?

cetgtptt  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(141)

目标:

我正在尝试使用PyQt5显示一个使用OpenCV编辑的图像。

上图显示了我的预期输出(从openCV窗口显示)和PyQt5 Label Pixmap中显示的实际输出的并排比较。
图片显示图像已成功调整大小,但未正确显示。

关于QLabel(用于显示图片):

QLabel位于Frame中。它的定义如下:

self.ImageDisplayerLB = QtWidgets.QLabel(self.topFrame) #topFrame is a QFrame
        self.ImageDisplayerLB.setEnabled(True)
        self.ImageDisplayerLB.setText("")
        self.ImageDisplayerLB.setPixmap(QtGui.QPixmap("./<image>.jpg"))
        self.ImageDisplayerLB.setAlignment(QtCore.Qt.AlignCenter)
        self.ImageDisplayerLB.setObjectName("ImageDisplayerLB")
        self.gridLayout_2.addWidget(self.ImageDisplayerLB, 0, 0, 1, 1)

关于QLabel中使用的QFrame:

QFrame确实设置了 * 最小高度和宽度**(大小)*,因此在显示图像时看起来不会太小。

self.topFrame = QtWidgets.QFrame(self.frame)
        self.topFrame.setMinimumSize(QtCore.QSize(831, 409))
        self.topFrame.setStyleSheet("background-color: rgb(1,1,1);")
        self.topFrame.setObjectName("topFrame")
        self.topFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.topFrame.setFrameShadow(QtWidgets.QFrame.Raised)

在处理事件时,Pixmap再次被不同的函数调用设置。下面的代码片段似乎是错误发生的地方。

if hw := self.__check_oversized_image(image): # Returns height, width if image is larger than the QLabel size, else returns None.
            w, h = self.ImageDisplayerLB.width(), self.ImageDisplayerLB.height()
            self.ImageDisplayerLB.pixmap().detach() # Tried the same without it, makes no difference

            thresh = min((self.ImageDisplayerLB.width(), self.ImageDisplayerLB.height()))

            r = thresh / image.shape[1]
            dim = (thresh, int(image.shape[0] * r))
            image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA) # Resize Image maintaining the ratio

            self.ImageDisplayerLB.setScaledContents(True) # Makes no difference with or without this

# End of if block
        frame = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        self.qimage = QtGui.QImage(
            frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888
        )
        try:
            self.pimage = QtGui.QPixmap.fromImage(self.qimage, QtCore.Qt.AutoColor)
            self.ImageDisplayerLB.setPixmap(self.pimage)
        except Exception as e:
            print(e)

什么时候发生?

这个问题只是当图像被发现超大,我正在修改图像。它工作正常,没有图像超大。
任何帮助,以解决问题的图像是grayscale和倾斜。

最小可复制代码:

from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import QMainWindow
import cv2 as cv

class main(QMainWindow):
    def __init__(self):
        super().__init__()
        self.mainFrame = QtWidgets.QFrame(self)
        self.grid = QtWidgets.QGridLayout(self.mainFrame)
        self.label = QtWidgets.QLabel(self.mainFrame)
        img = cv.imread("cert_template.png")  # Image from -> https://simplecert.net/certificate-templates/
        frame = img.copy()
        self.label.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(frame.data,frame.shape[1],frame.shape[0],QtGui.QImage.Format_RGB888,))) # Not sure why this is grayscale and tilted
        self.mainFrame.setMinimumSize(QtCore.QSize(831, 409))
        self.label.setScaledContents(True)
        self.grid.addWidget(self.label, 0, 0, 1, 1)
        cv.imshow("image", img) # Displays the predicted output
        cv.waitKey(0) 

if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    window = main()
    window.show()
    app.exec_()

非常感谢。

juzqafwq

juzqafwq1#

bytesPerLine作为3 * img.shape[1]传入QImage构造函数:

QtGui.QImage(img, img.shape[1], img.shape[0], 3 * img.shape[1], QtGui.QImage.Format_BGR888)

最小工作示例:

from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import QWidget, QLabel
import cv2

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

        img = cv2.imread("cert_template.png")

        qt5_img = QtGui.QImage(img, img.shape[1], img.shape[0], 3 * img.shape[1], QtGui.QImage.Format_BGR888)
        pixmap = QtGui.QPixmap.fromImage(qt5_img)

        self.image_label = QLabel(self)
        self.image_label.setPixmap(pixmap)

        self.showMaximized()

if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    window = MainWindow()
    app.exec_()

相关问题