ImageDisplayQT
ImageDisplayQT is a PyQT widget for live scientific image display in Python QT Graphical User Interfaces.
It was designed as a simple and lightweight widget that allows real-time display of images. Features include a status bar, with pixel value inspection, a draggable region of interest, zoom and pan, and several types of overlay. Monochrome images can be displayed using any colormap from matplotlib.
Install using:
pip install ImageDisplayQT
It is developed mainly by Mike Hughes’s lab in the Applied Optics Group, School of Physics and Astronomy, University of Kent. The package was originally developed for GUIs for in endoscopic microscopy, including fluorescence endomicroscopy and holographic endomicroscopy.
The project is hosted on github. Bug reports, contributions and pull requests are welcome.
Contents
Getting Started
Import the ImageDisplay
class:
from image_display import ImageDisplay
Create an instance of ImageDisplay
:
imDisplay = ImageDisplay()
and then add this widget to your GUI, eg. using addWidget
.
To update the image display, call:
imDisplay.set_image(img)
where img
is either a 2D numpy array containing a monochrome image or a 3D numpy array containing a colour image with the third dimensions containing the red, green and blue channels.
Toggle the status bar visibility using set_status_bar
, for example:
imDisplay.set_status_bar(True)
Toggle the zoom facility using the mouse scroll wheel (or pinch zoom) using set_zoom_enabled
, for example:
imDisplay.set_zoom_enabled(True)
Once zoomed you can pan by holding the middle or right mouse buttons.
Toggle the ability to draw a rectangular region of interest by holding the left mouse button and dragging using set_roi_enabled
, for example:
imDisplay.set_roi_enabled(True)
You can set the colormap to be any Matplotlib colormap, for example:
imDisplay.set_colormap('hsv')
You can choose whether or not the image intensity is autoscaled to use the full dynamic range using autoscale_enabled
, for example:
imDisplay.autoscale_enabled(True)
Images are always displayed as 8bit images. If autoscale is set to True
then the smallest and largest image pixel values will be mapped to 0 and 255 respectively. For colour images, all three channels are scaled in the same way.
If autoscale is set to False
then no mapping will occur by default, the input image will simply be cast to an 8 bit unsigned image. This can be changed using set_display_range
:
imDisplay.set_display_range(min, max)
Where image pixel values of min
and below will be mapped to 0, and max
and above to 255.
Example
An example is included in the examples
folder of the github repository.
This example is a bare-bones PyQT GUI which displays images in sequence from either a monochrome or colour tif stack using the ImageDisplay widget. Various features can be toggled using a set of checkboxes.
Overlays
Five types of overlay are supported:
Rectangle
Ellipse
Line
Point
Text
Overlays are added using the add_overlay
function. This returns a reference to the overlay.
This can be later passed to remove_overlay
to delete the overlay.
Alternatively, all overlays can be removed using clear_overlays
.
To create a rectangular overlay:
from image_display import ImageDisplay
imDisplay = ImageDisplay()
imDisplay.add_overlay(ImageDisplay.RECTANGLE, x, y, w, h, pen, fill)
where x
and y
are the x and y co-ordinates of the top left of the rectangle, respectively, and w
and h
are the width and height.
These co-ordinates are specified in terms of pixels in the original image (i.e. not screen pixels).
Co-ordinates outside the image can be specified in which case the overlay will be clipped.
The pen
and fill
should be a QPen
and QBrush
respectively. For example:
overlay = imDisplay.add_overlay(ImageDisplay.RECTANGLE, 90, 100, 30, 40, QPen(Qt.blue, 2, Qt.SolidLine), QBrush(Qt.red))
generates a rectangle with a blue solid outer line of thickness 2 and a red fill. For a transparent fill, pass None
for fill
.
To add an ellipse, the structure is:
overlay = imDisplay.add_overlay(ImageDisplay.ELLIPSE, x, y, w, h, pen, fill)
For a line:
overlay = imDisplay.add_overlay(ImageDisplay.LINE, x, y, w, h, pen)
For a point:
overlay = imDisplay.add_overlay(ImageDisplay.POINT, x, y, pen)
Note that no fill
is specified for lines and points.
To add a text overlay:
overlay = imDisplay.add_overlay(ImageDisplay.TEXT, x, y, pen, text)
where text
is the string to add. The co-ordinates are the lower left of the bounding rectangle of the text box.
To remove any overlay, use:
imDisplay.remove_overlay(overlay)
where overlay
is the reference returned when creating the overlay using add_overlay
.
To clear all overlays use:
imDisplay.clear_overlays()
Customisation
The widget appearance and behaviour can be customised as follows without sub-classing.
Overall Appearance
At creation, the following stylesheet is applied to the widget:
setStyleSheet("border:1px solid white")
Apply a different stylesheet to change the overall appearance, e.g. to change or remove the border.
Status Bar
Set the visibility of the status bar (visible by default):
set_status_bar(True/False)
To customise colours of the status bar, the following values can be set directly:
statusPen
The border colour/style, provide aQPen
, such asQPen(Qt.white, 2, Qt.SolidLine)
.statusBrush
The fill colour/style, provide aQBrush
, such asQBrush(Qt.white, Qt.SolidPattern)
.statusTextPen
The font colour, provide aQPen
, such asQPen(Qt.black, 2, Qt.SolidLine)
.
Zoom
To enable or disable zooming (enabled by default):
set_zoom_enabled(True/False)
To control how much a mouse wheel scroll or pinch zoom changes the zoom, use:
set_zoom_step_divider(zoomDivider)
where a bigger value of zoomDivider
makes the amount zoomed in by each mouse wheel click smaller. The zoom is (base 2) logarithmic. A value of 1
means the zoom will go as 1X, 2X, 4X, 8X, 16X etc. Default is 2.
Set the visibility of the zoom indicator using:
set_zoom_indicator_enabled(True/False)
To customise colours of the zoom indicator, the following values can be set directly:
zoomIndicatorPen
The colour of the zoom indicator, provide aQPen
such asQPen(Qt.white, 1, Qt.SolidLine)
.zoomIndicatorBrush
The fill colour of the zoom indicator, provide aQBrush
such asQBrush(Qt.white, Qt.SolidPattern)
.zoomIndicatorWidth
With of zoom indicator, default 60.zoomIndicatorOffsetX
Horizontal position of zoom indicator, relative to top right corner of image, default 20.zoomIndicatorOffsetY
Vertical position of zoom indicator, relative to top right corner of image, default 20.
Region of Interest (ROI)
Set whether a ROI can be dragged using:
set_roi_enabled(True/False)
To customise colours, the following values can be set directly:
roiDragContrastPen
The colour/style of the first rectangle to be drawn while the ROI is being dragged, provide aQPen
such asQPen(Qt.white, 2, Qt.SolidLine)
.roiDragPen
The colour/style of the second rectangle to be drawn while the ROI is being dragged. This is drawn over the first rectangle and so should usually be a dotted/dashed line of a different colour to help improve visibility when colour images are displayed. Provide aQPen
such asQPen(Qt.red, 2, Qt.DotLine)
.roiContrastPen
The colour/style of the first rectangle to be drawn of an ROI which has been set. Provide aQPen
such asPen(Qt.white, 2, Qt.SolidLine)
.roiPen
The colour/style of the second rectangle to be drawn of an ROI which has been set. This is drawn over the first rectangle and so should usually be a dotted/dashed line of a different colour to help improve visibility when colour images are displayed. Provide aQPen
such asQPen(Qt.green, 2, Qt.DotLine)
.
Acknowledgements: Funding to Mike Hughes’s lab from EPSRC (Ultrathin fluorescence microscope in a needle, EP/R019274/1), Royal Society (Ultrathin Inline Holographic Microscopy).