-
-
Save miura/3736860 to your computer and use it in GitHub Desktop.
Using TurboReg from ImageJ macro, to output shifts.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var npos = 0; // this variable is better be global. | |
var directapply = 0; // "boolean" user input direct application of driftcorrect | |
var crop = 0; // "boolean" user input crop to ROI | |
var splitch = 0; // "boolean" user input splitting of channels | |
var targetstack = 1 // ImageID of the stack that is to be processed | |
var dir; | |
var cropxmax = 0; | |
var cropymax = 0; | |
var minout = 0; | |
var maxout = 0; | |
macro "CCS_APP" { | |
ipos = 0; // imaged position currently processed and "number of the file" | |
ch = 0; // channel, standardmäßig auf 0! | |
frame = 0; | |
slice = 0; | |
// -------------- Start of actual code ---------------- | |
setBatchMode(true); | |
openim = nImages(); | |
sel_im = newArray(nImages()+2); | |
for (i = 0; i < nImages; i++) // creating dropdown array | |
{ | |
selectImage(i+1); | |
sel_im[i] = getTitle(); | |
} | |
sel_im[sel_im.length-2] = "Open single stack"; | |
sel_im[sel_im.length-1] = "Batch-process folder"; | |
setBatchMode(false); | |
Dialog.create("Driftcorrect"); // creating startup dialog | |
Dialog.addChoice("Driftcorrect", sel_im); | |
Dialog.addCheckbox("Show corrected stack(s)", true); | |
Dialog.addCheckbox("Crop to covered region", true); | |
Dialog.addCheckbox("Split channels after correction", true); | |
Dialog.show(); | |
mode = Dialog.getChoice(); | |
directapply = Dialog.getCheckbox(); | |
crop = Dialog.getCheckbox(); | |
splitch = Dialog.getCheckbox(); | |
print(mode + "-mode"); | |
//---- single mode ----- | |
if (mode == "Open single stack") | |
{ | |
npos = 1; | |
ipos = 1; | |
dir = File.openDialog("Please select the stack"); | |
run("Bio-Formats Importer", | |
"open=[" + dir +"]" | |
+ " autoscale" | |
+ " color_mode=Grayscale" | |
+ " view=Hyperstack" | |
+ " stack_order=XYCZT" | |
); | |
openimage = getImageID(); | |
measure_driftcorrect(openimage); | |
if (directapply == true) | |
{ | |
selectImage(openimage); | |
apply_driftcorrect(openimage, crop); | |
} | |
if (splitch == true) | |
{ | |
selectImage(openimage); | |
run("Split Channels"); | |
} | |
} | |
//------- batch-process mode ------- | |
if (mode == "Batch-process folder") | |
{ | |
setBatchMode(true); | |
dir = getDirectory("Please select a folder containing stacks"); | |
dv_file_counter(dir); | |
for (ipos = 0 ; ipos <= npos; ipos++) //Image importer loop. | |
{ | |
run("Bio-Formats Importer", | |
"open=[" + dir + "/pos" + ipos + ".dv]" | |
+ " autoscale" | |
+ " color_mode=Grayscale" | |
+ " view=Hyperstack" | |
+ " stack_order=XYCZT" | |
+ " use_virtual_stack") | |
measure_driftcorrect("pos" + ipos +".dv - C=0"); | |
for (f = 0; f<2; f++){ | |
apply_driftcorrect("pos" + ipos +".dv - C=" + f); | |
//close(); | |
} | |
} | |
setBatchMode(false); | |
} | |
//----------- already opened image mode ------------ | |
else | |
{ | |
selectWindow(mode); | |
dir = getInfo("image.filename"); // getting path of open image | |
openimage = getImageID(); | |
measure_driftcorrect(openimage); | |
if (directapply == true) | |
{ | |
selectImage(openimage); | |
apply_driftcorrect(openimage, crop); | |
} | |
if (splitch == true && chn > 1) | |
{ | |
selectImage(openimage); | |
run("Split Channels"); | |
} | |
} | |
print("I'm done."); | |
} // end Macro | |
// ------ function definitions ------- | |
function dv_file_counter(dir) | |
{ | |
list = getFileList(dir); | |
for (i = 0; i < list.length; i++) | |
if (endsWith(list[i], ".dv") == true) | |
npos++; | |
if (npos <= 0) | |
exit("No *.dv files in chosen directory."); | |
else | |
write(npos + " *.dv files found in chosen directory."); | |
} // end of function | |
function measure_driftcorrect(dcstack) // add batchmode=true arg? | |
{ | |
setBatchMode(true); | |
if (isOpen(dcstack) != true) //check that target-window open | |
exit("The stack you want to correct for drift is not open!"); | |
else | |
{ | |
selectImage(dcstack); | |
Stack.getDimensions(w, h, chn, sln, frn); | |
filename = getInfo("image.filename"); | |
dcresultsx = newArray(frn+1); | |
dcresultsy = newArray(frn+1); | |
cenSl = sln/2; // go to central Z-postition. dirty here! needs to be rounded up! cenSl: central slice | |
write("Moving to slice " + cenSl + " of " + sln); | |
Stack.setSlice(cenSl); | |
run("Reduce Dimensionality...", " frames keep"); // das neue Window heißt wie das alte, nut mit einem "-1" dahinter | |
dcstack_reduced = getImageID(); // | |
selectImage(dcstack_reduced); // select new window with the reduced timepoint | |
Stack.setFrame(0); // set to first time frame - for StackReg as reference | |
write("Starting driftcorrect measurement on position " + ipos + ", slide " + cenSl); | |
for (frame = 0; frame <= frn; frame++) | |
{ | |
selectImage(dcstack_reduced); | |
Stack.setFrame(frame); | |
run("Duplicate...", "title=sourceimage"); | |
frame1 = "sourceimage"; // a frame in a sequence | |
selectImage(dcstack_reduced); | |
Stack.setFrame(frame + 1); // select next frame. | |
run("Duplicate...", "title=targetimage"); | |
frame2 = "targetimage"; // next frame in the sequence | |
selectWindow(frame1); | |
width = getWidth(); | |
height = getWidth(); | |
run("TurboReg ", | |
"-align " | |
+ "-window " + frame1 + " "// Source (window reference). | |
+ " 0 0 " + (width - 1) + " " + (height - 1) | |
+ " -window " + frame2 + " "// Target (window reference). | |
+ " 0 0 " + (width - 1) + " " + (height - 1) | |
+ " -translation" | |
+ " " + (width / 2) + " " + (height / 2) | |
+ " " + (width / 2) + " " + (height / 2) | |
+ " -hideOutput" | |
); | |
sourceX0 = getResult("sourceX", 0); // First line of the table. | |
sourceY0 = getResult("sourceY", 0); | |
targetX0 = getResult("targetX", 0); | |
targetY0 = getResult("targetY", 0); | |
xoffset = sourceX0 - targetX0; // calculate offsets in respect to previous image. | |
yoffset = sourceY0 - targetY0; | |
xoffsetsum = xoffsetsum + xoffset; // x and yoffsetsums: values each frame has to be aligned in respect to first frame. | |
yoffsetsum = yoffsetsum + yoffset; | |
dcresultsx[frame] = xoffsetsum; // saving results for each frame in arrays | |
dcresultsy[frame] = yoffsetsum; | |
print("Frame " + frame + " - x: " + xoffsetsum + " y: " + yoffsetsum); | |
selectWindow(frame1); | |
close(); | |
selectWindow(frame2); | |
close(); | |
} // closes for (frame = 0; frame <= driftcorfrn; frame++); | |
} //closes else | |
selectImage(dcstack_reduced); | |
close(); | |
print("Done calculating drift in position " + ipos); | |
run("Clear Results"); // transferring results to results-table | |
for (i = 0; i < dcresultsx.length; i++) | |
{ | |
setResult("Frame", i, i); | |
setResult("X-offsetsum", i, dcresultsx[i]); | |
setResult("Y-offsetsum", i, dcresultsy[i]); | |
} | |
absolute_max(dcresultsx); // absolute maxfunction here! | |
setResult("X-max", 0, maxout); | |
absolute_max(dcresultsy); | |
setResult("Y-max", 0, maxout); | |
updateResults(); | |
selectWindow("Results"); | |
filename1 = split(filename, "."); | |
print("Saving results as " + filename1[0] + "driftcor.xls"); | |
saveAs("Results", filename1[0] + "driftcor.xls"); // saves resultstable as a file. | |
selectImage(dcstack); | |
close(); | |
setBatchMode(false); | |
} // end of function | |
function apply_driftcorrect(targetstack, croparg) // targetstack is ImageID | |
{ | |
selectImage(targetstack); | |
Stack.getDimensions(w, h, chn, sln, frn); | |
for (frame = 0; frame <= frn; frame++) // frame <= frn!! | |
{ | |
corx = getResult("X-offsetsum", frame); // load corrected x-position from results-table | |
cory = getResult("Y-offsetsum", frame); // load corrected y-position | |
for (slice = 1; slice <= sln; slice++) // shift all z-slices of one frame | |
{ | |
for (channel = 1; channel <= chn; channel++) | |
{ | |
selectImage(targetstack); | |
Stack.setPosition(channel, slice, frame); | |
run("Translate...", "x=" + corx + " y=" + cory + " interpolation=None slice"); | |
} | |
} | |
} | |
if (croparg == true) | |
{ | |
makeRectangle( getResult("X-max", 0), getResult("Y-max", 0), w-getResult("X-max", 0), h-getResult("Y-max",0)); | |
run("Crop"); | |
} | |
} // end of function | |
function absolute_max(array) | |
{ | |
Array.getStatistics(array, min, max, mean, stdDev); | |
if (abs(min) <= abs(max)) | |
{maxout = max;} | |
if (abs(min) > abs(max)) | |
{maxout = min;} | |
} // end of function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Dear miura,
My name is mengda. When I run TurboReg to registrate a stack of images(source) to another single image(target) from Macro, only the first two slice is registrated and outputted(perfectly rotated), however, the rest slices seems stucked and not outputted. But if I run it manually by clicking TurboReg and set the parameter in panel, and click "Batch" button, then whole stack registrated (perfectly rotated).
Do you know what should be considered in code when processing stack as source in batch mode?
Thanks in advance!
The code is:
run("TurboReg ",
"-align " // Register the two images that we have just prepared.
+ "-window " + sourceName + " "// Source (window reference).
+ "0 0 " + (width - 1) + " " + (height - 1) + " " // No cropping.
+ "-window " + targetName + " "// Target (file reference).
+ "0 0 " + (width - 1) + " " + (height - 1) + " " // No cropping.
+ "-affine "
+ (width / 2) + " " + (height / 2) + " " // Source translation landmark.
+ (width / 2) + " " + (height / 2) + " " // Target translation landmark.
+ "0 " + (height / 2) + " " // Source first rotation landmark.
+ "0 " + (height / 2) + " " // Target first rotation landmark.
+ (width - 1) + " " + (height / 2) + " " // Source second rotation landmark.
+ (width - 1) + " " + (height / 2) + " " // Target second rotation landmark.
+ "-showOutput");