QLabel 在 OpenCV 图像处理后没有更新图像

QLabel is not updating the image after OpenCV image manipulation

我一直在尝试创建一个交互式 OpenCV 图像查看器,以便我能够在处理后立即查看图像。比如说,我在图像上应用二进制阈值操作并从 PyQt 滑块更改阈值。现在,我想在图像查看器中查看每个阈值图像。

我为此使用 python OpenCV 和 PyQT5 库创建了一个非常基本的程序。但是,图像没有在 QLabel 中更新。

下面是我的代码:

import sys
import cv2
import numpy as np
import imutils
from PyQt5 import QtCore
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QLCDNumber, QSlider, QLabel, QCheckBox
from PyQt5.QtGui import QPixmap, QImage


class MyWindow(QWidget):

def __init__(self):
    super().__init__()
    self.imglabel = QLabel(self)
    self.imglabel.setFixedSize(1200, 900)
    ori_img = cv2.imread("../resources/omr-1-ans-ori.png", cv2.IMREAD_COLOR)
    ori_img = imutils.resize(ori_img, height=960)
    self.gray_img = cv2.cvtColor(ori_img, cv2.COLOR_BGR2GRAY)
    self.gray_img_c = ori_img

    self.thresh = False
    self.thresh_karnel_size = 11

    self.init_ui()

def init_ui(self):
    # lcd = QLCDNumber(self)
    hbox1 = QHBoxLayout()
    cb_thresh = QCheckBox('thresh', self)
    cb_thresh.setChecked(False)

    cb_thresh.stateChanged.connect(self.changeTitleThresh)
    hbox1.addWidget(cb_thresh)

    thresh_slider = QSlider(Qt.Horizontal, self)
    thresh_slider.setFocusPolicy(Qt.StrongFocus)
    thresh_slider.setTickPosition(QSlider.TicksBothSides)
    thresh_slider.setTickInterval(1)
    thresh_slider.setSingleStep(1)
    thresh_slider.setPageStep(1)
    thresh_slider.setMinimum(1)
    thresh_slider.setMaximum(127)
    thresh_slider.valueChanged[int].connect(self.threshSliderChangeValue)

    vbox = QVBoxLayout()
    vbox.addLayout(hbox1)
    vbox.addWidget(thresh_slider)
    vbox.addWidget(self.imglabel)
    self.setLayout(vbox)

    self.setGeometry(50, 50, 1200, 768)
    self.setWindowTitle('Learning PyQT5')
    self.updateImage()
    self.show()

def changeTitleThresh(self, state):
    # print("thresh checkbox: ", state, Qt.Checked)
    if state == Qt.Checked:
        self.thresh = True
    else:
        self.thresh = False

def threshSliderChangeValue(self, value):

    ksize = (value * 2) + 1
    print("ksize: ", ksize)
    if ksize > 1 and ksize % 2 != 0 and self.thresh:
        self.thresh_karnel_size = ksize
        self.gray_img = cv2.threshold(self.gray_img, self.thresh_karnel_size, 255, cv2.THRESH_BINARY)[1]
        self.gray_img_c = cv2.cvtColor(self.gray_img.copy(), cv2.COLOR_GRAY2BGR)
        self.updateImage()

def updateImage(self):

    height, width, channel = self.gray_img_c.shape
    bytesPerLine = 3 * width
    qImg = QImage(self.gray_img_c.data, width, height, bytesPerLine, QImage.Format_RGB888)
    pixMap = QPixmap.fromImage(qImg)
    pixMap = pixMap.scaled(700, 500, Qt.KeepAspectRatio)
    self.imglabel.setPixmap(pixMap)
    self.imglabel.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyWindow()
    sys.exit(app.exec_())

我已经尝试了通过 google 搜索找到的所有解决方案。但是,无法修复它。 任何帮助或提示将不胜感激。

原始图像必须保持完整,但您每次都在应用滤镜并修改它,在下面的示例中我将展示正确的方法

import sys
import cv2
import imutils
from PyQt5 import QtCore, QtGui, QtWidgets


class MyWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        ori_img = cv2.imread("../resources/omr-1-ans-ori.png", cv2.IMREAD_COLOR)
        self.original_image_color = imutils.resize(ori_img, height=960)
        self.original_image_gray = cv2.cvtColor(self.original_image_color, cv2.COLOR_BGR2GRAY)

        self.thresh = False
        self.thresh_karnel_size = 11

        self.init_ui()

    def init_ui(self):
        self.imglabel = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
        self.imglabel.setFixedSize(1200, 900)

        cb_thresh = QtWidgets.QCheckBox('thresh', checked=False)
        cb_thresh.stateChanged.connect(self.changeTitleThresh)

        self.thresh_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal, 
            focusPolicy=QtCore.Qt.StrongFocus,
            tickPosition=QtWidgets.QSlider.TicksBothSides,
            tickInterval=1,
            singleStep=1,
            pageStep=1,
            minimum=1,
            maximum=127)
        self.thresh_slider.valueChanged[int].connect(self.threshSliderChangeValue)

        vbox = QtWidgets.QVBoxLayout(self)
        vbox.addWidget(cb_thresh)
        vbox.addWidget(self.thresh_slider)
        vbox.addWidget(self.imglabel)
        self.threshSliderChangeValue(self.thresh_slider.value())
        self.setGeometry(50, 50, 1200, 768)
        self.setWindowTitle('Learning PyQT5')
        self.show()

    @QtCore.pyqtSlot(int)
    def changeTitleThresh(self, state):
        self.thresh = state == QtCore.Qt.Checked
        self.threshSliderChangeValue(self.thresh_slider.value())

    @QtCore.pyqtSlot(int)
    def threshSliderChangeValue(self, value):
        ksize = (value * 2) + 1
        if ksize > 1 and ksize % 2 != 0 and self.thresh:
            self.thresh_karnel_size = ksize
            _, gray_img = cv2.threshold(self.original_image_gray, self.thresh_karnel_size, 255, cv2.THRESH_BINARY)
            gray_img_c = cv2.cvtColor(gray_img.copy(), cv2.COLOR_GRAY2BGR)
            self.updateImage(gray_img_c)
        else:
            self.updateImage(self.original_image_color)

    def updateImage(self, image):
        height, width, channel = image.shape
        bytesPerLine = 3 * width
        qImg = QtGui.QImage(image.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)
        pixMap = QtGui.QPixmap.fromImage(qImg).scaled(700, 500, QtCore.Qt.KeepAspectRatio)
        self.imglabel.setPixmap(pixMap)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = MyWindow()
    sys.exit(app.exec_())