pythonmatplotlibuser-interfacetraining-datalabeling

Python GUI to "label" ground truth in images?


A project I am working on involves finding x, y coordinates of objects in an image. For a given image, I want to augment an annotation to specific x, y through visual inspection.

As a toy example, I have an image of stars. From this image, I derive an array of x, y coordinates of the centroids of stars, found using skimage.peak_local_max:

centroids = [[3.567, 4.325], [7.814, 6.769], [2.122, 9.177], ...]

enter image description here which can be overlayed on the original image. What I would like is a user friendly interface that allows annotation of data. Say, the top most star is selected with a mouse click ("green box") such that my metadata gets augmented to look like:

    x    y    selected
0   3.567         4.325         False
1   7.814         6.769         True
2   2.122         9.177         False
...

... before moving on to the next image (with its own set of centroids to be overlayed and selected).

My question isn't really about "overlaying" annotation on an image, but rather annotating data. The confluence of these keywords taken of out context has made searching answers very difficult. Annotating my data is much easier with visual inspection, rather than checking each coordinate numerically. Is there a quick & dirty way to do this using common Python libraries?


Solution

  • I have seen something similar done using Matplotlib and easygui in Python.

    You can create a click trigger with easygui:

        def double_click_trigger(page_num, event):
            if event.dblclick:
                x = int(event.xdata)
                y = int(event.ydata)
                print(f"Clicked at {x}, {y}")
    

    Then create a matplotlib plot and connect the trigger to it:

            im = some_image ...
            fig, ax = plt.subplots()
            ax.imshow(im.resize(size))
    
            def this_page_trigger(event):
                return double_click_trigger(i, event)
    
            ax.set_title(f'Page {i + 1} (double click coordinates)')
            fig.canvas.mpl_connect('button_press_event', this_page_trigger)
            plt.show()
    

    Then you can write out the x/y to file as JSON or whatever.