How to add widgets to pypylon ImageWindow?

380 Views Asked by At

Now I'm working with pypylon (https://github.com/basler/pypylon) which is a Python wrapper for C++ library for working with Basler camera. This library provides an oportunity to retrieve data (images, which are of type pylon.GrabResult) from the camera and display them in a window which is also provided by this library. The problem is that I need to expand the project and add some functionality to the window: some widgets (e.g. buttons, which will help user to analize data from the image etc.). The base pylon window (pylon.ImageWindow) doesn't have a possibility to add widgets.

I have several ideas on how I can resolve this problem:

  1. Use another Python GUI library (e.g. matplotlib, tkinter etc.) and hand over the data from pypylon to this library.
  2. Create my own class inherited from pylon.ImageWindow and add the new functionality.

I tried first approach. I used matplotlib and handed over an image data as an numpy array. Works almost perfectly: I can add buttons and other widgets, but the problem occured, it works considerably slower than in "native" image window. Code looks like this:

import random

import numpy as np

from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.widgets import Button

from pypylon import pylon
from pypylon import genicam

MAX_PICTURES_GRABBED = 10000
fig = plt.figure()
ar = np.zeros((3000, 3000))
main_ax = plt.axes([0, 0.1, 1, 1])
im = plt.imshow(ar, axes=main_ax, cmap="gray", vmin=0, vmax=127)

try:
    camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
    camera.StartGrabbingMax(MAX_PICTURES_GRABBED, pylon.GrabStrategy_LatestImageOnly)
except genicam.GenericException as e:
    print(e)

def animate(_):
    try:
        grab_result = camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)
        if grab_result.GrabSucceeded():
            im.set_array(grab_result.Array)
        else:
            print("Error: ", grab_result.ErrorCode)
        grab_result.Release()
    except genicam.GenericException as exp:
        print(exp)
    return [im]

# Example widget.
btn_change_color_axe = plt.axes([0.1, 0.02, 0.2, 0.055])
btn_change_color = Button(btn_change_color_axe, 'Change color')
btn_change_color.on_clicked(lambda event: im.set_cmap(random.choice(plt.colormaps())))

ani = FuncAnimation(fig, animate, interval=0, blit=False)
plt.show()

camera.Close()

The second approach seems like inventing a wheel and will be time consuming. So the questions are:

  1. Am I missing something: maybe there is a better way of resolving my problem?
  2. Is there a way to make the image flow faster in first approach or maybe there is a way of displaying either a GrabResult or ImageWindow itself in another GUI library window (preferably matplotlib but not exclusivly).
  3. If the second approach is the best can you reference me to materials regarding this approach. And also maybe I should consider using C# or C++ for this project because they are natively supported by Basler and have extensive documentation?

Additional info: camera model: Basler acA3088-57um.

0

There are 0 best solutions below