28

I am trying to convert python opencv image to QPixmap.

I follow the instruction shows Page Link and my code is attached below

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)

The code has no compile and runtime error but the conversion is wrong and I just get some noise image. I am not sure what the problem is. Could anyone help?

9 Answers 9

49

Use this to convert cvImage to Qimage, here cvImage is the original image.

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

and set this Qimage to Label.setPixmap parameter from Qimage. It works!!!

Sign up to request clarification or add additional context in comments.

8 Comments

I had to create QPixmap explicitly: self.imageLable01.setPixmap(QPixmap(qImg)) and pass bytesPerLine + 1
Any documentation that mentions numpy format is always RGB888 ?
Doesn't always have to be RGB888, from teh qt5 docs, doc.qt.io/qt-5/qimage.html#image-formats a list of supported formats. Of course, you'll have to make sure your numpy array has the right data.
@MarkCarpenterJr Is there any way to determine which image format I need? Tried several from your link but none works.
With OpenCV you want to use QImage.Format_BGR888 as OpenCV uses BGR, not RGB.
|
23

Just complementing the answer of AdityaIntwala, if the image appears to be red or blue, it is because the format is not RGB, but BGR (the inverse). In this case, use the QImage.rgbSwapped method to correct:

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

1 Comment

If you've got channel as a variable, why hardocde 3 in there?
8
#image is the numpy array that you got from cv2.imread(example_image.jpg)

image = QtGui.QImage(image, image.shape[1],\
                            image.shape[0], image.shape[1] * 3,QtGui.QImage.Format_RGB888)
pix = QtGui.QPixmap(image)

self.scene.addPixmap(pix)

Comments

6

Hate to add to the large number of answers, but as this was the only thing that worked for me I will, in case others run into the same issue.

As mentioned here on GitHub

Wrap the numpy array/ndarry in a np.require(array, np.uint8, 'C') call first, such as:

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

Comments

3

There is the easiest way:

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))

Comments

2

Here's my take on this:

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

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

    return qpixmap

1 Comment

This is incorrect. img.shape is [h, w, (channels)] and bytesPerLine = channels * width. Also note QImage(data, width, height, (bytesPerLine), QImage.Format)
1

AdityaIntwala's answer was close but it didnt work for me. the cvImg.data gave an error like 'argument 1 has unexpected type 'memoryview'. So I have removed the 'cvImg.data' and passed the cvImg.tobytes() as bytes, and it worked

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

then I have set the pixmap as shown below

self.imageLabel.setPixmap(QPixmap(qImg))

Comments

0
  image=cv2.imread("your_image.png")
  image = QtGui.QImage(image, image.shape[1],image.shape[0], image.shape[1] * 3, QtGui.QImage.Format_BGR888)
  pix = QtGui.QPixmap(image)
  self.image.setPixmap(QtGui.QPixmap(pix))

1 Comment

Hi and welcome to stack overflow, posting an answer with only a code block is not recommended, its better to have some text around it explaining how and why this works
0

When using OpenCV to read an image, the output is in BGR format. However, before running QImage, you need to convert BGR to RGB.

Please convert using cv2.cvtColor(img,cv2.COLOR_BGR2RGB). If you convert BGR to RGB using other solutions, such as img = img[:,:,(2,1,0)], it may not be complete.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.