【问题标题】:Converting numpy image to QPixmap将 numpy 图像转换为 QPixmap
【发布时间】:2019-10-13 18:48:02
【问题描述】:

我是计算机科学专业的学生,​​我正在使用 OpenCvPython 学习图像处理。我正在使用眼周区域进行性别检测。我在浏览图像时遇到问题;裁剪代码工作正常,但在界面上输出未按要求显示。

我搜索了解决方案并申请了各种Qimage-Format,但都无法正常工作。

如果你能帮助我,我将不胜感激。

我已附上代码以及当前输出和所需的输出,我还将附上,以便让问题更清晰易懂

from PyQt5 import QtGui,QtWidgets,QtCore,uic
from PyQt5.QtWidgets import QApplication,QMainWindow,QPushButton,QMessageBox,QStatusBar
from PyQt5.QtCore import QCoreApplication

import sys
import cv2

IMAGE_1=0
class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super(Window,self).__init__()
        uic.loadUi('Welcome1.ui',self)
        self.title="Gender_Identifier"

        self.setWindowIcon(QtGui.QIcon("main-logo.png"))
#        self.browse_button.clicked.connect(self.setimage)
 #       self.roi_button.clicked.connect(self.crop)
        self.work_IMAGE=None
        self.browse_button.clicked.connect(self.setimage)
        self.roi_button.clicked.connect(self.crop)

        button=QPushButton("close",self)
        button.clicked.connect(self.close)

        self.InitWindow()

        #IMAGE=self.set_image()
    def InitWindow(self):

        self.statusBar().showMessage("This is a simple status bar")
        self.setWindowTitle(self.title)

    def file(self):

        fileName ,_ =QtWidgets.QFileDialog.getOpenFileName(None,"Select Image", "D:\python_data\interface","Image Files (*.png *.jpg)")
        return fileName

    def setimage(self):
        fileName ,_ =QtWidgets.QFileDialog.getOpenFileName(None,"Select Image", "D:\python_data\interface\images\preprocessed","Image Files (*.png *.jpg)")

        if fileName:
            #pixmap object
            pixmap=QtGui.QPixmap(fileName)
            pixmap=pixmap.scaled(self.browse_label.width(),self.browse_label.height(),QtCore.Qt.KeepAspectRatio)
            self.browse_label.setPixmap(pixmap)
            self.browse_label.setAlignment(QtCore.Qt.AlignCenter)
            if(fileName):
                self.work_IMAGE=fileName
    def crop(self):
        if(self.work_IMAGE):
            file=self.work_IMAGE
            img = cv2.imread(file, 0)

            height,width=img.shape[:2]
            start_row,strt_col=int(height*.40),int(width*.15)
            end_row,end_col=int(height*.60),int(width*.90)
            croped=img[start_row:end_row,strt_col:end_col].copy()
            #cv2.imshow("img",croped)
            image = QtGui.QImage(croped, croped.shape[0], croped.shape[1], QtGui.QImage.Format_RGB888)
            pixmap = QtGui.QPixmap(image)
            print(type(image))
            print(type(pixmap))
            print(type(croped))
            #cv2.imshow("img",croped)

            pixmap=pixmap.scaled(self.roi_label.width(),self.roi_label.height(),QtCore.Qt.KeepAspectRatio)
            cv2.imshow("img",croped)
            self.roi_label.setPixmap(pixmap)
            self.roi_label.setAlignment(QtCore.Qt.AlignCenter)


if __name__=='__main__':

    App=QtWidgets.QApplication(sys.argv)
    window=Window()
   # IMAGE=window.setimage()
    #window.crop(IMAGE)
   # IMAGE_1=IMAGE
    #print(IMAGE)
    #print(IMAGE_1)
    window.show()
    sys.exit(App.exec_())

当用户点击 "Region of Interest" 按钮时我需要; lable_box 应仅显示裁剪后的图像,如 second image.

所示

【问题讨论】:

    标签: python numpy opencv pyqt pyqt5


    【解决方案1】:

    您必须使用QImage::Format_Indexed8 格式将numpy 数组转换为QImage。我已经实现了一种将某些类型的 numpy 数组转换为 QImage 的方法

    def numpyQImage(image):
        qImg = QtGui.QImage()
        if image.dtype == np.uint8:
            if len(image.shape) == 2:
                channels = 1
                height, width = image.shape
                bytesPerLine = channels * width
                qImg = QtGui.QImage(
                    image.data, width, height, bytesPerLine, QtGui.QImage.Format_Indexed8
                )
                qImg.setColorTable([QtGui.qRgb(i, i, i) for i in range(256)])
            elif len(image.shape) == 3:
                if image.shape[2] == 3:
                    height, width, channels = image.shape
                    bytesPerLine = channels * width
                    qImg = QtGui.QImage(
                        image.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888
                    )
                elif image.shape[2] == 4:
                    height, width, channels = image.shape
                    bytesPerLine = channels * width
                    fmt = QtGui.QImage.Format_ARGB32
                    qImg = QtGui.QImage(
                        image.data, width, height, bytesPerLine, QtGui.QImage.Format_ARGB32
                    )
        return qImg
    

    所以在你的情况下应该是:

    def crop(self):
        if not self.work_IMAGE:
            return
        img = cv2.imread(self.work_IMAGE, cv2.IMREAD_GRAYSCALE)
        if img is None:
            return
        height, width = img.shape[:2]
        start_row, strt_col = int(height * 0.40), int(width * 0.15)
        end_row, end_col = int(height * 0.60), int(width * 0.90)
        croped = img[start_row:end_row, strt_col:end_col].copy()
        qImg = numpyQImage(croped)
        pixmap = QtGui.QPixmap.fromImage(qImg)
        pixmap = pixmap.scaled(self.roi_label.size(), QtCore.Qt.KeepAspectRatio)
        self.roi_label.setPixmap(pixmap)
        self.roi_label.setAlignment(QtCore.Qt.AlignCenter)
    

    【讨论】:

    • 我正在实现这个..但它给了我错误(名称'numpyQImage'未定义)......虽然我已经定义了两个..
    • 是的,先生..我正在尝试解决这个问题,但我找不到解决方案
    • 我对 Pyside2 v5.12.0 及更高版本的这个答案有一些问题。在函数范围内创建 QImage 并按值返回似乎不适用于 Qt 的隐式数据共享,它适用于 QImage 并且是一种允许按值传递但最小化复制的方法。在两个不同的图像上使用这个函数,我让第二个的结果覆盖了内存中第一个的结果。这是一个非常有用的起点,只需将结果直接保存到成员变量或全局而不是从函数返回
    猜你喜欢
    • 1970-01-01
    • 2016-03-17
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    相关资源
    最近更新 更多