python中QImage转numpy的方法

网上很多从numpy(opencv在python中加载了图像,就是以numpy数组存储,相当于c++中的Mat)加载图像到QImage的方法,搜了好久都没有找到从QImage转存到numpy的方法。而我的一个应用需要用到这个功能,opencv无法在图像中写入汉子,所以我就通过Qimage进行了写入汉子处理,处理完成后需要转成numpy再通过opencv写入到video中。 弄了两天,好不容易发现了这篇,赶紧收藏并粘贴代码。原文https://blog.csdn.net/xjcvip007/article/details/53493290

代码如下:

def qimage2numpy(qimage, dtype='array'):
    """Convert QImage to numpy.ndarray.  The dtype defaults to uint8
    for QImage.Format_Indexed8 or `bgra_dtype` (i.e. a record array)
    for 32bit color images.  You can pass a different dtype to use, or
    'array' to get a 3D uint8 array for color images."""
    result_shape = (qimage.height(), qimage.width())
    temp_shape = (qimage.height(),
                  qimage.bytesPerLine() * 8 / qimage.depth())
    if qimage.format() in (QtGui.QImage.Format_ARGB32_Premultiplied,
                           QtGui.QImage.Format_ARGB32,
                           QtGui.QImage.Format_RGB32):
        if dtype == 'rec':
            dtype = QtGui.bgra_dtype
        elif dtype == 'array':
            dtype = np.uint8
            result_shape += (4,)
            temp_shape += (4,)
    elif qimage.format() == QtGui.QImage.Format_Indexed8:
        dtype = np.uint8
    else:
        raise ValueError("qimage2numpy only supports 32bit and 8bit images")
        # FIXME: raise error if alignment does not match
    buf = qimage.bits().asstring(qimage.numBytes())
    result = np.frombuffer(buf, dtype).reshape(temp_shape)
    if result_shape != temp_shape:
        result = result[:, :result_shape[1]]
    if qimage.format() == QtGui.QImage.Format_RGB32 and dtype == np.uint8:
        result = result[..., :3]
    result = result[:,:,::-1]
    return result
 

先开始对pyqt5 qimage.bits()返回类型sip.voidptr object类型一直不知道怎么处理,这个是个指针呀,在python中怎么处理指针呢?上面是采用变换成字符串的模式,sip.voidptr object类型还有asarray()、getsize()、setsize()函数,下面就是利用setsize()函数直接返回原图片的数据区。但要注意Qimage内部是按照每个像素4个字节的方式组织数据的,即使最后一个alpha通道没有用,也用0xff来填充。掌握原理后,其实可以采取更简单的方法处理

ptr = qimg.constBits()
ptr.setsize(qimg.byteCount())

mat = np.array(ptr).reshape( qimg.height(), qimg.width(), 4)  #  注意这地方通道数一定要填4,否则出错
return mat 

你可能感兴趣的:(python中QImage转numpy的方法)