Skip to content

Instantly share code, notes, and snippets.

@ekatrukha
Created February 7, 2019 18:03
Show Gist options
  • Save ekatrukha/815c2a739262afe5649682a670ea7c05 to your computer and use it in GitHub Desktop.
Save ekatrukha/815c2a739262afe5649682a670ea7c05 to your computer and use it in GitHub Desktop.
ImageJ macro making a tilted movie out of Z-stack
//ImageJ macro making a tilted movie out of stack
//uses shear transform + rotation
//Eugene Katrukha katpyxa at gmail.com
requires("1.48h");
sTitle=getTitle();
sMovieTitle=sTitle+"_tilt_movie";
setBatchMode(true);
//Dialog
Dialog.create("Tilt parameters:");
Dialog.addNumber("Tilt radius in X (px):", 20);
Dialog.addNumber("Tilt radius in Y (px):", -20);
Dialog.addNumber("Rotation angle:", 15);
Dialog.addNumber("Number of movie frames:", 40);
sZChoice=newArray("Last frame is top","First frame is top");
Dialog.addChoice("Z direction:", sZChoice);
Dialog.show();
nCurrStepX=Dialog.getNumber();
nCurrStepY=Dialog.getNumber();
nCurrRotAngle=0.5*Dialog.getNumber();
nSteps=Dialog.getNumber();
sChoice=Dialog.getChoice();
nStepX=(-2)*nCurrStepX/nSteps;
nStepY=(-2)*nCurrStepY/nSteps;
//nRotationRange = 20;
nRotStep = (-2.0)*nCurrRotAngle/nSteps;
init=getImageID();
bNotFirstIt=false;
print("Starting movie generation...");
for (i=0;i<nSteps;i++)
{
run("Duplicate...", "duplicate");
copyx=getImageID();
for (j=0;j<nSlices;j++)
{
if(startsWith(sChoice, "Last"))
{ setSlice(nSlices-j);}
else {
setSlice(j+1);}
//making shear transform with respect to stack center
dx=2.*((j-nSlices*0.5)*nCurrStepX/nSlices);
dy=2.*((j-nSlices*0.5)*nCurrStepY/nSlices);
runstring="x="+toString(dx)+" y="+toString(dy)+" interpolation=Bilinear slice";
run("Translate...", runstring);
}
//adding some rotation
run("Z Project...", "projection=[Max Intensity]");
runstring="angle="+toString(nCurrRotAngle)+" grid=1 interpolation=Bicubic";
run("Rotate... ", runstring);
if(bNotFirstIt)
{
sCurrTitle=sTitle+"_frame"+toString(i);
rename(sCurrTitle);
run("Concatenate...", " title=["+sMovieTitle+"] image1=["+sMovieTitle+"] image2=["+sCurrTitle+"]");
sMovieID=getImageID();
}
else
{
rename(sMovieTitle);
sMovieID=getImageID();
bNotFirstIt=true;
}
//updating rotate/shear counters
nCurrStepX=nCurrStepX+nStepX;
nCurrStepY=nCurrStepY+nStepY;
nCurrRotAngle= nCurrRotAngle+nRotStep;
selectImage(copyx);
close();
selectImage(init);
print("Frame " +toString(i+1) +" out of "+toString(nSteps));
}
selectImage(sMovieID);
setBatchMode(false);
print("Done");
@gletort
Copy link

gletort commented Feb 8, 2019

Hi ! Great macro !
If you are interested, I did a plugin version of it: https://github.com/gletort/ImageJFiles/tree/master/3DTilt, to make it faster and it can handle hyperstack. I cannot contribute it to your gist though as it doesn't handle .jar files well.

@maciejmotyka
Copy link

Hi! Thank you both for this useful tool.
I have some confocal z-stacks with slices apart by 10.5 pixels. Does this macro/plugin take into account slice spacing?
So far I've been using the 3D Project plugin, which has an option to specify the slice spacing. With 3DTilt is it enough to set the voxel size to 1x1x10.5, or is it necessary to alter the code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment