使用PySide将QImage转换为NumPy数组

11

我目前正在从PyQt转换到PySide。

使用PyQt时,我使用在SO上找到的以下代码将QImage转换为Numpy.Array:

def convertQImageToMat(incomingImage):
    '''  Converts a QImage into an opencv MAT format  '''

    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

然而ptr.setsize(incomingImage.byteCount())在PySide中不起作用,因为它是PyQt的void*支持的一部分。

我的问题是:如何使用PySide将QImage转换为Numpy.Array

编辑:

Version Info
> Windows 7 (64Bit)
> Python 2.7
> PySide Version 1.2.1
> Qt Version 4.8.5

1
PySide似乎没有提供bits方法。这也是PyQt的一部分吗?使用constBits怎么样? - Henry Gomersall
我简直不敢相信我没看到那个!非常感谢。如果您将您的评论重新发布为答案,我会接受它。再次感谢! - Mailerdaimon
完成了,但这是否足以回答问题? - Henry Gomersall
是的,因为这是唯一缺失的部分以使其工作。我会在一秒钟内编辑我的问题并添加工作代码。 - Mailerdaimon
3个回答

7

对我来说,使用constBits()的解决方案不起作用,但是以下方法有效:

def QImageToCvMat(incomingImage):
    '''  Converts a QImage into an opencv MAT format  '''

    incomingImage = incomingImage.convertToFormat(QtGui.QImage.Format.Format_RGBA8888)

    width = incomingImage.width()
    height = incomingImage.height()

    ptr = incomingImage.bits()
    ptr.setsize(height * width * 4)
    arr = np.frombuffer(ptr, np.uint8).reshape((height, width, 4))
    return arr

3
请注意,使用bits()而不是constBits()会创建一个深拷贝。这可能符合您的意图,也可能不符合。 - Mailerdaimon
@Mailerdaimon 我需要深拷贝,因为我想要操作数据。如果我不使用 bits(),至少会出现访问冲突。 - JTIM

3

关键在于使用QImage.constBits(),正如@Henry Gomersall所建议的那样。我现在使用的代码是:

def QImageToCvMat(self,incomingImage):
    '''  Converts a QImage into an opencv MAT format  '''

    incomingImage = incomingImage.convertToFormat(QtGui.QImage.Format.Format_RGB32)

    width = incomingImage.width()
    height = incomingImage.height()

    ptr = incomingImage.constBits()
    arr = np.array(ptr).reshape(height, width, 4)  #  Copies the data
    return arr

太棒了!你知道它的反义词吗? - Maham
@Maham 最好单独提出这个问题。 - Mailerdaimon
@Silencer:你可能想把问题具体化,以便向我们提问。我正在使用PyQt5,它对我来说是有效的。 - Mailerdaimon
抱歉,我找到了原因:我同时使用cv2.imshowQLabel进行显示,然后它们因为gtkXXX的某些原因发生了冲突。但是当我注释掉cv2.imshow时,它就可以正常工作了。再次抱歉。 - Kinght 金

2

PySide似乎没有提供bits方法。那么使用constBits获取数组指针如何呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接