| 
  • If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • You already know Dokkio is an AI-powered assistant to organize & manage your digital files & messages. Very soon, Dokkio will support Outlook as well as One Drive. Check it out today!

View
 

lsgui Under the hood

Page history last edited by Max Seligman 3 years, 11 months ago

 

Home  *  Installation  *  Using lsgui  *  Under the hood  *  Applications  *  Discussion  *  Contact Us

 


 

Image acquisition toolbox and camera interfaces

lsgui currently supports the LS600 default sensor, The Imaging Source DMM37UX178-ML (with a very low noise Sony Starvis sensor), and Basler acA1300-200um high speed cameras. The latter two interface through MATLAB's Image Acquisition Toolbox. Cameras interface by customizing a function that implements the following responses:

Message  Response  Notes 
'img'  return an image   
'exposure'  set exposure  logarithmic conversion implemented for imageSource and Basler 
'gain' set gain gain scale can vary depending on maker and model of camera 
'init' initialize device handle stored in persistent variable vid
'roi' set region of interest changing on the fly is dangerous
'params' return internal variable vid  
'close' delete live video object  

Three examples have been written and can serve as template for additional cameras: imageSource.m, basler.m, and ls620cam.m

 

MATLAB's Image acquisition toolbox supports at least two modes of initialization that result in substantially different performances: obj = imaq.VideoDevice(); and obj = videoinput();. The preview() function delivers much faster frame rate to the display than our interfaces, and in future iterations, we hope to incorporate some of its performance tricks. The default Lumascope camera interfaces through Etaluma's Lumaview software and a driver called LumaUSB.dll, who's location is hard-coded in ls620cam.m. Initialization of the ls620 hardware requires uploading some binary files, which at this point can only be done by launching Lumaview software, making sure the hardware is working, and then quitting the software.  

 

lsgui.m

This file is the main entry function for the gui, and can be invoked from the command line or by opening the .exe. sim is a global boolean that needs to be declared as global and initialized before involving the function from the command line. Setting sim to true enables debugging without hardware connected. The camera is selected by setting the camera variable to the appropriate function handle, e.g., camera = @ls620cam;. Next the camera hardware and its controller gui are initialized (the camera controller was built with guide lscon; the motion controller with guide motion;). The main gui window elements are next initialized and objects are labeled with unique Tags so they can be found from other scopes. lsgui.m ends with uncontrol callback functions for each button: StreamingButton() and RGBButton() hold persistent variables to a timerObj that calls a respective UpdateDisplay() function described below. 

 

Timers

MATLAB is fundamentally single threaded, but its uiobjects are event driven. Image data can be updated without blocking by calling it from a timer object (which MATLAB implements through Java). Building and debugging multithreaded apps can be challenging, so this paradigm offers great simplification by keeping all thread creation and management under another hood. The timer objects are initialized in the callback functions of the streaming buttons, at the bottom of lsgui.m

     timerObj = timer('ExecutionMode','fixedDelay','Period',.1,'BusyMode','drop', ...

               'TimerFcn','Update3PanelDisplay3color()','Name','3colorUpdate');

     start(timerObj);

 

Streaming images at high speed (set by the 'Period' property) takes most CPU cycles, which is why we implemented the Streaming buttons to toggle on and off. With streaming on, the command line may respond sluggishly, but any MATLAB command can run concurrently with lsgui

 

Graphics objects and updates

Functions like imagesc() and plot() have significant overhead. To increase frame rate, these are called only to initialize the graphics objects. During subsequent updates, graphics object's data are replaced, while not replacing the objects themselves. For example, we initialize the axes for the streaming images and assign its handle a unique tag (in Update3PanelDisplay.m): 

          imageH = imagesc(newImg);

     set(imageH, 'Tag','mainImg');

For subsequent updates, instead of calling imagesc(newImg); we just replace the data:

     set(imageH,'CData',newImg); 

Since StreamingButtons call timers that call updateDisplay functions, a lot of parameters would either have to be global or passed as arguments from one function to another. The solution we've implemented uses MATLAB's findobj() function to make the public properties of objects accessible from anywhere. E.g., findobj('Tag','mainImg') returns a handle that any code anywhere can drill down into its properties and data. 

 

AID and code size

This architecture interconnect diagram (AID) shows are how the principle files interact. Arrows denote control -- who calls who. Data generally flows bidirectionally. 

 

There is some danger that by using findobj(), any piece of code can change any object anywhere, and the system becomes unstable and unpredictable. Functional programming, where no variable can ever be changed after its created, is a "solution" to this problem, and this radical approach has reasonable advocates (e.g., https://www.youtube.com/watch?v=0if71HOyVjY). However, what makes our approach work, and stable, is MATLAB's remarkably concise, compact, coherent, and expressive syntax and semantics. The entire core application consists of just a few hundred lines of source code, broken down as follows (code lines calculated in a Unix shell via: cat filename |  sed '/^[^A-z]*$/d' | sed '/^\%.*$/d' | wc -l)

File Name  # of lines (wc -l)  # code lines Description 
lscon.m  297  66 hardware console -- machine generated by guide 
lscontroller.m  131  115 bureaucrat that runs the hardware console 
lsgui.m  117  98 gui entry point 
ls620cam.m  87  70 default camera interface 
imageSource.m  70  51 The Image Source camera interface 
basler.m  66  50 Basler camera interface 
drawTarget.m  61  43 Overlays target and grid on image to assist with optical alignment 
Update3PanelDisplay.m 41 38 timer callback to update gui
Update3PanelDisplay3color.m 16 16 timer callback for real-time pseudocolor
lscomposite.m 40 24 acquire a 3-color composite pseudocolor image
lsleds.m 44 25 interface with LED driver
displayFPS.m 18 17 compute and display frames per second statistic
Total lines written by us 691 547 Doesn't include some generic toolbox functions

 

And for a single camera (all that's ever used at one time), the total is ~540 lines of source, including white space and comments, ~430 executable lines! Note that although we generally follow a minimalist programming pattern, minimizing code size was not a particular target -- our goal was minimizing complexity. This code became functional at ~80% of its size, but many features (such as multiple camera support) have been added since with relatively minor increase in code size (although the algorithmic complexity has had to increase, e.g., using a function handle to access the camera). Another example of the compact expressiveness MATLAB enables: all 7 camera functions listed in Table 1 above are implemented in between 66 and 87 lines of code, for each of 3 cameras. By default, MATLAB supports zooming into the mainImg, but making the left and bottom side panes track the main zoom required just 2 lines (in Update3PanelDisplay.m):

    % zoom line graphs to track main image zoom

    lineH(1).Parent.XLim = imageH.Parent.XLim;

    lineV(1).Parent.YLim = imageH.Parent.YLim;

 

Heavyweight coding practices or radical ideas like making all objects static only are considered when the alternatives of exploding code complexity justify them. Here we've demonstrated how using MATLAB's object graphics, timers, and function handle addressing of generic camera interfaces, results in a remarkably simple yet powerful digital microscope interface. Next we'll summarize some advanced microscopy applications that this interface has enabled. 

 

 

 

Applications

Comments (0)

You don't have permission to comment on this page.