Search code examples
pythonimagewindowneural-networkupdating

Show an updating image in just one window


I want to show a jpg in a window which updates multiple times per second. I have coded a very very compact program with just 100 lines of code (a neural network which creates the image) and don't want to put in another 100 lines of code to just show the image. Is there anything I can do to solve this problem?

Many thx, jj


Solution

  • As it was stated in the comments that IO is not an issue, we shall go straight to the available standard image plot tools used in matplotlib, since it is the defacto standard plotting library for python. While not knowing the dimensions of typical images originating in neural networks, a quick comparison of the average time it would take to call e.g. imshow, pcolormesh and matshow for different image dimensions cannot hurt (pcolor is significantly slower, so it is omitted).

    import matplotlib.pyplot as plt
    import numpy as np
    import timeit
    
    n = 13
    repeats = 20
    timetable = np.zeros((4, n-1))
    labellist = ['imshow', 'matshow', 'pcolormesh']
    
    for i in range(1, n):
        image = np.random.rand(2**i, 2**i)
        print('image size:', 2**i)
        timetable[0, i - 1] = 2**i
    
        timetable[1, i - 1] = timeit.timeit("plt.imshow(image)", setup="from __main__ import plt, image", number=repeats)/repeats
        plt.close('all')
        timetable[2, i - 1] = timeit.timeit("plt.matshow(image)", setup="from __main__ import plt, image", number=repeats)/repeats
        plt.close('all')
        timetable[3, i - 1] = timeit.timeit("plt.pcolormesh(image)", setup="from __main__ import plt, image", number=repeats)/repeats
        plt.close('all')
    
    for i in range(1, 4):
        plt.semilogy(timetable[0, :], timetable[i, :], label=labellist[i - 1])
        plt.legend()
        plt.xlabel('image size')
        plt.ylabel('avg. exec. time [s]')
        plt.ylim(1e-3, 1)
    
    plt.show()
    

    enter image description here

    So, imshow it is. An elegant way to update or animate a plot in matplotlib is the animation framework it offers. That way one does not have to bother with many lines of code, as it was asked for. Here is a simple example:

    import matplotlib.pyplot as plt
    import numpy as np
    import time
    from matplotlib import animation
    
    data = np.random.rand(128, 128)
    
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)
    
    im = ax.imshow(data, animated=True)
    
    def update_image(i):
        data = np.random.rand(128, 128)
        im.set_array(data)
        # time.sleep(.5)
        # plt.pause(0.5)
    ani = animation.FuncAnimation(fig, update_image, interval=0)
    
    plt.show()
    

    In this example the neural network would be called out of the update function. The update behaviour under heavy computational work can be emulated by time.sleep. If your application is multi-threaded plt.pause might come in handy to give the other threads time to do their work. interval=0 basically makes the plot update as often as possible.

    I hope this points you in the general direction and is helpful. If you do not want to utilize animations, canvas clearing and/or blitting need to be taken care of manually.