Reputation: 361
Considering the following code
from PyQt5.QtWidgets import QMainWindow, QLabel, QSizePolicy, QApplication
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qt
import numpy as np
import sys
class Test(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(10,10,640, 400)
pixmap_label = QLabel()
pixmap_label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
pixmap_label.resize(640,400)
pixmap_label.setAlignment(Qt.AlignCenter)
im_np = np.ones((1800,2880,3),dtype=uint8)
im_np = np.transpose(im_np, (1,0,2))
qimage = QImage(im_np, im_np.shape[1], im_np.shape[0],
QImage.Format_RGB888)
pixmap = QPixmap(qimage)
pixmap = pixmap.scaled(640,400, Qt.KeepAspectRatio)
pixmap_label.setPixmap(pixmap)
self.setCentralWidget(pixmap_label)
self.show()
def main():
app = QApplication(sys.argv)
win = Test()
sys.exit(app.exec_())
if __name__=="__main__":
main()
I get the following error
TypeError: arguments did not match any overloaded call: QImage(): too many arguments QImage(QSize, QImage.Format): argument 1 has unexpected type 'numpy.ndarray' QImage(int, int, QImage.Format): argument 1 has unexpected type 'numpy.ndarray' QImage(bytes, int, int, QImage.Format): argument 1 has unexpected type 'numpy.ndarray'
QImage(sip.voidptr, int, int, QImage.Format): argument 1 has unexpected type 'numpy.ndarray' QImage(bytes, int, int, int, QImage.Format): argument 1 has unexpected type 'numpy.ndarray'
QImage(sip.voidptr, int, int, int, QImage.Format): argument 1 has unexpected type 'numpy.ndarray' QImage(List[str]): argument 1 has unexpected type 'numpy.ndarray' QImage(str, format: str = None): argument 1 has unexpected type 'numpy.ndarray' QImage(QImage): argument 1 has unexpected type 'numpy.ndarray' QImage(Any): too many arguments
According to this post this can be caused by numpy creating a view. Modifying the lines
im_np = np.array(img)
im_np = np.transpose(im_np, (1,0,2))
To
im_np = np.array(img)
im_np = np.transpose(im_np, (1,0,2))
im_np_cpy = np.copy(im_np)
Produces the same error. To test that I am not passing a view I print the result of the test
im_np_cpy.base is im_np
and it's False. The image is visualised correctly with cv2. I am clearly missing something, any idea what?
Cheers!
Upvotes: 15
Views: 31171
Reputation: 93
If we use opencv module in pyqt Qimage, use the below command for image.
qimage = QImage(img, img.shape[1], img.shape[0], QImage.Format_BGR888)
And if we use images, then directly use this:
qimage = QImage(img, img.shape[1], img.shape[0], QImage.Format_RGB888)
Upvotes: 1
Reputation: 93
import copy
im_np = np.array(img)
im_np = np.transpose(im_np, (1,0,2))
im_np_cpy = copy.deepcopy(im_np)
Use above command for getting the im_np
data to im_np_cpy
Upvotes: 1
Reputation: 508
Axis transposing, reordering (BGR to RGB) or any transition that doesn't require a copy, a new image container, representing the same image buffer will be created. the problems starts to appear at the interface point to another module. usually an image buffer is represented as a continues stream of bytes along a defined order of axis. it could be solved using:
im_np = np.array(img)
im_np = np.transpose(im_np, (1,0,2))
im_np = np.ascontiguousarray(im_np)
qimage = QImage(im_np.data, im_np.shape[1], im_np.shape[0],
QImage.Format_RGB888)
or alternatively (faster) by:
im_np = np.array(img)
qimage = QImage(im_np.data, im_np.shape[1], im_np.shape[0],
QImage.Format_BGR888)
Upvotes: 5
Reputation: 359
Just do this:
h,w = img.shape
qimage = QImage(img.data, w, h, 3*w, QImage.Format_RGB888)
Upvotes: 5
Reputation: 116
Ivan's answer is short and elegant, however while numpy uses (H, W) order, Qt uses (W, H) order. Therefore, to make it work, I have to exchange w and h in the second line:
h, w, _ = img.shape
qimage = QImage(img.data, w, h, 3 * w, QImage.Format_RGB888)
(I would have preferred to comment on the above answer but I don't have enough reputation.)
Upvotes: 9
Reputation: 81
Check if the module qimage2ndarray suits your needs, with just one line of code https://pypi.org/project/qimage2ndarray/
yourQImage=qimage2ndarray.array2qimage(yournumpyarray)
Upvotes: 8
Reputation: 593
I added a copy after the transpose like this:
im_np = np.transpose(im_np,(1,0,2)).copy()
and that worked for me.
Upvotes: 15