首页 > 解决方案 > 将 numpy 图像转换为 QPixmap

问题描述

我是计算机科学专业的学生,​​我正在学习使用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_boxsecond image.

标签: pythonnumpyopencvpyqtpyqt5

解决方案


您必须使用该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)

推荐阅读