¿Cómo configurar el color al convertir una matriz numpy CV2 a QImage?

El progtwig está basado en pyqt y opencv. Planeo leer y procesar imágenes con opencv mientras uso QT como GUI.

Cuando abro una imagen gris, el resultado es correcto. Pero cambiará el color de la imagen al abrir una imagen en color. Supongo que es porque cometí un error al convertir la matriz numpy al tipo OImage, pero no puedo averiguar cómo corregirlo.

# -*- coding: utf-8 -*- from PyQt4.QtGui import * from PyQt4.QtCore import * import sys import cv2 from cv2 import cv QTextCodec.setCodecForTr(QTextCodec.codecForName("utf8")) class MainWindow(QMainWindow): def __init__(self,parent=None): super(MainWindow,self).__init__(parent) self.setWindowTitle("Show Image with pyqt") self.imageLabel=QLabel() self.imageLabel.setSizePolicy(QSizePolicy.Ignored,QSizePolicy.Ignored) self.setCentralWidget(self.imageLabel) self.image=QImage() self.createActions() self.createMenus() self.cv_img = None def createActions(self): self.fileOpenAction=QAction(QIcon(":/fileopen.png"),self.tr("Open"),self) self.fileOpenAction.setShortcut("Ctrl+O") self.fileOpenAction.setStatusTip(self.tr("Open the file")) self.connect(self.fileOpenAction,SIGNAL("triggered()"),self.slotOpenFile) self.exitAction=QAction(QIcon(":/filequit.png"),self.tr("Quit"),self) self.exitAction.setShortcut("Ctrl+Q") self.setStatusTip(self.tr("Quit")) self.connect(self.exitAction,SIGNAL("triggered()"),self.close) def createMenus(self): fileMenu=self.menuBar().addMenu(self.tr("File")) fileMenu.addAction(self.fileOpenAction) fileMenu.addAction(self.exitAction) def slotOpenFile(self): fileName=QFileDialog.getOpenFileName(self,self.tr("Open a file"),\ ".",self.tr("Image File(*.png *.jpg *.jpeg *.bmp)")) cvfilename=fileName.toLocal8Bit().data() if fileName.isEmpty()==False: cvfilename=fileName.toLocal8Bit().data() #convert Qstring to char* self.cv_img = cv2.imread(cvfilename) #read image with opencv cv2.imshow("Show Image with Opencv",self.cv_img) #show image with opencv, this is the right result self.image =QImage(self.cv_img.tostring(),\ self.cv_img.shape[0],self.cv_img.shape[1],QImage.Format_RGB888) #convert numpy array to QImage self.imageLabel.setPixmap(QPixmap.fromImage(self.image)) self.resize(self.image.width(),self.image.height()) app=QApplication(sys.argv) main=MainWindow() main.show() app.exec_() 

Aquí está el resultado con la imagen en color, el color de la imagen cambia cuando se muestra con QT, pero está bien con un simple opencv

Es necesario convertir los datos de imagen de BGR a RGB. También debe intercambiar ancho y alto (ver más abajo): su código solo funciona para imágenes con el mismo ancho y alto.

 self.cv_img = cv2.imread(cvfilename) if self.cv_img != None: # Notice the dimensions. height, width, bytesPerComponent = cv_img.shape bytesPerLine = bytesPerComponent * width; cv2.imshow("Show Image with Opencv", self.cv_img) # Convert to RGB for QImage. cv2.cvtColor(self.cv_img, cv.CV_BGR2RGB, self.cv_img) self.image = QImage(self.cv_img.data, width, height, bytesPerLine, QImage.Format_RGB888) 

Sé que este es un tema bastante antiguo, pero para mí cv2.cvtColor funciona muy lento. Encontré otra función que puede ayudar a aquellos que la necesitarán en el futuro (me tomó una eternidad encontrar este remedio):

 def cv2_to_qimage(cv_img): height, width, bytesPerComponent = cv_img.shape bgra = np.zeros([height, width, 4], dtype=np.uint8) bgra[:, :, 0:3] = cv_img return QtGui.QImage(bgra.data, width, height, QtGui.QImage.Format_RGB32) 

Espero que lo encuentres útil

El siguiente código tiene una actualización de filtro de color para las versiones de openCV3.x. Código de ejemplo proviene de hluk .

 import cv2 from cv2 import CV ...... self.cv_img = cv2.imread(cvfilename) if self.cv_img != None: # Notice the dimensions. height, width, bytesPerComponent = cv_img.shape bytesPerLine = bytesPerComponent * width; cv2.imshow("Show Image with Opencv", self.cv_img) # Convert to RGB for QImage. cv2.cvtColor(self.cv_img, cv2.COlOR_BGR2RGB, self.cv_img) self.image = QImage(self.cv_img.data, width, height, bytesPerLine, QImage.Format_RGB888)