qimage2ndarray is a small python extension for quickly converting between QImages and numpy.ndarrays (in both directions). These are very common tasks when programming e.g. scientific visualizations in Python using PyQt4 as the GUI library.
Similar code was found in Qwt and floating around on mailing lists, but qimage2ndarray has the following unique feature set:
Supports conversion of scalar and RGB data, with arbitrary dtypes and memory layout, with and without alpha channels, into QImages (e.g. for display or saving using Qt).
Using a tiny C++ extension, qimage2ndarray makes it possible to create ndarrays that are views into a given QImage‘s memory.
This allows for very efficient data handling and makes it possible to modify Qt image data in-place (e.g. for brightness/gamma or alpha mask modifications).
qimage2ndarray is stable and unit-tested:
Masked arrays are also supported and are converted into QImages with transparent pixels.
Supports value scaling / normalization to 0..255 for convenient display of arbitrary NumPy arrays.
The extension is open source, BSD-licensed, and the mercurial repository can be browsed online or cloned using Mercurial:
hg clone http://www.informatik.uni-hamburg.de/~meine/hg/qimage2ndarray/
There are two opposite directions of conversion, discussed in the next subsections:
The first task is supported by a family of functions that create views into the corresponding QImage memory, while the second task will always copy the image data (usually converting it into the appropriate type or value range).
Note
The reason for this is that ndarrays are much more flexible than QImages, and while it is possible – even using pure python – to create QImages that are views into an ndarray’s memory, this will only work if the latter fulfills certain strict requirements w.r.t. dtype, strides / memory layout etc. Thus, you’d need functions that set up a properly convertible ndarray, which makes this less convenient. Moreover, it is then a logical next step to let QImage set up and manage the memory and instead create ndarray views.
QImages can be viewn as recarrays using recarray_view(), as uint8-valued array using rgb_view(), alpha_view(), or just byte_view(), or as raw 2D array using raw_view().
Returns recarray view of a given 32-bit color QImage‘s memory.
The result is a 2D array with a complex record dtype, offering the named fields ‘r’,’g’,’b’, and ‘a’ and corresponding long names. Thus, each color components can be accessed either via string indexing or via attribute lookup (through numpy.recarray):
>>> from PyQt4.QtGui import QImage, qRgb
>>> qimg = QImage(320, 240, QImage.Format_ARGB32)
>>> qimg.fill(qRgb(12,34,56))
>>>
>>> import qimage2ndarray
>>> v = qimage2ndarray.recarray_view(qimg)
>>>
>>> red = v["r"]
>>> red[10,10]
12
>>> pixel = v[10,10]
>>> pixel["r"]
12
>>> (v.g == v["g"]).all()
True
>>> (v.alpha == 255).all()
True
Parameter: | qimage (QImage with 32-bit pixel type) – image whose memory shall be accessed via NumPy |
---|---|
Return type: | numpy.ndarray with shape (height, width) and dtype bgra_dtype |
Returns RGB view of a given 32-bit color QImage‘s memory. Similarly to byte_view(), the result is a 3D numpy.uint8 array, but reduced to the rgb dimensions (without alpha), and reordered (using negative strides in the last dimension) to have the usual [R,G,B] order. The image must have 32 bit pixel size, i.e. be RGB32, ARGB32, or ARGB32_Premultiplied. (Note that in the latter case, the values are of course premultiplied with alpha.)
Parameter: | qimage (QImage with 32-bit pixel type) – image whose memory shall be accessed via NumPy |
---|---|
Return type: | numpy.ndarray with shape (height, width, 3) and dtype uint8 |
Returns alpha view of a given 32-bit color QImage‘s memory. The result is a 2D numpy.uint8 array, equivalent to byte_view(qimage)[...,3]. The image must have 32 bit pixel size, i.e. be RGB32, ARGB32, or ARGB32_Premultiplied. Note that it is not enforced that the given qimage has a format that actually uses the alpha channel – for Format_RGB32, the alpha channel usually contains 255 everywhere.
Parameter: | qimage (QImage with 32-bit pixel type) – image whose memory shall be accessed via NumPy |
---|---|
Return type: | numpy.ndarray with shape (height, width) and dtype uint8 |
Returns raw 3D view of the given QImage‘s memory. This will always be a 3-dimensional numpy.ndarray with dtype numpy.uint8.
Note that for 32-bit images, the last dimension will be in the [B,G,R,A] order due to QImage‘s memory layout (the alpha channel will be present for Format_RGB32 images, too).
For 8-bit (indexed) images, the array will still be 3-dimensional, i.e. shape will be (height, width, 1).
Parameter: | qimage (QImage) – image whose memory shall be accessed via NumPy |
---|---|
Return type: | numpy.ndarray with shape (height, width, 1 or 4) and dtype uint8 |
Returns raw 2D view of the given QImage‘s memory. The result will be a 2-dimensional numpy.ndarray with an appropriately sized integral dtype. (This function is not intented to be used directly, but used internally by the other – more convenient – view creation functions.)
Parameter: | qimage (QImage) – image whose memory shall be accessed via NumPy |
---|---|
Return type: | numpy.ndarray with shape (height, width) |
Convert a 2D or 3D numpy array into a 32-bit QImage. The first dimension represents the vertical image axis; the optional third dimension is supposed to contain either three (RGB) or four (RGBA) channels. Scalar data will be converted into corresponding gray RGB triples; if you want to convert to an (indexed) 8-bit image instead, use gray2qimage.
The parameter normalize can be used to normalize an image’s value range to 0..255:
If array contains masked values, the corresponding pixels will be transparent in the result. Thus, the result will be of QImage.Format_ARGB32 if the input already contains an alpha channel (i.e. has shape (H,W,4)) or if there are masked pixels, and QImage.Format_RGB32 otherwise.
Parameters: |
|
---|---|
Return type: | QImage with RGB32 or ARGB32 format |
Convert the 2D numpy array gray into a 8-bit, indexed QImage with a gray colormap. The first dimension represents the vertical image axis.
The parameter normalize can be used to normalize an image’s value range to 0..255:
If the source array gray contains masked values, the result will have only 255 shades of gray, and one color map entry will be used to make the corresponding pixels transparent.
Parameters: |
|
---|---|
Return type: | QImage with RGB32 or ARGB32 format |