Преобразование изображения Python Opencv (массив numpy) в изображение PyQt QPixmap

Я пытаюсь преобразовать изображение python opencv в QPixmap.

Я следую инструкциям, которые показывают Ссылка на страницу и мой код прикреплен ниже

img = cv2.imread('test.png')[:,:,::1]/255. 
imgDown = cv2.pyrDown(img)
imgDown = np.float32(imgDown)        
cvRGBImg = cv2.cvtColor(imgDown, cv2.cv.CV_BGR2RGB)
qimg = QtGui.QImage(cvRGBImg.data,cvRGBImg.shape[1], cvRGBImg.shape[0], QtGui.QImage.Format_RGB888)
pixmap01 = QtGui.QPixmap.fromImage(qimg)
self.image01TopTxt = QtGui.QLabel('window',self)
self.imageLable01 = QtGui.QLabel(self)
self.imageLable01.setPixmap(pixmap01)

В коде нет ошибок компиляции и времени выполнения, но преобразование неверно, и я просто получаю шумовое изображение. Я не уверен, в чем проблема. Может ли кто-нибудь помочь?


person SimaGuanxing    schedule 11.12.2015    source источник


Ответы (5)


Используйте это, чтобы преобразовать cvImage в Qimage, здесь cvImage — исходное изображение.

height, width, channel = cvImg.shape
bytesPerLine = 3 * width
qImg = QImage(cvImg.data, width, height, bytesPerLine, QImage.Format_RGB888)

и установите для этого Qimage значение Label.setPixmap из Qimage . Оно работает!!!

person AdityaIntwala    schedule 08.03.2016
comment
Мне пришлось создать QPixmap явно: self.imageLable01.setPixmap(QPixmap(qImg)) и передать bytesPerLine + 1 - person jfs; 05.06.2018
comment
Любая документация, в которой упоминается формат numpy, всегда RGB888? - person Overdrivr; 09.10.2018
comment
Не всегда должен быть RGB888, из документов qt5, doc. qt.io/qt-5/qimage.html#image-formats список поддерживаемых форматов. Конечно, вам нужно убедиться, что ваш массив numpy имеет правильные данные. - person Mark Carpenter Jr; 02.01.2020
comment
@MarkCarpenterJr Есть ли способ определить, какой формат изображения мне нужен? Пробовал несколько по вашей ссылке, но ни один не работает. - person Matthias; 12.05.2020
comment
@Matthias Вы можете сначала попробовать преобразовать в определенный формат, а затем создать файл QImage(). Вы также можете посмотреть на кортеж в массиве и догадаться об определении формата, например, RGB888 имеет 8 бит на пиксель и считается 24-битным форматом, пиксель будет выглядеть как 3 8-битных значения; (255 255 255). Хотя все зависит от того, чем вы занимаетесь. - person Mark Carpenter Jr; 12.05.2020

Просто дополняя ответ AdityaIntwala, если изображение кажется красным или синим, это потому, что формат не RGB, а BGR (обратный). В этом случае используйте метод QImage.rgbSwapped для исправления:

height, width, channel = cvImg.shape
bytesPerLine = 3 * width
qImg = QImage(cvImg.data, width, height, bytesPerLine, QImage.Format_RGB888).rgbSwapped()
person Sergio Montazzolli    schedule 11.06.2018

Ненавижу добавлять к большому количеству ответов, но, поскольку это было единственное, что сработало для меня, я сделаю это, если другие столкнутся с той же проблемой.

Как упоминалось здесь, на GitHub

Сначала оберните массив numpy/ndarry вызовом np.require(array, np.uint8, 'C'), например:

arr2 = np.require(arr, np.uint8, 'C')
qImg = QtGui.QImage(arr2, width, height, QtGui.QImage.Format_RGB888)
person so860    schedule 30.05.2019

Вот мой взгляд на это:

def convert_nparray_to_QPixmap(self,img):
    w,h,ch = img.shape
    # Convert resulting image to pixmap
    if img.ndim == 1:
        img =  cv2.cvtColor(img,cv2.COLOR_GRAY2RGB)

    qimg = QImage(img.data, h, w, 3*h, QImage.Format_RGB888) 
    qpixmap = QPixmap(qimg)

    return qpixmap
person Ivan    schedule 04.12.2020

Есть самый простой способ:

from PIL.ImageQt import ImageQt 
from PIL import Image
from PySide2.QtGui import QPixmap
import cv2


# Convert an opencv image to QPixmap
def convertCvImage2QtImage(cv_img):
    rgb_image = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
    PIL_image = Image.fromarray(rgb_image).convert('RGB')
    return QPixmap.fromImage(ImageQt(PIL_image))
person Sajjad Aemmi    schedule 24.12.2020