In this article we will see how we can perform common image analysis using PyQtGraph module in Python. PyQtGraph is a graphics and user interface library for Python that provides functionality commonly required in designing and science applications. Its primary goals are to provide fast, interactive graphics for displaying data (plots, video, etc.) and second is to provide tools to aid in rapid application development (for example, property trees such as used in Qt Designer).
In order to install the PyQtGraph we use the command given below.
pip install pyqtgraph
Image analysis is the extraction of meaningful information from images; mainly from digital images by means of digital image processing techniques. Image analysis tasks can be as simple as reading bar coded tags or as sophisticated as identifying a person from their face.
In order to do this we have to do the following.
- Import the required libraries like pyqtgraph, pyqt5 and numpy.
- Create a main window class using pyqt5.
- Create a graphic window to add the widgets required to show the image analysis.
- Create two plot area and add a image item to it with the roi object to first plot area.
- Create an isocurve object and add it to the image item.
- Create a data for image and add it to the image item.
- Connect a update method to the roi object when the region is changed, inside the update method get the region and set it to the second plot area.
- Create a mouse move event and set the position, pixel value to the title according to the mouse position.
- Add this graph window to the main window layout with any additional widgets.
Below is the implementationÂ
Python3
# importing Qt widgets from PyQt5.QtWidgets import * Â
# importing system import sys Â
# importing numpy as np import numpy as np Â
# importing pyqtgraph as pg import pyqtgraph as pg from PyQt5.QtGui import * from PyQt5.QtCore import * Â
class Window(QMainWindow): Â
    def __init__( self ):         super ().__init__() Â
        # setting title         self .setWindowTitle( "PyQtGraph" ) Â
        # setting geometry         self .setGeometry( 100 , 100 , 900 , 550 ) Â
        # icon         icon = QIcon( "skin.png" ) Â
        # setting icon to the window         self .setWindowIcon(icon) Â
        # calling method         self .UiComponents() Â
        # showing all the widgets         self .show() Â
    # method for components     def UiComponents( self ): Â
        # creating a widget object         widget = QWidget() Â
        # text         text = "Image Analysis" Â
        # creating a label         label = QLabel(text) Â
        # setting minimum width         label.setMinimumWidth( 130 ) Â
        # making label do word wrap         label.setWordWrap( True ) Â
        # creating a graphic layout widget Â
        win = pg.GraphicsLayoutWidget() Â
        # plot area (ViewBox + axes) for displaying the image         p1 = win.addPlot(title = "") Â
        # item for displaying image data         img = pg.ImageItem() Â
        # adding image to the plot area         p1.addItem(img) Â
        # Custom ROI for selecting an image region         roi = pg.ROI([ - 10 , 14 ], [ 5 , 5 ])         roi.addScaleHandle([ 0.5 , 1 ], [ 0.5 , 0.5 ])         roi.addScaleHandle([ 0 , 0.5 ], [ 0.5 , 0.5 ]) Â
        # adding roi to the plot area         p1.addItem(roi) Â
        # setting z value to roi         # making sure ROI is drawn above image         roi.setZValue( 10 ) Â
        # creating a Isocurve drawing on the image         iso = pg.IsocurveItem(level = 1.2 , pen = 'r' ) Â
        # setting parent as image         iso.setParentItem(img) Â
        # setting z axis value of isocurve         iso.setZValue( 5 ) Â
        # Contrast/color control         hist = pg.HistogramLUTItem() Â
        # setting image to the control         hist.setImageItem(img) Â
        # adding control widget to the plot window         win.addItem(hist) Â
        # creating draggable line for setting isocurve level         isoLine = pg.InfiniteLine(angle = 0 , movable = True , pen = 'r' )         hist.vb.addItem(isoLine) Â
        # making user interaction a little easier         hist.vb.setMouseEnabled(y = False )         isoLine.setValue( 0.8 ) Â
        # bring iso line above contrast controls         isoLine.setZValue( 1000 ) Â
        # going to next row of graphic window         win.nextRow() Â
        # another plot area for displaying ROI data         p2 = win.addPlot(colspan = 2 ) Â
        # setting maximum height of plot area         p2.setMaximumHeight( 250 ) Â
        # generating image data         data = np.random.normal(size = ( 200 , 100 ))         data[ 20 : 80 , 20 : 80 ] + = 2. Â
        # setting gaussian filter to the data         data = pg.gaussianFilter(data, ( 3 , 3 ))         data + = np.random.normal(size = ( 200 , 100 )) * 0.1 Â
        # setting data to the image         img.setImage(data) Â
        # setting level         hist.setLevels(data. min (), data. max ()) Â
        # build isocurves from smoothed data         iso.setData(pg.gaussianFilter(data, ( 2 , 2 ))) Â
        # set position and scale of image         img.scale( 0.2 , 0.2 )         img.translate( - 50 , 0 ) Â
        # zoom to fit image         p1.autoRange() Â
        # method for updating the plot         def updatePlot(): Â
            # getting the selected region by the roi             selected = roi.getArrayRegion(data, img) Â
            # plot the selected region             p2.plot(selected.mean(axis = 0 ), clear = True ) Â
        # connecting the update plot method         # it get called when the region is changed         roi.sigRegionChanged.connect(updatePlot) Â
        # call the update plot method         updatePlot() Â
        # method for updating the isocurve         def updateIsocurve():             # setting iso level             iso.setLevel(isoLine.value()) Â
        isoLine.sigDragged.connect(updateIsocurve) Â
        # method for image hover event         def imageHoverEvent(event): Â
            # showing the position, pixel, and value under the mouse cursor             # if cursor is not on the plot area             if event.isExit():                 # set title as blank                 p1.setTitle("")                 return Â
            # getting cursor position             pos = event.pos()             i, j = pos.y(), pos.x() Â
            # pixel values             i = int (np.clip(i, 0 , data.shape[ 0 ] - 1 ))             j = int (np.clip(j, 0 , data.shape[ 1 ] - 1 )) Â
            # value of point             val = data[i, j]             ppos = img.mapToParent(pos)             x, y = ppos.x(), ppos.y() Â
            # setting plot title data             p1.setTitle(                 "pos: (%0.1f, %0.1f) pixel: (%d, %d) value: %g" % (x, y, i, j, val)) Â
        # Monkey-patch the image to use our custom hover function.         img.hoverEvent = imageHoverEvent Â
        # Creating a grid layout         layout = QGridLayout() Â
        # minimum width value of the label         label.setMinimumWidth( 130 ) Â
        # setting this layout to the widget         widget.setLayout(layout) Â
        # adding label in the layout         layout.addWidget(label, 1 , 0 ) Â
        # plot window goes on right side, spanning 3 rows         layout.addWidget(win, 0 , 1 , 3 , 1 ) Â
        # setting this widget as central widget of the main window         self .setCentralWidget(widget) Â
# create pyqt5 app App = QApplication(sys.argv) Â
# create the instance of our Window window = Window() Â
# start the app sys.exit(App. exec ()) |
Output: