Re: Save orthogonal views as avi?
Posted by Martin Höhne on Oct 09, 2012; 7:16am
URL: http://imagej.273.s1.nabble.com/Save-orthogonal-views-as-avi-tp5000314p5000349.html
meanwhile I managed to write a macro that does what I want. Just in case anyone is interested.
Martin
-------------
/*
* Macro to fullfill this task I asked for in the ImageJ-list:
* Dear list,
* when I have a z-stack (RGB) and view this stack with the orthogonal views switched on,
* I can play that stack, i.e. move through the z-stack and the yellow cross-hair is
* moving in parallel in the yz and xz view.
* Is there a way of saving this whole view, i.e. xy, yz and xz including the moving
* yellow crosshair in one series/avi?
*
* The idea how to solve this (use reslice and combine stacks) is from the reply from Tiago Ferreira.
*
*
* Martin Hoehne 2012-10-08
*
*/
macro "Ortho view movie" {
if (nImages()!=0) exit ("please close all other images before running the macro");
//open file and create results dir
// path = File.openDialog("Select the file");
// open(path);
run("Bat Cochlea Volume (19K)"); //works as a testfile
getDimensions(width, height, channels, slices, frames);
getVoxelSize(voxwidth, voxheight, depth, unit);
run("Orthogonal Views");
msg1 = "\nPostion the crosshair in the xy window."+
"\n(original stack)"+
"\n \nWhen done, continue with <OK>";
waitForUser(msg1);
setBatchMode(true);
// get the position where the user has put the yellow cross-hair in the xy-stack
for (i=1; i<=3; i++){
img=getTitle();
if (substring(img,0,2)=="YZ") {
yzID = getImageID();
x=coord(img);
rename("YZ_"+x); //no space in title allowed to combine stacks later in macro
yztitle=getTitle();
}
if (substring(img,0,2)=="XZ") {
xzID = getImageID();
y=coord(img);
rename("XZ_"+y); //no space in title allowed to combine stacks later in macro
xztitle=getTitle();
}
close();
// in the first round the original image is still selected and closed
// in the next two round the YZ and XZ views are selected, resp.
// I could not find another way of getting hold of the titles of the
// XZ and YZ windows
}
// image has to be reopened
run("Bat Cochlea Volume (19K)");
//open(path);
run("RGB Color");
imgID=getImageID();
setLineWidth(20);
// reslice YZ (single slice at the position (x) chosen by the user
selectImage(imgID);
makeLine(x,0,x,height);
run("Add Selection...", "stroke=green width=1"); //add the vertical crosshair line to the selection
run("Reslice [/]...", "output="+ depth+" slice_count=1 rotate");
getDimensions(w,h,c,s,f); //dimensions are dependent on depth, i.e. slice thickness
// green frame around the image
setBackgroundColor(0,255,0);
run("Canvas Size...","width="+w+4+" height="+h+4+" position=Center");
rename("YZ_"+ x);
orthoYZ=getImageID();
makestack(orthoYZ, slices, width, height, voxwidth, voxheight, depth, 1);
// reslice XZ (single slice at the position (y) chosen by the user
selectImage(imgID);
makeLine(0,y,width,y);
run("Add Selection...", "stroke=orange width=1"); //add the horizontal crosshair line to the selection
run("Reslice [/]...", "output="+ depth+" slice_count=1");
getDimensions(w,h,c,s,f); //dimensions are dependent on depth, i.e. slice thickness
// orange frame around the image
setBackgroundColor(255,153,0);
run("Canvas Size...","width="+w+4+" height="+h+4+" position=Center");
rename("XZ_"+ y);
orthoXZ=getImageID();
makestack(orthoXZ, slices, width, height, voxwidth, voxheight, depth, 2);
// Flatten the crosshair onto the original xy-stack
selectImage(imgID);
run("Flatten", "stack");
// white frame around the image
setBackgroundColor(255, 255, 255);
run("Canvas Size...", "width="+width+4+" height="+height+4+" position=Center");
// combine views
stk1=getTitle();
setBackgroundColor(40, 40, 40);
run("Combine...", "stack1="+ stk1 +" stack2="+ yztitle);
rename("combi1");
run("Combine...", "stack1=combi1" +" stack2="+ xztitle +" combine");
setBatchMode(false);
// grey frame around the image + labeling
getDimensions(w,h,c,s,f); //dimensions of the combined stacks
run("Canvas Size...", "width="+w+20+" height="+h+40+" position=Center");
setFont("Sanserif", 14);
makeText("xy view", 20, 0);
run("Add Selection...", "stroke=white");
makeText("xz view", 20, h+18);
run("Add Selection...", "stroke=orange");
makeText("yz view", w-44,0);
run("Add Selection...", "stroke=green");
// stupid command to unselect the "yz view" text -- most likely there are more elegant ways
makePoint(w*2, h);
}
//-FUNCTIONS-----------------------------------------------------------------------------------//
function coord(imgname) {
// function returns the x or y value of the selected section. Extracted from the image title
//(e.g. title = YZ 123) --> 123 is returned
string=substring(imgname,3,lengthOf(imgname));
return parseInt(string);//Converts string to an integer and returns it. Returns NaN if the string cannot be converted into a integer.
}
function makestack(imgID, slices, xmax, ymax, voxwidth, voxheight, depth, orient) {
// duplicate the YZ or the XZ image resp. z-times (i.e. make a stack with
// identical number of slices as the original x-y-z stack.
// Draw a line in each of the images indicating a different z-position. If the z-slice
// is thicker than 1 pixel (interpolated) the line is drawn in the middle of the slice position
//
// The last argument of the function (orient) is needed for the orientation
setForegroundColor(255, 255, 255);
neuID = getImageID();
titel = getTitle();
run("Select All");
run("Copy");
run("Duplicate...", "title=["+titel+"]");
dup=getImageID();
selectImage(neuID);
close();
selectImage(dup);
for (i=0; i<slices; i++) {
run("Paste");
// draw line indicating the z-plane
if (orient==1) {
zspace=depth/voxwidth; //take thickness of z-slices into account
drawLine(i*zspace+zspace/2,2,i*zspace+zspace/2,ymax+1);
}
if (orient==2) {
zspace=depth/voxheight;
drawLine(2,i*zspace+zspace/2,xmax+1,i*zspace+zspace/2);
}
run("Add Slice");
}
run("Delete Slice");
}