使用 PySide 将 QImage 转换为 Numpy 数组

Posted

技术标签:

【中文标题】使用 PySide 将 QImage 转换为 Numpy 数组【英文标题】:QImage to Numpy Array using PySide 【发布时间】:2013-11-11 08:48:59 【问题描述】:

我目前正在从 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* support 的一部分。

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

编辑:

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

【问题讨论】:

PySide 似乎没有提供bits 方法。这也是 PyQt 的一部分吗?用constBits怎么样? m( 不敢相信我没有看到!非常感谢。如果您将您的评论作为答案重新发布,我会接受它。再次感谢! 完成了,但这足以回答这个问题吗? 是的,因为它是唯一缺少让它工作的东西。我编辑我的问题以在几秒钟内添加工作代码。 【参考方案1】:

诀窍是按照@Henry Gomersall 的建议使用QImage.constBits()。我现在使用的代码是:

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 这最好在单独的问题中提出 @Silencer:您可能想问这个问题,向我们展示究竟是什么不起作用。我正在使用 PyQt5,它对我有用。 对此感到抱歉。我找到了原因:我同时使用cv2.imshowQLabel 显示,然后由于gtkXXX 的某种原因它们发生冲突。但是当我评论cv2.imshow 时,它起作用了。再次抱歉。【参考方案2】:

PySide 似乎没有提供bits 方法。使用constBits 获取指向数组的指针怎么样?

【讨论】:

【参考方案3】:

对我来说,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

【讨论】:

请注意,使用 bits() 而不是 constBits() 会创建深层副本。这可能是也可能不是您想要的。 @Mailerdaimon 我需要深拷贝,因为我想操作数据。如果我不使用bits(),至少我会遇到访问冲突

以上是关于使用 PySide 将 QImage 转换为 Numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章

使用 QImage::loadFromData 将 cv::mat 转换为 QImage

将 cv::mat 转换为 QImage

使用原始数据将 QImage 转换为 cv::Mat

将 QImage* 转换为 void* ,反之亦然

Qt5 将 QImage 转换为 OpenGL 格式

如何将灰度/二进制 Mat 转换为 QImage?