'Convert QImage BGR888 to Mat (OpenCV) in Python
I'm trying to convert a QImage into Mat format (to save a video from a sequence of QImage) in Python.
I've been trying the different solutions proposed online, such as the ones described here:
PyQt/PySide: How do I convert QImage into OpenCV's MAT format
https://code-examples.net/en/q/12faee7
One of this solution is the following one:
def convertQImageToMat(incomingImage):
incomingImage = incomingImage.convertToFormat(4)
width = incomingImage.width()
height = incomingImage.height()
ptr = incomingImage.bits()
ptr.setsize(incomingImage.byteCount())
arr = np.array(ptr).reshape(height, width, 4) # Copies the data
return arr
But when trying this solution, I end up with a black video of 105KB containing no frame (whatever the number of frames that I write to my cv2.VideoWriter).
If I try this other solution:
def convertQImageToMat(incomingImage):
incomingImage = incomingImage.convertToFormat(QImage.Format.Format_BGR888)
width = incomingImage.width()
height = incomingImage.height()
ptr = incomingImage.constBits()
arr = np.array(ptr).reshape(height, width, 4)
return arr
I then end up with this error:
ValueError: cannot reshape array of size 1 into shape (3060,5440,4)
And no video is then produced (because the above error occurs during frame format conversion, before the cv2.VideoWrite function)
I believe these erros may be due to the non-standard initial format of my QImage, which is as follow:
img = QImage(self.buf, self.width, self.height, (self.width * 24 + 31) // 32 * 4, QImage.Format_BGR888)
I've seen here a solution to convert a BGR888 QImage into Mat format (Error when converting Qimage to Mat opencv), but this solution is in C++, which I don't master.
Anyone here have already tried to convert such a BGR888 QImage into Mat in Python, or knows how to convert the c++ code provided in the above link into Python?
Many thanks in advance for your help
EDIT 27/04/2022 13:08
I found a way using a solution I found here (https://devdreamz.com/question/158707-in-pyqt-how-do-i-convert-qimage-to-a-list-of-pixels). Here is the edited function:
def convertQImageToMat(incomingImage):
incomingImage = incomingImage.convertToFormat(QImage.Format_RGBX8888)
ptr = incomingImage.constBits()
ptr.setsize(incomingImage.byteCount())
cv_im_in = np.array(ptr, copy=True).reshape(incomingImage.height(), incomingImage.width(), 4)
cv_im_in = cv2.cvtColor(cv_im_in, cv2.COLOR_BGRA2RGB)
return cv_im_in
This works fine, however, I am now wondering whether convertToFormat(QImage.Format_RGBX8888) alters or not my image (since its initial format is BGR888). If someone can confirm that this does not change anything, then I could call this a solved issue.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
