A montage display for real-time display of volumetric data

 

By default, Scanbox displays the incoming image stream on its main window. Thus, during volumetric scanning, one sees the incoming images as depth is changing over time.  If one is imaging only a handful of optical planes, it is difficult to see what is really going on.

A different way to visualize the data in such recordings is to have a montage showing the different optical sections separately, each being updated as new data becomes available. Here, we offer a plug-in for Scanbox that implements this mode of visualization.

As discussed in previous examples, Scanbox shares date with other processing by means of memory-mapped files. A header at the beginning of the file provides a mechanism for exclusive access to the data via a semaphore and exposes basic information about the data, such as the size of the images, the frame # being shared at any one time, and the period (in frames) of the volumetric scanning waveform, among other information.

Such data, along with a readily available montage function from Matlab, allows one to easily display the data as separate optical planes during acquisition.

Here is the code:


% Plug-in Demo: Display optical sections separately

close all; % Close all open figs

% Open memory mapped file -- define just the header first

mmfile = memmapfile('scanbox.mmap','Writable',true, ...
    'Format', { 'int16' [1 16] 'header' } , 'Repeat', 1);
flag = 1;

% Process all incoming frames until Scanbox stops

while(true)
    
    while(mmfile.Data.header(1)<0) % wait for a new frame...
        if(mmfile.Data.header(1) == -2) % exit if Scanbox stopped
            return;
        end
    end
        
    if(flag) % first time? Format chA according to lines/columns in data
        mmfile.Format = {'int16' [1 16] 'header' ; ...
            'uint16' double([mmfile.Data.header(2) mmfile.Data.header(3)]) 'chA'};
        mchA = double(intmax('uint16')-mmfile.Data.chA);
        flag = 0;
        nplanes = mmfile.Data.header(6);
        I = zeros([size(mchA) 1 nplanes]);
        I(:,:,1,1) = mchA;
        imaqmontage(I);
        axis off;           % remove axis
        colormap gray;      % use gray colormap
    else
        I(:,:,1,mod(mmfile.Data.header(1),nplanes)+1) = double(intmax('uint16')-mmfile.Data.chA);
        imaqmontage(I);
    end
    
    mmfile.Data.header(1) = -1; % signal Scanbox that frame has been consumed!
    drawnow limitrate;
    
end

clear(mmfile); % close the memory mapped file
close all;     % close all figures

And here are, side-by-side, the result of viewing the incoming stream in the main Scanbox window and in the volumetric plug-in.