LEVERSC: Cross-Platform Scriptable Multichannel 3-D Visualization for Fluorescence Microscopy Images (Usage Example)
Usage Example
Scripted Movie Rendering (in MATLAB)
In this section we will discuss in detail the usage of the script application programming interface (API) for rendering high-quality presentation movies.
The full script (sampleVolumeMovie.m
) is available in the src/MATLAB
directory of the LEVERSC repository.
Movie setup
We begin by loading some image data, in this case from the sample .LEVER file distributed along with the LEVERSC repository.
%% Load image (in this case from a LEVER file)
strDB='../../sampleImages/lscSampleImage.LEVER';
[im,CONSTANTS]=leversc.loadImage(strDB);
A leversc class object must be initialized, here we initialize the leversc class with image data and metadata (metadata fields such as PixelPhysicalSize
are important for correct data visualization).
% Initialize leversc class with image and metadata
lsc=leversc(im,CONSTANTS);
A reproducible movie render should set the rendering parameters consistently at the beginning of rendering to properly visualize the data.
In this case we used the LEVERSC tool interface to interactively identify good visualization values, then used the /renderParams
API call to read the current settings.
The image below shows the LEVERSC interface for selecting visualization (rendering) parameters:
The selected rendering parameters were hard-coded into our rendering script.
%% Set up pre-selected render properties
lsc.renderParams(1).alpha = 1;
lsc.renderParams(1).dark = 0;
lsc.renderParams(1).medium = 0.78;
lsc.renderParams(1).bright = 0.96;
lsc.renderParams(1).color = [1;1;1];
We disable the display of most UI elements
%% Disable most UI elements
lsc.uiParams.sidebar='none';
lsc.uiParams.clockButton='none';
lsc.uiParams.webToolbar='none';
We reset the view parameters to defaults for the start of the movie:
%% Reset view parameters (also set background to black)
lsc.viewParams.clipMode = 0;
lsc.viewParams.worldRot = reshape([1,0,0,0; 0,1,0,0; 0,0,1,0; 0,0,0,1], 16,1);
lsc.viewParams.zoom = 0;
lsc.viewParams.bgColor = [0,0,0];
The first step in this movie is to apply a quick animated zoom to fill the display with the actual data in the volume, capturing frames for each zoom level. Since our movie will run at 10 frames per second (fps) we interpolate our zoom over 10 frames (a 1 second zoom):
%% Quick zoom from 0 to 0.4 (1 sec = 10 frames)
zlevels = linspace(0,0.4, 10);
for i=1:length(zlevels)
lsc.viewParams.zoom=zlevels(i);
imCap = get_rendered_frame(lsc);
if ( bPreview )
imagesc(imCap);
axis image;
drawnow();
else
writeVideo(vidWrite,imCap);
end
end
Next we apply a 5 second (50 frame) rotation of 180 degrees about the y-axis:
%% Rotate halfway around in 5sec
angles = linspace(0,180,50);
for i=2:length(angles)
ry=[cosd(angles(i)), 0, sind(angles(i)),0;
0,1,0,0;
-sind(angles(i)),0,cosd(angles(i)),0;
0,0,0,1];
worldRot=ry;
lsc.viewParams.worldRot=worldRot(:);
imCap = get_rendered_frame(lsc);
if ( bPreview )
imagesc(imCap);
axis image;
drawnow();
else
writeVideo(vidWrite,imCap);
end
end
Next we move the sampling plane to the edge of the volume and turn on planar clipping. Then we animate moving the plane to just a little back from the volume center. The plane animation is 2 seconds (20 frames) long:
%% Put sample plane at the back of the volume and set to planar clipping mode,
%% then animate plane movement into just back from center
planeZs = linspace(85,50, 20);
lsc.viewParams.planeCenter(3) = planeZs(1);
lsc.viewParams.clipMode = 1; % Plane-clipping mode
for i=1:length(planeZs)
lsc.viewParams.planeCenter(3) = planeZs(i);
imCap = get_rendered_frame(lsc);
if ( bPreview )
imagesc(imCap);
axis image;
drawnow();
else
writeVideo(vidWrite,imCap);
end
end
We apply another 180 degree rotation to rotate the volume the rest of the way back to the starting view. This time we show matrix multiplication for the world rotation matrix by a delta rotation matrix:
%% Rotate the rest of the way around with plane clipping on (5sec)
% This time we use a "delta" rotation matrix to show how matrix
% products can be used
frameRots = 50;
angleDelta = 180 / frameRots;
deltaRY = [cosd(angleDelta), 0, sind(angleDelta),0;
0,1,0,0;
-sind(angleDelta),0,cosd(angleDelta),0;
0,0,0,1];
worldRot = reshape(lsc.viewParams.worldRot, 4,4);
for i=1:frameRots
worldRot = deltaRY * worldRot;
lsc.viewParams.worldRot = worldRot(:);
imCap = get_rendered_frame(lsc);
if ( bPreview )
imagesc(imCap);
axis image;
drawnow();
else
writeVideo(vidWrite,imCap);
end
end
As a final animation, we change the plane clipping mode to slice sampling, and animate moving out of the volume towards the camera:
%% Change to slice clipping mode and pull plane back toward camera
startZ = lsc.viewParams.planeCenter(3);
planeZs = linspace(startZ,1,20);
lsc.viewParams.clipMode = 2; % Slice-clipping mode
for i=1:length(planeZs)
lsc.viewParams.planeCenter(3) = planeZs(i);
imCap = get_rendered_frame(lsc);
if ( bPreview )
imagesc(imCap);
axis image;
drawnow();
else
writeVideo(vidWrite,imCap);
end
end
If run with the bPreview
flag set to false, this will generate lscSampleMovie.mp4
.
NOTE: The LEVERSC window size will determine the resolution of the video produced, so it is important to set the window size appropriately before running the video script.
Using the example shown here, as well as the full viewParams
and renderParams
API calls, complex camera and movie effects can be built through interpolation of multiple parameters at each frame.