diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b689f3e --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Compiled files +/MT2-project-ImageProcessing/plugins/ +*.class + +# Archives +*.zip +*.tar.gz +*.tar +*.rar + +# macOS cache files +.DS_Store + +# Temporary files +*.tmp diff --git a/MT2-project-ImageProcessing.zip b/MT2-project-ImageProcessing.zip deleted file mode 100644 index 8d8e423..0000000 Binary files a/MT2-project-ImageProcessing.zip and /dev/null differ diff --git a/MT2-project-ImageProcessing/.idea/.gitignore b/MT2-project-ImageProcessing/.idea/.gitignore new file mode 100644 index 0000000..8bfa967 --- /dev/null +++ b/MT2-project-ImageProcessing/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ + +# Editor-based HTTP Client requests +/httpRequests/ +# Environment-dependent path to Maven home directory +/mavenHomeManager.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/MT2-project-ImageProcessing/.idea/libraries/ij.xml b/MT2-project-ImageProcessing/.idea/libraries/ij.xml new file mode 100644 index 0000000..8037f06 --- /dev/null +++ b/MT2-project-ImageProcessing/.idea/libraries/ij.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/MT2-project-ImageProcessing/.idea/misc.xml b/MT2-project-ImageProcessing/.idea/misc.xml new file mode 100644 index 0000000..235ccb7 --- /dev/null +++ b/MT2-project-ImageProcessing/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/MT2-project-ImageProcessing/.idea/modules.xml b/MT2-project-ImageProcessing/.idea/modules.xml new file mode 100644 index 0000000..866a26e --- /dev/null +++ b/MT2-project-ImageProcessing/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/MT2-project-ImageProcessing/.idea/runConfigurations.xml b/MT2-project-ImageProcessing/.idea/runConfigurations.xml new file mode 100644 index 0000000..93e4b17 --- /dev/null +++ b/MT2-project-ImageProcessing/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/MT2-project-ImageProcessing/.idea/vcs.xml b/MT2-project-ImageProcessing/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/MT2-project-ImageProcessing/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/MT2-project-ImageProcessing/.idea/workspace.xml b/MT2-project-ImageProcessing/.idea/workspace.xml new file mode 100644 index 0000000..7bab5f0 --- /dev/null +++ b/MT2-project-ImageProcessing/.idea/workspace.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1736514014989 + + + + + + \ No newline at end of file diff --git a/MT2-project-ImageProcessing/MT2-project-ImageProcessing.iml b/MT2-project-ImageProcessing/MT2-project-ImageProcessing.iml new file mode 100644 index 0000000..5e6f2af --- /dev/null +++ b/MT2-project-ImageProcessing/MT2-project-ImageProcessing.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MT2-project-ImageProcessing/ij.jar b/MT2-project-ImageProcessing/ij.jar new file mode 100644 index 0000000..91fc6af Binary files /dev/null and b/MT2-project-ImageProcessing/ij.jar differ diff --git a/MT2-project-ImageProcessing/img/cells.png b/MT2-project-ImageProcessing/img/cells.png new file mode 100644 index 0000000..aa4d6b5 Binary files /dev/null and b/MT2-project-ImageProcessing/img/cells.png differ diff --git a/MT2-project-ImageProcessing/img/cells_reference.png b/MT2-project-ImageProcessing/img/cells_reference.png new file mode 100644 index 0000000..f0f2f49 Binary files /dev/null and b/MT2-project-ImageProcessing/img/cells_reference.png differ diff --git a/MT2-project-ImageProcessing/macros/AA_ReadMe.txt b/MT2-project-ImageProcessing/macros/AA_ReadMe.txt new file mode 100644 index 0000000..3aa0849 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/AA_ReadMe.txt @@ -0,0 +1,26 @@ +This folder contains ImageJ macros. You open a macro file using the +File->Open command and run it by pressing ctrl-r (File->Run Macro). +You can also open a macro file by dragging and dropping it on the +main ImageJ window. You can run a small piece of macro code by selecting +it in the editor and typing ctrl-r. Some of the files (e.g., MacroSet.txt) +contain multiple macros that are installed in the editor's "Macros" menu. + +Macros located in the ImageJ/plugins folder, with names containing an +an underscore ("_") or ending in ".ijm", are installed in the Plugins menu. +Examples of such macros can be found in ImageJ/plugins/Examples/_Macros. + +Macros and macro tools in the ImageJ/macros/StartupMacros.txt file are +installed in the Plugins>Macros submenu and in the toolbar when ImageJ +starts. Macros can be assigned keyboard shortcuts. For examples, +refer to the macros/MacroSet.ijm file. Note that macro shortcuts only +work when an image window or the ImageJ window has focus. + +The tools folder contains tool macros that are added to ImageJ's tool +bar when you open the file. The toolsets folder contains macro sets +that are installed in the toolbar's ">>" menu when ImageJ starts. + +Information about the macro language (including a 48 page PDF), +a list of the built in macro functions and more example macros are +available at + + http://imagej.nih.gov/ij/developer diff --git a/MT2-project-ImageProcessing/macros/About Startup Macros b/MT2-project-ImageProcessing/macros/About Startup Macros new file mode 100644 index 0000000..043703b --- /dev/null +++ b/MT2-project-ImageProcessing/macros/About Startup Macros @@ -0,0 +1,9 @@ + Macros and macro tools in ImageJ/macros/StartupMacros.txt + are automatically installed in the Plugins>Macros menu and + in the toolbar when ImageJ starts. Use the Plugins>Macros> + Startup Macros... command to display or edit this file. + + More information is available at: + + + diff --git a/MT2-project-ImageProcessing/macros/AnimatedGaussianBlur.ijm b/MT2-project-ImageProcessing/macros/AnimatedGaussianBlur.ijm new file mode 100644 index 0000000..f279678 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/AnimatedGaussianBlur.ijm @@ -0,0 +1,26 @@ +// Animated Gaussian Blur +// +// Creates a 51 frame stack containing a copy of the current +// image plus copies blurred using the Gaussian Blur filter +// with the radius varying between 1 and 50. + + if (nImages==0) + run("Blobs (25K)"); + inc=1; max=50; + run("Select All"); + run("Copy"); + setBatchMode(true); + run("Duplicate...", "title=[Animated Gaussian Blur]"); + slice = 0; + for (radius=inc; radius<=max; radius+=inc) { + run("Add Slice"); + run("Paste"); + run("Gaussian Blur...", "slice radius="+radius); + setMetadata("radius="+radius); + showProgress(radius, max/inc); + } + setSlice(1); + setMetadata("original"); + setBatchMode(false); + run("Select None"); + doCommand("Start Animation") diff --git a/MT2-project-ImageProcessing/macros/AnimationMacros.ijm b/MT2-project-ImageProcessing/macros/AnimationMacros.ijm new file mode 100644 index 0000000..0209fcf --- /dev/null +++ b/MT2-project-ImageProcessing/macros/AnimationMacros.ijm @@ -0,0 +1,12 @@ +// These macros allow you to use the 0, 1, 2, etc. +// keys to slow down or speed up an animation. + + macro "1 fps [1]" {run("Animation Options...", "speed=1 start");} + macro "2 fps [2]" {run("Animation Options...", "speed=2 start");} + macro "5 fps [3]" {run("Animation Options...", "speed=5 start");} + macro "7.5 fps [4]" {run("Animation Options...", "speed=7.5 start");} + macro "10 fps [5]" {run("Animation Options...", "speed=10 start");} + macro "15 fps [6]" {run("Animation Options...", "speed=15 start");} + macro "20 fps [7]" {run("Animation Options...", "speed=20 start");} + macro "30 fps [8]" {run("Animation Options...", "speed=30 start");} + macro "60 fps [9]" {run("Animation Options...", "speed=60 start");} diff --git a/MT2-project-ImageProcessing/macros/BatchModeCalculator.ijm b/MT2-project-ImageProcessing/macros/BatchModeCalculator.ijm new file mode 100644 index 0000000..21f4e83 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/BatchModeCalculator.ijm @@ -0,0 +1,12 @@ +// This macro demonstrates how to use +// the Image Calculator in batch mode. + + setBatchMode(true); + run("Clown (14K)"); + img1 = getTitle(); + run("Lena (68K)"); + img2 = getTitle(); + run("Image Calculator...", + "image1=&img1 operation=Average image2=&img2 create"); + run("Rename...", "title=Sum"); + setBatchMode(false); diff --git a/MT2-project-ImageProcessing/macros/BatchModeTest.ijm b/MT2-project-ImageProcessing/macros/BatchModeTest.ijm new file mode 100644 index 0000000..2d6c18f --- /dev/null +++ b/MT2-project-ImageProcessing/macros/BatchModeTest.ijm @@ -0,0 +1,16 @@ +// This macro is an example that shows how to process +// an image in batch mode and then display the result. + + setBatchMode(true); + run("Clown (14K)"); + makeRectangle(104, 72, 150, 159); + run("Fill"); + run("Select None"); + run("Rotate... ", "angle=15 interpolation=Bilinear"); + run("Smooth"); + run("Find Edges"); + run("Add...", "value=25"); + run("Gaussian Blur...", "radius=2"); + run("Median...", "radius=1"); + run("Unsharp Mask...", "gaussian=2 mask=0.60"); + setBatchMode(false); // displays the image diff --git a/MT2-project-ImageProcessing/macros/Calculations.ijm b/MT2-project-ImageProcessing/macros/Calculations.ijm new file mode 100644 index 0000000..022cf86 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/Calculations.ijm @@ -0,0 +1,20 @@ +// The macro interpreter will evaluate expressions and +// display the results without having to use the print() +// function or having to put a simicolon at the end +// of each line. + +// Press ctrl+r (Macros>Run Macro) to evaluate the +// following expressions. Select one or more lines and +// press ctrl+r to evaluate just the selected lines. +// Press ctrl+e (Macros>Evaluate Line) to evaluate the +// current line. + + 2+2 + (2.5+1)/3 + cos(0.7*PI) + "2^10=" + pow(2,10) + "log(0)=" + log(0) + "100 in hex=" + toHex(100) + "FF in decimal=" + 0xff; + r = 10 + "radius=" + r + "mm, area=" + round(PI*r*r) + "mm^2" diff --git a/MT2-project-ImageProcessing/macros/CompositeSelections.ijm b/MT2-project-ImageProcessing/macros/CompositeSelections.ijm new file mode 100644 index 0000000..3f2dcde --- /dev/null +++ b/MT2-project-ImageProcessing/macros/CompositeSelections.ijm @@ -0,0 +1,44 @@ +// "CompositeSelections" +// This macro demonstrates how to create composite selections using +// makeOval(), makeRectangle() and makePolygon(), in combination +// with setKeyDown("shift") (to add selections) and setKeyDown("alt") +// (to subtract selections). + + width=400; height=400; + saveSettings; + run("Colors...", "selection=red"); + newImage("Composite Selections", "8-bit White", 400, 400, 1); + setLocation(screenWidth/2-width/2, screenHeight/10); + makeOval(110, 94, 156, 156); + setKeyDown("alt"); + makeOval(144, 129, 87, 87); + show(); + + makeOval(62, 40, 55, 55); + setKeyDown("shift"); + makeOval(246, 49, 60, 60); + setKeyDown("shift"); + makeOval(285, 200, 60, 60); + setKeyDown("shift"); + makeRectangle(136, 254, 58, 58); + setKeyDown("shift"); + makeRectangle(31, 150, 58, 58); + show(); + + makePolygon(84,182,143,127,212,87,260,124,301,202,290,255,247,253,214,188,190,195,134,249,87,247,116,201); + setKeyDown("alt"); + makePolygon(228,136,158,151,137,189,143,204,193,171,243,183,260,174); + setKeyDown("shift"); + makePolygon(264,70,285,48,311,43,369,76,363,189,322,186,300,140,271,116); + show(); + + restoreSettings; + + + function show() { + for (i=0; i<10; i++) { + run("Invert"); + wait(150); + } + wait(1000); + } diff --git a/MT2-project-ImageProcessing/macros/ConvertOverlayToIcon.ijm b/MT2-project-ImageProcessing/macros/ConvertOverlayToIcon.ijm new file mode 100644 index 0000000..50d1381 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/ConvertOverlayToIcon.ijm @@ -0,0 +1,131 @@ +// This macro converts an overlay or selection in a 16x16 image into +// a tool icon. Type "1" to create a 16x16 image. Type "b" to add a +// selection to the overlay. Type "y" to display the Properties dialog, +// where you can set the selection's outline or fill colors. Press "2" +// to convert the overlay or selection into a tool icon. Press "3" to +// remove the overlay. + + convertOverlayToIcon(); + exit; + + macro "New Image [1]" { + newImage("Untitled", "8-bit black", 16, 16, 1); + run("In [+]"); + run("In [+]"); + run("In [+]"); + run("In [+]"); + run("In [+]"); + run("In [+]"); + run("In [+]"); + run("In [+]"); + run("In [+]"); + } + + macro "Convert [2]" { + convertOverlayToIcon(); + } + + macro "Remove Overlay [3]" { + run("Remove Overlay"); + } + + function convertOverlayToIcon() { + requires("1.48j"); + if (getWidth>17 || getHeight>17) + exit("Image cannot be larger then 17x17"); + if (Overlay.size==0 && selectionType==-1) + exit("Overlay or selection required"); + icon = ""; + if (Overlay.size>0) { + for (i=0; imax) n=max; + c = "0"; + if (n<16) + c = toHex(n); + else if (n==16) + c = "g"; + else if (n==17) + c = "h"; + String.append(c); + } + + function color(c) { + r = call("ij.plugin.Colors.getRed", c); + g = call("ij.plugin.Colors.getGreen", c); + b = call("ij.plugin.Colors.getBlue", c); + r=parseInt(r); g=parseInt(g); b=parseInt(b); + String.append("C"); + hex(floor(r/16)); hex(floor(g/16)); hex(floor(b/16)); + } + diff --git a/MT2-project-ImageProcessing/macros/CreateImageFromFunction.ijm b/MT2-project-ImageProcessing/macros/CreateImageFromFunction.ijm new file mode 100644 index 0000000..26fc8e7 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/CreateImageFromFunction.ijm @@ -0,0 +1,23 @@ +// This macro uses a math function to generate an image. + + width = 500; height = 500; + xc = width/2; yc = height/2; + newImage("Math", "32-bit black", width, height, 1); + for (y= 0; y1000) threshold=31; + if (w2>=threshold) { + imp.updateAndDraw(); + delay = (w2-threshold-1)/4; + if (delay>200) delay=200; + if (count<5000) delay+=100; + if (count<1500) delay+=150; + if (count<15) delay+=200; + if (count>50000) delay/=2; + if (delay>1) { + imp.setTitle("Cloud Debugger ("+count+", "+depth+")"); + IJ.wait(delay); + } + } + var cT = (c1 + c2) / 2.0; + var cB = (c3 + c4) / 2.0; + var cL = (c1 + c3) / 2.0; + var cR = (c2 + c4) / 2.0; + plasma(x - size/2, y - size/2, size/2, stddev/2, cL, cM, c3, cB); + plasma(x + size/2, y - size/2, size/2, stddev/2, cM, cR, cB, c4); + plasma(x - size/2, y + size/2, size/2, stddev/2, c1, cT, cL, cM); + plasma(x + size/2, y + size/2, size/2, stddev/2, cT, c2, cM, cR); + depth--; + } diff --git a/MT2-project-ImageProcessing/macros/Examples/JavaScript/Dual_Progress_Bars.js b/MT2-project-ImageProcessing/macros/Examples/JavaScript/Dual_Progress_Bars.js new file mode 100644 index 0000000..2db2da5 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/Examples/JavaScript/Dual_Progress_Bars.js @@ -0,0 +1,10 @@ +// This macro demonstrates how IJ.showProgress() displays subordinate +// progress bars as moving dots when passed a negative argument. + + n = 10; + imp = IJ.createImage("Untitled", "8-bit random", 400, 400, n); + for (i=1; i<=n; i++) { + IJ.showProgress(-i/n); + imp.setSlice(i); + IJ.run(imp, "Median...", "radius=20 slice"); + } diff --git a/MT2-project-ImageProcessing/macros/Examples/JavaScript/Example_Plot.js b/MT2-project-ImageProcessing/macros/Examples/JavaScript/Example_Plot.js new file mode 100644 index 0000000..1a9697c --- /dev/null +++ b/MT2-project-ImageProcessing/macros/Examples/JavaScript/Example_Plot.js @@ -0,0 +1,23 @@ + img = IJ.openImage("http://imagej.nih.gov/ij/images/blobs.gif"); + img.setRoi(new Line(56,64,90,15)); + pp = new ProfilePlot(img); + y1 = pp.getProfile(); + n = y1.length; + x = new Array(n); + for (i=0; irx)&&(xry)&&(y0) { + // move existing star + while ((flags&16)!=0) { + getCursorLoc(x, y, z, flags); + Roi.move(rx+x-x0, ry+y-y0); + wait(10); + } + exit(); + } + // or create a new one + makeLine (x0,y0,x0+1,y0+1); + while ((flags&16)!=0) { + getCursorLoc(x, y, z, flags); + xs=newArray(nPoints*2); + ys=newArray(nPoints*2); + r = maxOf(minSize,sqrt((x-x0)*(x-x0)+(y-y0)*(y-y0))); + a = atan2(x-x0,y-y0); + for (i=0;i1) ration = 1; + lineWidth = Dialog.getNumber(); + fillStar = Dialog.getCheckbox; + if (Dialog.getCheckbox) + run("Color Picker..."); + if (Dialog.getCheckbox) + open("http://wsr.imagej.net/download/Examples/Images/Tree.jpg"); +} diff --git a/MT2-project-ImageProcessing/macros/Examples/Macro/Synthetic_Image.ijm b/MT2-project-ImageProcessing/macros/Examples/Macro/Synthetic_Image.ijm new file mode 100644 index 0000000..1f224e3 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/Examples/Macro/Synthetic_Image.ijm @@ -0,0 +1,29 @@ +// Generates a synthetic image and displays the elapsed +// time as the image title. For speed comparisons, versions +// are available for all ImageJ scripting languages. +// +// Relative speeds (lower is better): +// Java: 1 (0.012) +// Macro: 25 +// Python: 67 +// JavaScript: 125 +// BeanShell: 260 +// +// Delete ImageJ/plugins/jars/BeanShell.jar and restart ImageJ if +// the BeanShell version takes more than a few seconds to run. + + size = 512; + newImage("title", "32-bit black", size, size, 1); + t0 = getTime; + for (y=0; yFFT>Custom Filter command + + // delete any existing filter + if (isOpen("Filter")) { + selectWindow("Filter"); + run("Close"); + } + + // Create filter + // Note that the filer does not have to be the same size as the image + size = 256; + newImage("Filter", "8-bit black", size, size, 1); + radius = size/10; + makeOval(getWidth/2-radius, getHeight/2-radius, radius*2, radius*2); + setForegroundColor(255, 255, 255); + run("Fill"); + run("Select None"); + run("Gaussian Blur...", "radius="+0.9*radius); + //run("Size...", "width=512 height=512 interpolate"); + filter = getImageID(); + + // Create profile plot of filter + makeLine(0, 127, 255, 127); + run("Plot Profile"); + run("Duplicate...", "title='Profile of Filter'"); + selectWindow("Plot of Filter"); + run("Close"); + + // Open a sample image and do low-pass filtering + run("Bridge (174K)"); + //run("Boats (356K)"); + //run("Mandrill (70K)"); + //run("Lena (47K)"); + image = getImageID(); + run("Duplicate...", "title='Low-pass Result'"); + run("Custom Filter...", "filter=Filter"); + run("Enhance Contrast", "saturated=1 "); + + // Do high-pass filtering + selectImage(filter); + run("Invert"); + selectImage(image); + run("Duplicate...", "title='High-pass Result'"); + run("Custom Filter...", "filter=Filter"); + run("Enhance Contrast", "saturated=1 "); + + run("Tile"); diff --git a/MT2-project-ImageProcessing/macros/FilterTester.txt b/MT2-project-ImageProcessing/macros/FilterTester.txt new file mode 100644 index 0000000..65f3423 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/FilterTester.txt @@ -0,0 +1,399 @@ +// An ImageJ macro to test the result of various PlugInFilters +// against a list of previously obtained results. +// Consistancy between stacks and single-image operations, +// correct undo as well as isotropy of filter operations are +// also checked. +// +// version 2021-Jun-07 + +// Options are explained in more detail below +writeResults = false; //usually false, 'true' for learning mode +verbose = false; //usually false, 'true' for debugging or timing +nStackTests = 6; //usually 6, faster if fewer tests +nIsotropyTests = 4; //usually 1 (=none), set to 4 for isotropy tests +maxThreads = 8; //if >0, run with 1...maxThreads +nRuns = 1; //do everything nRun times (set >1 if poorly reproducible) +stopOnFail=true; //stops and shows result on first 'fail' +resultsFile = "FilterTesterTasklist.txt"; //usually "FilterTesterTasklist.txt" +setOption("DisableUndo", false); //usually false, true will cause "Fail: undo" errors, + //but should not cause any other errors + +// Set "writeResults" true to create a new list of results +// (only do this if you are sure that the current Version of +// ImageJ has no bugs) + +// 'resultsFile' is the name of the file with the commands & results +//(it must be in the "macros" folder) +//The lines in that file contain (semicolon-delimited): +// command-string; options-string; flags; results +// The strings should not be enclosed in quotes. +// The results are comma-delimited; mean, min, max for each type of +// selection and data file type +// Flags are bitwise OR of bits: +// bit 0 (1) - do on 8-bit image +// bit 1 (2) - do on 16-bit image +// bit 2 (4) - do on 32-bit image +// bit 3 (8) - do on RGB image +// bit 4 (16) - do on binary image +// bit 5 (32) - do on stacks of the types defined previously +// bit 6 (64) - command creates a separate output image (no stack) that should be measured +// bit 7 (128) - disable anisotropy tests (if filtering is not isotropic, but works +// differently when rotated/flipped, e.g. "Shadow" filters). +// bit 8 (256) - disable Undo test +// +// Lines starting with a character less than '0' (e.g., '#') are comments. + +// 'nStackTests' is the number of stack tests to do: +// Stack tests: 0 = none; 2 = try processing single slice&full stack; 6 = do all tests +// Stack test passes are: +// 0 = single image +// odd = stack, process current slice only +// even = stack, process all +// startSlice = 1 in pass 1&2; goes up to slice 3 in pass 5&6 + +// 'nIsotropyTests' is the number of isotropy tests to do (mainly useful when +// developing new filters): +// 1 - no additional tests, 2 adds 90-degree rotated, 3 adds 180-degree rotated, +// 4 adds flipped (i.e., does all isotropy tests) + +// Initialize + +saveSettings(); +setBackgroundColor(0, 0, 0); +setBatchMode(true); +run("Conversions...", "scale weighted"); +run("Set Measurements...", " mean min redirect=None decimal=9"); +run("Options...", "iterations=1 count=1"); //process>binary>options +oldThreads = parseInt(call("ij.Prefs.getThreads")); +oldOptions = parseInt(call("ij.Prefs.get", "prefs.options", "1073762560")); +optionKeepUndoBuffers = (oldOptions&(1<<30))!=0; +optionNoClickToGC = (oldOptions&(1<<28))!=0; + +imageTypes = 5; //8-bit, 16-bit, 32-bit, RGB, binary +var types = newArray("8bit","16bit","32bit","RGB","binary"); +var selections = newArray("all", "rect", "oval"); +var stackTests = newArray("single image", "slice 1 only", "stack currentslice 1", "slice 2 only", "stack currentslice 2", "slice 3 only", "stack currentslice 3") +var isotropyTests = newArray("", " isotropy 90degR", " isotropy 180deg", " isotropy flipV"); // see also rotateRoi +rotations = newArray("Rotate 90 Degrees Right", "Rotate 90 Degrees Right", "Flip Horizontally"); +if (nIsotropyTests < 1) nIsotropyTests = 1; +if (nIsotropyTests > 4) nIsotropyTests = 4; + +cornerPixel = newArray(imageTypes); //the pixel at (0,0) in the unrotated image (to check equal handling of all edges) +measure = newArray(43, 34, 20, 20); //coordinates of measure Rectangle +rect = newArray(44, 31, 25, 22); //coordinates of rect roi for processing +oval = newArray(45, 33, 24, 12); //coordinates of oval roi for processing +measureR = newArray(4); //rotated versions for isotropy test +rectR = newArray(4); +ovalR = newArray(4); + +var success = true; //remember errors for final status display + +//create test images of 5 types + +blobsFile = getDirectory("startup")+"samples"+File.separator+"blobs.gif"; +blobsFile = "/atHome/ImageJ Developer/testimages/blobs.gif"; + +if (File.exists(blobsFile)) + open(blobsFile); +else + run("Blobs (25K)"); +var width; +width = getWidth(); +var height; +height = getHeight(); +setPixel(49, 44, 254); +setPixel(46,33,1); +imageID = newArray(imageTypes*nIsotropyTests); //0...3 original of types, 4...7 rotated 90deg (isotropy test), etc. +imageID[0] = getImageID(); +rename("Test8"); +run("Duplicate...", "title=Test16"); +run("16-bit"); +run("Multiply...", "value=2.333"); +imageID[1] = getImageID(); +run("Duplicate...", "title=Test32"); +run("32-bit"); +run("Multiply...", "value=0.0333"); +run("Add...", "value=-0.011"); +imageID[2] = getImageID(); +selectImage(imageID[0]); +run("Duplicate...", "title=R"); +run("Multiply...", "value=0.6"); +selectImage(imageID[0]); +run("Duplicate...", "title=G"); +run("Multiply...", "value=0.9"); +selectImage(imageID[0]); +run("Duplicate...", "title=B"); +run("Multiply...", "value=1.1"); +run("RGB Merge...", "red=R green=G blue=B"); +rename("TestRGB"); +imageID[3] = getImageID(); +selectImage(imageID[0]); +run("Duplicate...", "title=TestBinary"); +setThreshold(139, 255); +run("Convert to Mask"); +resetThreshold(); +imageID[4] = getImageID(); +//create flipped and rotated versions for isotropy tests +for (rot = 1; rot < nIsotropyTests; rot++) { + rotation = rotations[rot-1]; + for (type = 0; type < imageTypes; type++) { + selectImage(imageID[(rot-1)*imageTypes+type]); //create new image from previous rotation of same image type + titleS="title=[type"+type+"_isotropy"+rot+"]"; + run("Duplicate...", titleS); + run(rotation); + imageID[rot*imageTypes+type] = getImageID(); + } +} +if (maxThreads<1) { + minThreads = oldThreads; + maxThreads = oldThreads; +} else + minThreads = 1; +if (nRuns<1) + nRuns = 1; +if (writeResults) { + nRuns = 1; + maxThreads = minThreads; + nIsotropyTests = 1; +} +//read tasklist + +macroDir = getDirectory("macros"); +if (File.exists(macroDir+resultsFile)) + tasklist = File.openAsString(macroDir+resultsFile); +else { + print("Tasklist not found at"); + print(" "+macroDir+resultsFile); + print("A tasklist is available at"); + print(" http://rsb.info.nih.gov/ij/macros/FilterTesterTasklist.txt"); + exit(); +} +tasks = split(tasklist, "\n\r"); +startTime = getTime; +progress = 0; +progressAll = lengthOf(tasks); + +if (writeResults) { + if (File.exists(macroDir+resultsFile+".tmp")) + if (!File.delete(macroDir+resultsFile+".tmp")) exit("error - cannot delete old "+resultsFile+".tmp"); + outFile = File.open(macroDir+resultsFile+".tmp"); +} + +for (iRun=0; iRun1) print("FilterTester Run "+(iRun+1)+"/"+nRuns); + //loop over commands + for (iTask = 0; iTask < lengthOf(tasks); iTask++) { + if(charCodeAt(tasks[iTask], 0)<48) { // comment line? + if (writeResults) print (outFile, tasks[iTask]); // keep comment lines + progressAll--; // comment lines don't count as progress + } else { // non-comment line + taskParts = split(tasks[iTask],";"); + if (writeResults) + outLine = taskParts[0]+";"+taskParts[1]+";"+taskParts[2]+";"; + else { + results = split(taskParts[3],","); + if (lengthOf(results)<3) { + cleanup(imageID); + exit("Error: "+taskParts[0]+" - no results in\n"+resultsFile); + } + } + taskParts[1] = replace(taskParts[1],"\\\\n", "\n");// replace escaped linefeeds by real ones + flags = parseInt(taskParts[2]); + //print(taskParts[0]+": flags="+flags); + doStacks = bitSet(flags, 5); + separateOutput = bitSet(flags, 6); + anisotropic = bitSet(flags, 7); + noUndo = bitSet(flags, 8); + if (writeResults) + lastStackTest = 0; + else if (doStacks) + lastStackTest = nStackTests; + else + lastStackTest = 1; //try on single image and slice one of a stack only + for (nThreads = minThreads; nThreads <= maxThreads; nThreads++) { + run("Memory & Threads...", "parallel=&nThreads run"); + for (stack = 0; stack <= lastStackTest; stack++) { + startSlice = floor((stack-1)/2)+1; + allSlices = (stack > 0) && ((stack-2*floor(stack/2)) == 0); + if (allSlices) + allSlicesS = " stack"; + else + allSlicesS = ""; + //print(stackTests[stack]+" allSlices="+toString(allSlices)+" startSlice="+toString(startSlice)); + if (stack>0 || writeResults || anisotropic) + nRot = 1; + else + nRot = nIsotropyTests; + for (rot = 0; rot < nRot; rot++) { + testNum = 0; + for (type = 0; type < imageTypes; type++) if (bitSet(flags,type)) { + for (selection = 0; selection < 3; selection++) { + //print(" type="+type+" selection="+selection+", isotropy test="+rot); + rotateRoi(rot, measure, measureR); + rotateRoi(rot, rect, rectR); + rotateRoi(rot, oval, ovalR); + selectImage(imageID[rot*imageTypes+type]); + run("Duplicate...", "title=test"); + makeRectangle(measureR[0],measureR[1],measureR[2],measureR[3]); + getStatistics(area, meanIn, minIn, maxIn, std, histogram); + run("Select None"); + if (stack >0) { // create a stack + //make all slices equal if only one should be processed to detect unwanted processing. + //make other slices blank when processing all to detect slice confusion + if (allSlices) run("Cut"); + else run("Copy"); + run("Add Slice"); + if (!allSlices) run("Paste"); + run("Add Slice"); + if (!allSlices) run("Paste"); + setSlice(startSlice); + if (allSlices) run("Paste"); + } + if (allSlices) setSlice(4-startSlice); //try processing a slice different from the current one + if (selection == 1) + makeRectangle(rectR[0],rectR[1],rectR[2],rectR[3]); + else if (selection == 2) + makeOval(ovalR[0],ovalR[1],ovalR[2],ovalR[3]); + inputImage = getImageID(); +//print(taskParts[0], taskParts[1]+allSlicesS, getTitle, is("binary")); +//if (!is("binary")) setBatchMode("exit and display"); + run(taskParts[0], taskParts[1]+allSlicesS); // THE OPERATION + if (verbose) + print("t="+(getTime-startTime)+"\nrun("+taskParts[0]+", \""+taskParts[1]+allSlicesS+"\"); "+getWidth+"x"+getHeight+"x"+nSlices+"x"+bitDepth+" threads="+nThreads); + makeRectangle(measureR[0],measureR[1],measureR[2],measureR[3]); + if (allSlices) setSlice(startSlice); + getStatistics(area, mean, min, max, std, histogram); + if (writeResults) { + outLine = outLine+toString(mean)+","+toString(min)+","+toString(max)+","; + if (abs(mean-meanIn)<0.000001 && abs(min-minIn)<0.000001 && abs(max-maxIn)<0.000001) + failNoChange(taskParts[0],taskParts[1],type,selection, nThreads); + } else { // if not writeResults + meanR = parseFloat(results[3*testNum]); //compare values with numbers in TaskList file + minR = parseFloat(results[3*testNum+1]); + maxR = parseFloat(results[3*testNum+2]); + //print(taskParts[0]+" mean="+toString(mean)+" expected="+toString(meanR)); + if (abs(mean-meanR)>0.0001) fail(taskParts[0], taskParts[1], type, rot, selection, nThreads, stack, mean,meanR,"mean"); + if (abs(min-minR)>0.0001) fail(taskParts[0], taskParts[1], type, rot, selection, nThreads, stack, min,minR,"min"); + if (abs(max-maxR)>0.0001) fail(taskParts[0], taskParts[1], type, rot, selection, nThreads, stack, max,maxR,"max"); + if (stack==0 && selection==0) { + corner = getCorner(rot); + if (rot == 0) cornerPixel[type] = corner; + else if (abs(corner-cornerPixel[type]) > 0.0001) + fail(taskParts[0], taskParts[1], type, rot, selection, nThreads, stack, corner, cornerPixel[type], "cornerPixel"); + } + if (stack >0 && !separateOutput) { + for (slice = 1; slice<=3; slice++) if (slice!=startSlice) { //check: other slice overwritten? + setSlice(slice); + getStatistics(area, mean, min, max, std, histogram); + if (abs(mean-meanR)<0.000001 && abs(min-minR)<0.000001 && abs(max-maxR)<0.000001) + failOver(taskParts[0], taskParts[1], type, selection, nThreads, stack, slice); + } + } //if stack>0 + if (stack == 0 && !separateOutput &&! noUndo) { //check: does undo work? + run("Undo"); + getStatistics(area, mean, min, max, std, histogram); + if (abs(mean-meanIn)>0.000001 || abs(min-minIn)>0.000001 || abs(max-maxIn)>0.000001) + failUndo(taskParts[0], taskParts[1], type, selection, nThreads); + } + } // if writeResults else + close(); + if (separateOutput) { + selectImage(inputImage); + close(); + } + testNum ++; + } // for selection + } // for type + } // for rot (isotropy test) + if (writeResults) + print (outFile, outLine); + } // for stack + } // for nThreads + progress++; + showProgress(progress, progressAll); + } // if not comment + } // for iTask +} +cleanup(imageID); +restoreSettings(); +restoreMemOptionS = ""; +if (optionKeepUndoBuffers) restoreMemOptionS = restoreMemOptionS + " keep"; +if (!optionNoClickToGC) restoreMemOptionS = restoreMemOptionS + " run"; +run("Memory & Threads...", "parallel="+oldThreads+restoreMemOptionS); + +setBatchMode("exit and display"); +if (writeResults) { + File.close(outFile); + if (!File.delete(macroDir+resultsFile)) exit("cannot delete old "+resultsFile); //delete old results file and replace by new + dummy = File.rename(macroDir+resultsFile+".tmp", macroDir+resultsFile); + showStatus("PlugInFilterTester writing done"); +} else { + if (success) doneS = " successful"; + else doneS = ": errors"; + beep; + showStatus("FilterTester"+doneS+" ("+d2s((getTime-startTime)/1000,2)+" seconds)"); + wait(2000); +} + + +function fail(task, text, type, rot, selection, threads, stack, val, valR, what) { + print("FAIL: "+task+": "+text+" type="+types[type]+isotropyTests[rot]+" select="+selections[selection]+" nThreads="+threads+", "+stackTests[stack]+": "+what+"="+toString(val)+" expected="+toString(valR)); + failCommonTasks(); +} + +function failOver(task, text, type, selection, threads, stack, slice) { + print("FAIL: "+task+": "+text+" type="+types[type]+" select="+selections[selection]+" nThreads="+threads+", "+stackTests[stack]+": slice "+slice+" overwritten"); + failCommonTasks(); +} + +function failUndo(task, text, type, selection, threads) { + print("FAIL: Undo of "+task+": "+text+" type="+types[type]+" select="+selections[selection]+" nThreads="+threads); + failCommonTasks(); +} + +function failNoChange(task, text, type, selection, threads) { + print("WARNING: "+task+": "+text+" type="+types[type]+" select="+selections[selection]+" nThreads="+threads+" changes nothing, stack tests will fail ('overwritten')"); + failCommonTasks(); +} + +function failCommonTasks() { + success = false; + if (stopOnFail) { + setBatchMode("exit and display"); + restoreSettings(); + exit("FilterTester - Stopped on Fail\nNOTE:\nOptions>Memory&Threads may be changed"); + } +} + +function cleanup(imageID) { + for (i = 0; i < lengthOf(imageID); i++) { + selectImage(imageID[i]); + close(); + } +} + +function bitSet(number,bitNum) { + mask = 1; + for (i=0; i". + +// Different font sizes + showMessage("1/5", "" + +"Big Font
" + +"Small Font"); + +// Multiple colors + showMessage("2/5", "" + +"" + +"C" + +"o" + +"l" + +"o" + +"r"); + +// Ordered lists and headers + showMessage("3/5", "" + +"

ACGT Bases

" + +"
    " + +"
  1. Adenine" + +"
  2. Cytosine" + +"
  3. Guanine" + +"
  4. Thymidine" + +"
"); + +// Unordered lists, headers, and text modifiers + showMessage("4/5", "" + +"

ImageJ

" + +"
    " + +"
  • Runs everywhere" + +"
  • Fastest pure Java image processing program" + +"
  • Easily extended using plugin and macros" + +"
"); + +// Headers, font color, and italics + showMessage("5/5", "" + +"

Fin

"); diff --git a/MT2-project-ImageProcessing/macros/KeyboardShortcuts.ijm b/MT2-project-ImageProcessing/macros/KeyboardShortcuts.ijm new file mode 100644 index 0000000..95f4e13 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/KeyboardShortcuts.ijm @@ -0,0 +1,90 @@ +// These macros demonstrate how to use keyboard shortcuts. +// There are three types of keyboard shortcuts: characters keys, functions keys and +// and numeric pad keys. This macro file contains examples of each of these. + +// Character key shortcuts ('a'..'z', 'A'..'z', '0'..'9') +// Character key shortcuts override ImageJ and plugin +// shortcuts. In case of duplicates, press the key to use +// the macro shortcut and press control plus the key to +// use the ImageJ or plugin shortcut. + + macro "Lower case a [a]" { + print(""); + print("Lower case a"); + print("This macro overrides the 'a' shortcut for the Select All"); + print("command. To use Edit>Selection>Select All, press ctrl-a."); + } + + macro "Upper case A [A]" { + print(""); + print("Upper case A"); + print("This macro overrides the 'A' shortcut for the Select None"); + print("command. To use Edit>Selection>Select None, press ctrl-shift-a."); + } + + macro "Lower case o [o]" { + print(""); + print("Lower case o"); + print("This macro overrides the 'o' shortcut for the Open"); + print("command. To use File>Open, press ctrl-o."); + } + + macro "Lower case q [q]" { + print(""); + print("Lower case q"); + } + + macro "One [1]" { + print(""); + print("One"); + print("This macro overrides the '1' shortcut for"); + print("Analyze>Gels>Select First lane."); + print("To use this command, press ctrl+1."); + } + + macro "Nine [9]" { + print(""); + print("Nine"); + } + + macro "Rename... [r]" { + run("Rename..."); + print(""); + print("Rename..."); + print("This example show how to assign a shortcut to"); + print("an ImageJ command. Use cntrl-r to run File>Revert,"); + print("which uses the same shortcut."); + } + + + +// Function key shortcuts +// Plugins also use function key shortcuts +// so conflicts are possible. + + macro "-" {} // separator + macro "F1 [f1]" {print("F1");} + macro "F2 [f2]" {print("F2");} + + +// Numeric keypad shortcuts +// Keypad shotcuts require ImageJ 1.33g or later. +// They are not available in Plugins so conflicts are +// not possible. On PCs, keypad shortcuts may not +// work unless the 'Num Lock' light is on. + + macro "-" {} // separator + macro "Numeric Pad 0 [n0]" { npad("0"); } + macro "Numeric Pad 1 [n1]" { npad("1"); } + macro "Numeric Pad 9 [n9]" { npad("9"); } + macro "Numeric Pad 9 [n/]" { npad("/"); } + macro "Numeric Pad 9 [n*]" { npad("*"); } + macro "Numeric Pad 9 [n-]" { npad("-"); } + macro "Numeric Pad 9 [n+]" { npad("+"); } + macro "Numeric Pad 9 [n.]" { npad("."); } + + function npad(key) { + print(""); + print("Keypad '"+key); + } + diff --git a/MT2-project-ImageProcessing/macros/LogWindowTricks.ijm b/MT2-project-ImageProcessing/macros/LogWindowTricks.ijm new file mode 100644 index 0000000..39d6255 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/LogWindowTricks.ijm @@ -0,0 +1,52 @@ +// This macro demonstrates how to clear the Log window +// and update its contents by sending it commands. +// +// There are three commands: +// +// "\\Clear" - erase the Log window +// "\\Update:" - replace the current line with +// "\\Update:" - replace the nth line with , where n<26 + + requires("1.37j"); + print("\\Clear"); + print("This macro demonstrates how a"); + print("macro can clear the Log window "); + print("and update its contents."); + print(""); + print("The Log window will be"); + print(" cleared in five seconds."); + + wait(5000); + print("\\Clear"); + wait(1000); + + print("Now, for 10 seconds, we will turn"); + print("the last line into a digital clock."); + print(""); + getDateAndTime(year, month, week, day, hour, min, sec, msec); + print("Date: "+year+"/"+month+"/"+day); + print("Time:"); + start = getTime; + while (getTime-start<=10000) { + getDateAndTime(year, month, week, day, hour, min, sec, msec); + print("\\Update:"+"Time: "+hour+":"+min+":"+sec+":"+floor(msec/100)); + wait(100); + } + + print("\\Clear"); + print("Finally, for 10 seconds, we repeatedly"); + print("update nine lines in the Log window."); + wait(4000); + print("\\Clear"); + bars = newArray("*", "**", "***", "****", "*****", "******", "*******", "********", "*********"); + n = bars.length; + index = 0; + print("\\Clear"); + start = getTime; + while (getTime-start<=10000) { + for (i=0; i1) + IJ.run(imp3, "Delete Slice", ""); + if (imp3.getStackSize()!=1) print(msg+3); + if (imp3.getStack().getSliceLabel(1)!=label+1) print(msg+4);; + } + imp = IJ.createImage("B","16-bit",size,size,1); + stack = imp.getStack(); + stack.setSliceLabel(label,1); + stack.addSlice(new FloatProcessor(size,size)); + ip = imp.getProcessor().duplicate(); + ip.add(12345); + imp.setProcessor(ip); + if (imp.getStatistics().mean!=12345) print(msg+5); + imp2 = imp.duplicate(); + imp3 = imp2.duplicate(); + stack = imp3.getStack(); + if (stack.getSliceLabel(1)!=label) print(msg+6); + stack = new ImageStack(size,size); + stack.addSlice(label,new ByteProcessor(size,size)); + if (stack.getSliceLabel(1)!=label) print(msg+7); + imp = new ImagePlus("",stack); + if (imp.getStack().getSliceLabel(1)!=label) print(msg+8); + imp = IJ.createImage("C","32-bit",size,size,1); + imp.setStack(stack); + if (imp.getStack().getSliceLabel(1)!=label) print(msg+9); + } + + function thresholdTests() { + msg = "FAIL: ThresholdTests #"; + img = IJ.createImage("Untitled", "8-bit ramp", 256, 256, 1); + IJ.setRawThreshold(img, 100, 200, null); + Prefs.blackBackground = true; + IJ.run(img, "Convert to Mask", ""); + stats = img.getStatistics(); + if (stats.histogram[255]!=25856) print(msg+1); + img = IJ.createImage("Untitled", "16-bit ramp", 256, 256, 1); + IJ.setRawThreshold(img, 16000, 45000, null); + IJ.run(img, "Convert to Mask", ""); + stats = img.getStatistics(); + if (stats.histogram[255]!=28928) print(msg+2); + img = IJ.createImage("Untitled", "32-bit ramp", 256, 256, 1); + IJ.setRawThreshold(img, 0.25, 0.75, null); + IJ.run(img, "Convert to Mask", ""); + stats = img.getStatistics(); + if (stats.histogram[255]!=33024) print(msg+3); + methods = AutoThresholder.getMethods(); + + // 'dark' + values = [277,357,4359,1070,277,713,2259,357,357,7728,1506,1030,317,2259,7094,674,2893]; + img = IJ.openImage("http://wsr.imagej.net/images/m51.zip"); + ip = img.getProcessor(); + for (i=0; itolerance || (!Double.isNaN(value1)&&Double.isNaN(value2)) ) + print(msg+test+" "+row+" "+column+" "+value1+" "+value2); + } + +function maskTests() { + msg = "FAIL: Mask Tests #"; + img = IJ.openImage("http://wsr.imagej.net/images/blobs.gif"); + IJ.setAutoThreshold(img, "Default"); + mask = img.createThresholdMask(); + if (mask.getMinThreshold()!=255) print(msg+1); + if (mask.getStats().histogram[255]!=22243) print(msg+2); + maskImg = new ImagePlus("mask",mask); + IJ.run(maskImg, "Create Selection", ""); + if (maskImg.getStatistics().area!=22243) print(msg+3); + img.setRoi(new OvalRoi(66,52,134,146)); + mask = img.createRoiMask(); + if (mask.getMinThreshold()!=255) print(msg+4); + if (mask.getStats().histogram[255]!=15368) print(msg+5); + maskImg = new ImagePlus("mask",mask); + IJ.run(maskImg, "Create Selection", ""); + if (maskImg.getStatistics().area!=15368) print(msg+6); + img.deleteRoi(); + IJ.setAutoThreshold(img, "MinError"); + IJ.run(img, "Analyze Particles...", " show=Overlay"); + mask = img.createRoiMask(); + if (mask.getStats().histogram[255]!=27149) print(msg+7); + IJ.run(img, "Set Scale...", "distance=1 known=10 unit=mm"); + IJ.run(img, "Create Mask", ""); + maskImg = WindowManager.getCurrentImage(); + if (maskImg.getCalibration().pixelWidth!=10) print(msg+8) + mask = maskImg.getProcessor(); + if (mask.getMinThreshold()!=255) print(msg+9); + if (mask.getStats().histogram[255]!=27149) print(msg+10); + maskImg.close(); + img.setOverlay(null); + IJ.setAutoThreshold(img, "Shanbhag"); + IJ.run(img, "Create Mask", ""); + maskImg = WindowManager.getCurrentImage(); + if (maskImg.getCalibration().pixelWidth!=10) print(msg+11) + mask = maskImg.getProcessor(); + if (mask.getMinThreshold()!=255) print(msg+12); + if (mask.getStats().histogram[255]!=16546) print(msg+13); + maskImg.close(); + //new ImagePlus("mask",mask).show(); +} + diff --git a/MT2-project-ImageProcessing/macros/RegressionTests.txt b/MT2-project-ImageProcessing/macros/RegressionTests.txt new file mode 100644 index 0000000..d14402a --- /dev/null +++ b/MT2-project-ImageProcessing/macros/RegressionTests.txt @@ -0,0 +1,739 @@ +// Macro language regression tests + + n = 1; // Iterations + t0 = getTime; + for (i=1; i<=n; i++) { + runMacro("RegressionTests.js"); // run JavaScript regression tests + if (i==1) + runMacro("FilterTester"); // run Michael Schmid's filter tests + test = "null"; + roiManagerTest(true); roiManagerTest(false); + measure(); + binary(); + logic("Logic"); + math("Math"); + functionCalls("FunctionCall"); + images("Image"); + setBatchMode(true); images("BatchImage"); setBatchMode(false); + benchmarks("Benchmark"); + analyzeParticles(); + duplication(false); duplication(true); + imageActivation(false); imageActivation(true); + tableTests(false); tableTests(true); + metadata(false); metadata(true); + particleAnalyzer(); + } + beep; + time = d2s((getTime-t0)/1000,2); + showStatus("Regression tests done ("+time+" seconds)"); + wait(4000); + exit(); + +// Logic tests +function logic(thisTest) { + test = thisTest; + if (1>2) fail(1); + if (2>1) ; else fail(2); + if (1+2*3!=7||2/3+1!=1+(2/3)) fail(3); + s = "ImageJ has a very nice macro language"; + if (s=="ImageJ has a very nice macro language2") fail(4); + if ("ImageJ has a very nice macro language "==s) fail(5); + a = newArray(1, 2, 3); + if (a[0]+a[0]!=a[1]) fail(6); + s = newArray('one', 'two'); + if (s[0]+s[1] != 'onetwo') fail(7); + if (s[0]>=s[1]) fail(8); +} + +// Math tests +function math(thisTest) { + test = thisTest; + n = 10; + if (n++!=10) fail(1); + if (++n!=12) fail(2); + if (n--!=12) fail(3); + if (--n!=10) fail(4); + a=newArray(0,1,2,3,4,5,6); + for (i=0; i1) fail(2); + if (abs(circularity-0.9994)>0.0001) fail(3); // 0.9997 before 1.52m11 + if (abs(minor-219.0134)>0.0001) fail(4); + run("Duplicate...", "title=temp"); + run("Restore Selection"); + setAutoThreshold(); + run("Convert to Mask"); + run("Restore Selection"); + getHistogram(values, counts, 256); + if (counts[255]!=2115) fail(5); + close; + selectImage(id); + close; + selectWindow("Results"); + run("Close"); + } + + function binary() { + test = "Binary"; + binary2(); + setBatchMode(true); + test = "Binary (batch)"; + binary2(); + setBatchMode(false); + } + + function binary2() { + run("Options...", "iterations=1 count=1 "); + run("Blobs (25K)"); + run("Convert to Mask"); + getHistogram(0, counts, 256); + if (counts[255]!= 22243) fail(1); + run("Erode"); + getHistogram(0, counts, 256); + if (counts[255]!= 17256) fail(2); + run("Undo"); + run("Close-"); + getHistogram(0, counts, 256); + if (counts[255]!= 21900) fail(3); + run("Undo"); + run("Open"); + getHistogram(0, counts, 256); + if (counts[255]!= 22148) fail(4); + run("Undo"); + run("Skeletonize"); + getHistogram(0, counts, 256); + if (counts[255]!= 686) fail(5); + run("Undo"); + run("Options...", "iterations=4 count=4"); + run("Open"); + getHistogram(0, counts, 256); + if (counts[255]!= 19196) fail(6); + run("Options...", "iterations=1 count=1 "); + close; + } + + +function roiManagerTest(batchMode) { + if (batchMode) + test = "Roi Manager (batch mode)"; + else + test = "Roi Manager"; + setBatchMode(batchMode); + newImage("Untitled", "8-bit", 2000, 2000, 1); + width = getWidth(); + height = getHeight(); + if (roiManager("count")>0) roiManager("reset"); + n = 250; + x = newArray(n); + y = newArray(n); + w = newArray(n); + h = newArray(n); + for (i=0; i0; i--) { + selectImage(i); + if (getTitle!="Stack") + close; + } + if (nImages!=1 || nSlices!=7) fail2(5,""); + id3 = getImageID; + run("Stack to Images"); + n3 = nImages; + if (n3!=7) fail2(6,""); + for (i=1; i<=n3; i++) { + id3 -= 1; + selectImage(id3); + if (getImageID!=id3) fail2(7,""); + } + + run("Close All"); + run("Blobs (25K)"); + id = getImageID; + run("Duplicate...", " "); + selectImage(id); + run("FFT"); + close; + if (getImageID!=id) fail2(8, ""+getImageID+" "+id); + run("Close All"); + + newImage("dummy", "32-bit ramp", 500, 500, 1); + id1 = getImageID(); + title = "Stack"; + newImage(title, "32-bit ramp", 500, 500, 3); + id2 = getImageID(); + run("Stack to Images"); + title2 = getTitle; + if (title2!=title+"-0003") fail2(9, title2); + + run("Close All"); + run("Blobs (25K)"); + newImage("Untitled", "8-bit random", 2000, 2000, 1); + selectWindow("blobs.gif"); + run("Duplicate...", "title=copyForMeasuring"); + run("Median...", "radius=15"); + getStatistics(area, mean, min, max, std); + if (abs(std-43.5047)>0.0001) fail2(10,""); + close(); + if (getTitle!="blobs.gif") fail2(11,getTitle+" blobs.gif"); + } + +function tableTests(batchMode) { + saveSettings; + if (batchMode) + test = "Tables (batch)"; + else + test = "Tables"; + setBatchMode(batchMode); + setOption("ExpandableArrays", true); + tables = newArray; + tableCount = 0; + + Table.reset("Results"); + if ("Results"!=Table.title) fail(1); + for (row=0, n=0; n<=2*PI; row++, n+=0.1) { + Table.set("n", row, n); + Table.set("sin(n)", row, sin(n)); + Table.set("cos(n)", row, cos(n)); + } + Table.update; + if ("Results"!=Table.title) fail(2); + tables[tableCount++] = Table.title; + + // Duplicate + table1 = "Sine/Cosine Table"; + Table.create(table1); + if (table1!=Table.title) fail(3); + for (n=0,row=0; n<=2*PI; n+=0.1,row++) { + Table.set("n", row, n); + Table.set("sin(n)", row, sin(n)); + Table.set("cos(n)", row, cos(n)); + } + Table.update; + if (Table.size()!=63) failt(4); + tables[tableCount++] = table1; + + table2 = table1 +" Copy"; + Table.create(table2); + headings = split(Table.headings(table1)); + for (row=0; row]"); + } + + macro "Update [7]" { + roiManager("update"); + } + + macro "Open All" { + dir = getDirectory("Choose a Directory "); + list = getFileList(dir); + for (i=0; iCongratulations!

"+ + "Level: "+level+"
"+ + "Score: "+score+"" + ); + close; + } + + macro"Up [n8]" {d="U";} + macro"Down [n2]" {d="D";} + macro"Down [n5]" {d="D";} + macro"Right [n6]" {d="R";} + macro"Left [n4]" {d="L";} + + function initPlayBoard() { + reuse = nImages>0; + if (reuse) reuse = startsWith(getTitle, "Level "); + if (reuse) + rename("Level "+level+" Score "+score); + else { + if (getVersion>="1.37e") + call("ij.gui.ImageWindow.centerNextImage"); + newImage("Level "+level,"8-bit",s,s,1); + run("View 100%"); run("In"); run("In"); + } + x=s/2;y=x;d=""; + r=newArray(0, 0, 255, 255, 0, 220); + g=newArray(0, 200, 0, 255, 255, 230); + b=newArray(0, 0, 0, 255, 255, 255); + setLut(r,g,b); // a custom LUT with just 5 colors. + setColor(3); fillRect(0,0,s,s); // the white image bckgd + setColor(0); drawRect(0,0,s,s); // the black image frame + setColor(5); // the backgroung text color + setFont("Monospaced",32,"bold"); setJustification("center"); + drawString("ImageJ",s/2,s/3); + drawString("Snake",s/2,2*s/3); + drawString("Game",s/2,s); + addItem(20,1); // 20 green color food + addItem(20,2); // 20 red color poison + addItem( 1,4); // 1 cyan color door to next level + setPixel(x,y,0); // sets start position to center + } + + function addItem(f,type) { + setColor(type); + for (i=0;iGame Over

"+ + "Level: "+level+"
"+ + "Score: "+score+"" + ); + close; + exit; + } + + function youAteSomethingGood() { + for (i=x-1;i<=x+1;i++) { + for (j=y-1;j<=y+1;j++) { + if (getPixel(i,j)==1) + setPixel(i,j,3); + } + } + score++; + rename("Level "+level+" Score "+score); + beep(); + } diff --git a/MT2-project-ImageProcessing/macros/StartupMacros.txt b/MT2-project-ImageProcessing/macros/StartupMacros.txt new file mode 100644 index 0000000..6bf0012 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/StartupMacros.txt @@ -0,0 +1,47 @@ +// "StartupMacros" +// The macros and tools in this file ("StartupMacros.txt") are +// automatically installed in the Plugins>Macros submenu and +// in the toolbar when ImageJ starts up. + +// The "AutoRun" macro has been replaced by the Edit>Options>Startup command. + + macro "Developer Menu Built-in Tool" {} + macro "Brush Built-in Tool" {} + macro "Flood Filler Built-in Tool" {} + macro "Arrow Built-in Tool" {} + + var pmCmds = newMenu("Popup Menu", + newArray("Help...", "Rename...", "Duplicate...", "Original Scale", + "Paste Control...", "-", "Record...", "Capture Screen ", "Monitor Memory...", + "List Commands...", "Control Panel...", "Startup Macros...", "Search...")); + + macro "Popup Menu" { + cmd = getArgument(); + if (cmd=="Help...") + showMessage("About Popup Menu", + "To customize this menu, edit the line that starts with\n\"var pmCmds\" in ImageJ/macros/StartupMacros.txt."); + else + run(cmd); + } + + macro "-" {} //menu divider + + macro "About Startup Macros..." { + path = getDirectory("macros")+"About Startup Macros"; + if (!File.exists(path)) + exit("\"About Startup Macros\" not found in ImageJ/macros/."); + open(path); + } + + // This example macro demonstrates how to create a + // custom command with a keyboard shortcut. + //macro "Save As JPEG... [j]" { + // quality = call("ij.plugin.JpegWriter.getQuality"); + // quality = getNumber("JPEG quality (0-100):", quality); + // run("Input/Output...", "jpeg="+quality); + // saveAs("Jpeg"); + //} + + + + diff --git a/MT2-project-ImageProcessing/macros/macros.iml b/MT2-project-ImageProcessing/macros/macros.iml new file mode 100644 index 0000000..b18257b --- /dev/null +++ b/MT2-project-ImageProcessing/macros/macros.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/MT2-project-ImageProcessing/macros/toolsets/Arrow Labelling Tools.ijm b/MT2-project-ImageProcessing/macros/toolsets/Arrow Labelling Tools.ijm new file mode 100644 index 0000000..a34f841 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/toolsets/Arrow Labelling Tools.ijm @@ -0,0 +1,989 @@ +/////////////////////////////////////////////////////////////////////// +// Image, Stack and Timelapse Arrow Labelling +// +// avaible in the IJ macros toolsets repertory at +// http://rsb.info.nih.gov/ij/macros/toolsets/Image, Stack and Timelapse Arrow Labelling.txt +/////////////////////////////////////////////////////////////////////// +// Author: Gilles Carpentier, Faculte des Sciences et +// Technologies, Universite Paris 12 Val de Marne, France + +// More information is available at +// http://image.bio.methods.free.fr/arrows.html + +// First version 24 04 2007 +// Requires the ImageJ 1.38p +// Based on the following macros: +// macro ArrowMakerTool, from the author and available on the ImageJ website at: +// http://rsb.info.nih.gov/ij/macros/tools/ArrowMakerTool.txt +// Macro BigCursorTool writen by Wayne Rasband, and avaible on the ImageJ website at: +// http://rsb.info.nih.gov/ij/macros/tools/BigCursorTool.txt +// macro change Color tool, from the author and available on the ImageJ website at: +// http://rsb.info.nih.gov/ij/macros/tools/ChangeColorTool.txt +// macro SelectionColorMenuTool, from the author and available on the ImageJ website at: +// http://rsbweb.nih.gov/ij/macros/tools/SelectionColorMenuTool.txt + +var x, y, quadrantx,xlocation,ylocation,xinit,yinit,xprime,yprime,arrowline ; //spacer, +var arrowlenght=20, arrowwidth=6, arrowconcav=21, taillenght=20,previewarrow=0,speed=15,defaultspeed=15; +var tailwidth=4, tailcolor="Cyan", tailorient="East", orientangle=0,newcolor = "Magenta", stackchoice="All the stack"; +var colorchoices=newArray("Magenta","Cyan","Yellow","Black","White","Red","Green","Blue"),rgb=newArray(3); +var fromSlice ="", toSlice="",FSlice=0,TSlice=0,curentSlice=0; +var lastx=-1,lasty=-1,h=-1,w=-1; +var dyn=0,colorok=0,cursorok=0,drawok=0; +var px = newArray(6), py = newArray(6); +var ImaDemo=""; + +var newlook="New User Graphic Interface"; +var oldlook="Standard User Interface"; +var interface=newArray("New User Graphic Interface","Standard User Interface"); +var lookInterface = "New User Graphic Interface"; + +var palette=0,reponse=0,cancel=0,apply=0; +var targetWindow=0,tempPalette=0,paletteID=0; +var Lpalette=250,Hpalette=420,Lprev=156,Hprev=156,xpreview=0,ypreview=0; + +var distBord=15,disthaut=30,largbuton=53,hautbuton=25;// button cancel and apply +var box1x=99,box1y=(Hpalette-135); +var box2x=222,box2y=(Hpalette-135); +var box3x=160,box3y=(Hpalette-115); +var box4x=89,box4y=(Hpalette-95); +var box5x=205,box5y=(Hpalette-95); + +var Red="", Green="", Blue="", color ="", previousColor=""; + +var onlinedoclink = "http://image.bio.methods.free.fr/arrows.html"; +var urllist = "http://image.bio.methods.free.fr/ij/ijupdatetest/ListOfMacros.txt";// to check the internet access +var demoimagelink1 ="http://image.bio.methods.free.fr/ij/ijmacro/zebrafish/LSM-timelapse-demo-movie.tif.zip",demoimagename1="LSM-timelapse-demo-movie.avi",demoimagename11="LSM-timelapse-demo-movie.zip"; +var demoimagelink2 ="http://image.bio.methods.free.fr/ij/ijmacro/zebrafish/LSM-timelapse-demo-movie-Arw.tif.zip",demoimagename2="LSM-timelapse-demo-movie-Arw.avi",demoimagename22="LSM-timelapse-demo-movie-Arw.zip"; + +var xx = requires138p(); // check version at install time +function requires138p() {requires("1.38p"); return 0;} + +// menu popup summering every commands of the the toolset menu bar (click right) +var pmCmds = newMenu("Popup Menu", newArray("Abort Download","-","Set Drawing Arrow\(s\) Location","Draw Arrow\(s\) at the Current Location","-","Restore the Last Cursor Location","Display Coordinates","-","New User Graphic Interface","Standard User Interface","-","Change the Color of a Arrow","-","Undo the Last Arrow","-", "Animation Speed Setting","Animate the Stack","-","Save a Stack as an \".avi\" Movie","-","Download\/Open Demo Timelapse Movie \(6 Mo\)","Download\/Open Demo Timelapse Movie Arrowed \(6 Mo\)","-","About \"Image, Stack and Timelapse Arrow Labelling\"","-","On Line Documentation")); + +// click right menu, (ctrl click) +macro "Popup Menu" { + cmd = getArgument(); + if (cmd !="-" && cmd =="Abort Download") {abortProcess ();} + if (cmd !="-" && cmd =="Set Drawing Arrow\(s\) Location") {colorok=0;cursorok=1;drawok=0;dyn=1;setTool(10);} + if (cmd !="-" && cmd =="Draw Arrow\(s\) at the Current Location") {drawArrow();} + if (cmd !="-" && cmd =="Change the Color of a Arrow") {colorok=1;cursorok=0;drawok=0;dyn=1; setTool(10);} + if (cmd !="-" && cmd =="Restore the Last Cursor Location") {restoreLastCursor ();} + if (cmd !="-" && cmd =="Display Coordinates") {DisplayCo ();} + if (cmd !="-" && cmd == "Undo the Last Arrow") {UndoLast ();} + if (cmd !="-" && cmd =="Save a Stack as an \".avi\" Movie") {saveAsAvi ();} + + if (cmd !="-" && cmd == "New User Graphic Interface") {lookInterface = "New User Graphic Interface";} + if (cmd !="-" && cmd == "Standard User Interface") {lookInterface = "Standard User Interface";} + + if (cmd !="-" && cmd =="Animation Speed Setting") {setMovieSpeed ();} + if (cmd !="-" && cmd =="Animate the Stack") {AnimateStack();} + if (cmd !="-" && cmd == "Download\/Open Demo Timelapse Movie \(6 Mo\)") {OpenMovieLink(1,demoimagelink1,demoimagename1,demoimagename11);} + if (cmd !="-" && cmd == "Download\/Open Demo Timelapse Movie Arrowed \(6 Mo\)") {OpenMovieLink(1,demoimagelink2,demoimagename2,demoimagename22);} + + if (cmd !="-" && cmd == "About \"Image, Stack and Timelapse Arrow Labelling\"") {about1();} + if (cmd !="-" && cmd == "On Line Documentation") {doc ();} +} + +macro " Tool-1 - " { + + if (colorok==1 && dyn ==1 && getTitle !="Arrow Palette" && getTitle !="Last Arrow") {changeColor ();} + if (cursorok==1 && dyn ==1 && getTitle !="Arrow Palette" && getTitle !="Last Arrow") {Arrow (1);} + + // no ansvers -> palette + if (palette==1 && getTitle =="Arrow Palette" && dyn ==1 && cancel==0 && reponse ==0) { + if (isOpen("Arrow Palette")) {goGraphInt ();} + } + + // ansvers is cancel -> close for cancel + if (palette==0 && getTitle =="Arrow Palette" && dyn ==1 && cancel==1 && reponse ==1) { + palette=0;cursorok=1; + if (isOpen("Arrow Palette")) { + selectImage ("Arrow Palette"); + close (); + } + } + // close for bad conditions + if (palette==1 && (getTitle !="Arrow Palette" || ! isOpen("Arrow Palette")) && dyn ==1 && cancel==0 && reponse ==0) { + palette=0;cursorok=0; + if (isOpen("Arrow Palette")) { + selectImage ("Arrow Palette"); + close (); + showMessage("No user ansvers from the \"Arrow Palette\". \nThe tool has been unselected."); + } + } + // apply a user choose + if (palette==0 && getTitle =="Last Arrow" && dyn ==1 && cancel==0 && reponse ==1 && apply==1) { + if (isOpen(targetWindow)) { + selectImage(targetWindow); + DrawTheArrows (x,y); + apply=0;reponse=0;cursorok=1; + } + } +} // leave slot between ImageJ tools, and allow user interaction + +// macro Open/Save a Movie Menu Tool +var mCmds = newMenu("Movie and Stack Menu Tool",newArray("Open a Movie as Stack","Save a Stack as an \".avi\" Movie","-","Download\/Open Demo Timelapse Movie \(6 Mo\)","Download\/Open Demo Timelapse Movie Arrowed \(6 Mo\)","-","Animation Speed Setting","Animate the Stack")); +macro "Movie and Stack Menu Tool - CdccD16Dd0C999Df5CdefD3aC888D15CedeD52Db0Dc4CabdD72CfffD3bD3cD3dD3eD3fD4cD4dD4eD4fD5dD5eD5fD68D6dD6eD6fD7dD7eD7fD8dD8eD8fD9dD9eD9fDadDaeDafDbdDbfDceDcfDddDdeDeeDefDfeDffC17dD44CcdeD92CbbbD1bCffeD33D75C39eD93CeeeD61D71D81D91CcccD04D0dD12D21D22Dd1Dd2Dd4De6De8Df6Df8DfcC18eD36CcddDb3CaaaD01D03D05De7De9Df7CfeeD29DacC59dD59Dc6CeeeD1fD30D40D41D50D51D65D70D80D90Da0Da1Da2Db1Db2Dc0Dc1Dc2DdcCccdD27D85C1aeD9bCeddD25Dd8CcccD02D09D14D1eDe2De4DebDf2Df4CfffD66D98DbeDcdDdfC7adDa8CeeeD42D97CccdD18D26DecC18dD47CdddD06D0bD1aD20D23DeaCaa9D17CeeeD0fD2aD2bD2cD2eD32D88Dc3C48dDb4CbcdD82C29dDa9CddeDdbCcbbD00Df0CfffD5cD67D79D89C6adD77CeeeD57C09eD49CdddD08Dd5CabbDf9CfffD2dD2fDedDfdC59dD35CcceD43C3adD64CdeeD0aD0cD78C7bdD74CfeeDd9CcdeDa7C08eD45D48Db6CdccDd6C999D11De3Df3C59cDa3CaddD8cC19eDaaCdddD0eD24CbbbD07D10De0C4aeD9aC19eDbaCdddD28DfaC4adD87CcddD62D6cC1aeD7bCeedD60DdaC8bdDc5C08eDb9CaaaD1dDe1Df1C6bdD84CbceD58D76D99C29eD4aCcdeD34D4bCbcbDfbC5aeD6aCeeeD31C0aeD6bDbbC5adDc8CcdeD56C2afD83CddeD69C8ceDa4C08eDb7Db8C999D13De5C9ceDccC19eD38DcbCdddDd7C4aeD95C09eD46C1aeD5aD8bC7beD8aCa9aD19C49dD53CaceDc9C39dDc7CceeD9cC5beD94C09fD54C2aeD73CddcD1cCaceDbcC4beD5bC08eD37C4adD55DabC8beD7aDcaC7adDa6C29eD86C6beD39C5adD96C3aeD63C8ceDa5CdcdDd3CadeD7c"{ + cmd = getArgument(); + if (cmd!="-" && cmd == "Open a Movie as Stack") {openMovie ();} + if (cmd!="-" && cmd == "Save a Stack as an \".avi\" Movie") {saveAsAvi ();} + if (cmd !="-" && cmd == "Download\/Open Demo Timelapse Movie \(6 Mo\)") {OpenMovieLink(1,demoimagelink1,demoimagename1,demoimagename11);} + if (cmd !="-" && cmd == "Download\/Open Demo Timelapse Movie Arrowed \(6 Mo\)") {OpenMovieLink(1,demoimagelink2,demoimagename2,demoimagename22);} + if (cmd !="-" && cmd == "Animation Speed Setting") {setMovieSpeed ();} + if (cmd !="-" && cmd =="Animate the Stack") {AnimateStack();} +} + +// macro Arrow Drawing Menu Tool +var aCmds = newMenu("Arrow Drawing Menu Tool",newArray("Set Drawing Arrow\(s\) Location","Draw Arrow\(s\) at the Current Location","-","Restore the Last Cursor Location","-","New User Graphic Interface","Standard User Interface","-","Display Coordinates","-","Change the Color of a Arrow","-","Undo the Last Arrow")); +macro "Arrow Drawing Menu Tool -C0b3D0bD1bD2bD3bD41D42D43D44D45D46D47D48D49D4aD4bD4cD4dD4eD4fD5bD6bD7bD8bD9bDabDbbDcbDdbDebDfbCfffD00D01D02D03D04D05D06D07D08D09D0aD0cD0dD0eD0fD10D11D12D13D14D15D16D17D18D19D1aD1cD1dD1eD1fD20D21D22D23D24D25D26D27D28D29D2aD2cD2dD2eD2fD30D31D32D33D34D35D36D37D38D39D3aD3cD3dD3eD3fD40D50D51D52D53D54D55D56D57D58D5cD5dD5eD5fD60D61D62D63D64D65D6aD6cD6dD6eD6fD70D71D72D73D7aD7cD7dD7eD7fD80D81D82D83D84D85D86D89D8aD8cD8dD8eD8fD90D91D92D93D94D95D96D99D9aD9cD9dD9eD9fDa0Da1Da2Da3Da4Da5Da6Da9DaaDacDadDaeDafDb0Db1Db2Db3Db4Db5Db6Db8Db9DbaDbcDbdDbeDbfDc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9DcaDccDcdDceDcfDd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9DdaDdcDddDdeDdfDe0De1De2De3De4De5De6De7De8De9DeaDecDedDeeDefDf0Df1Df2Df3Df4Df5Df6Df7Df8Df9DfaDfcDfdDfeDffC00fD59D67D68D69D74D75D76D77D78D79D87D88D97D98Da7Db7C88fD5aD66Da8" { + cmd = getArgument(); + if (cmd!="-" && cmd == "Set Drawing Arrow\(s\) Location") {colorok=0;cursorok=1;drawok=0;dyn=1; setTool(10);} + if (cmd!="-" && cmd == "Draw Arrow\(s\) at the Current Location") {drawArrow();} + if (cmd!="-" && cmd == "Change the Color of a Arrow") {colorok=1;cursorok=0;drawok=0;dyn=1; setTool(10);} + if (cmd!="-" && cmd == "Restore the Last Cursor Location") {restoreLastCursor ();} + if (cmd!="-" && cmd == "Display Coordinates") {DisplayCo ();} + if (cmd!="-" && cmd == "Undo the Last Arrow") {UndoLast ();} + if (cmd !="-" && cmd == "New User Graphic Interface") {lookInterface = "New User Graphic Interface";} + if (cmd !="-" && cmd == "Standard User Interface") {lookInterface = "Standard User Interface";} +} + +var cCmds = newMenu("Cursor Color Menu Tool",newArray("yellow","red","green","blue","magenta","cyan","orange","black","white","-","Restore Initial Selection Color","Get Curent Selection Color")); +macro "Cursor Color Menu Tool - C1b0D85D95Da5Db5Dc5Dd5De5Df5CfffD00D01D02D03D04D06D07D08D09D0aD0bD0cD0dD0eD0fD10D11D12D13D14D16D17D18D19D1aD1bD1cD1dD1eD1fD20D21D22D23D24D26D27D28D29D2aD2bD2cD2dD2eD2fD30D31D32D33D34D36D37D38D39D3aD3bD3cD3dD3eD3fD40D41D42D43D44D46D47D48D49D4aD4bD4cD4dD4eD4fD50D51D52D53D54D56D57D58D59D5aD5bD5cD5dD5eD5fD60D61D62D63D64D66D67D68D69D6aD6bD6cD6dD6eD6fD80D81D82D83D84D86D87D88D89D8aD8bD8cD8dD8eD8fD90D91D92D93D94D96D97D98D99D9aD9bD9cD9dD9eD9fDa0Da1Da2Da3Da4Da6Da7Da8Da9DaaDabDacDadDaeDafDb0Db1Db2Db3Db4Db6Db7Db8Db9DbaDbbDbcDbdDbeDbfDc0Dc1Dc2Dc3Dc4Dc6Dc7Dc8Dc9DcaDcbDccDcdDceDcfDd0Dd1Dd2Dd3Dd4Dd6Dd7Dd8Dd9DdaDdbDdcDddDdeDdfDe0De1De2De3De4De6De7De8De9DeaDebDecDedDeeDefDf0Df1Df2Df3Df4Df6Df7Df8Df9DfaDfbDfcDfdDfeDffC03fD70D71D72D73D74D75Cf00D05D15D25D35D45D55D65Cf0eD76D77D78D79D7aD7bD7cD7dD7eD7f" { + cmd=getArgument(); + if (previousColor == "") {previousColor= call("ij.gui.Roi.getColor");} + if (cmd != "Restore Initial Selection Color" && cmd != "Get Curent Selection Color" && cmd != "-") run("Colors...", "selection=["+cmd+"]"); + if (cmd == "Restore Initial Selection Color" && cmd != "-") RestoreInitColor (); + if (cmd == "Get Curent Selection Color" && cmd != "-") GetCurentSelectionColor (); + getSelectionColors(call("ij.gui.Roi.getColor")); + showStatus("Selection color is now " + getColorName(Red,Green,Blue)); +} + +macro "Abort Process Action Tool - C810Dc2Df7Ca55D42D51Ce20D7dD8cDd6CfffD88Da7Cd20DadCfedD3eD55D5bDa9Dc1Ce40D63De6CfffD00D01D03D04D05D06D07D08D09D0aD0cD0dD0eD0fD10D11D14D1cD1dD1eD1fD20D21D22D2fD31D3fD40D66D6aDaaDb0Db5DbbDc0De0DefDf0Df1Df2Df3DfdDfeDffC811Da1Dd3Cc77D1bD6cCe20Dc7CfffD23D65D79DdfCc31D68Da4CeffDeeCd52D27D4dC910D7fD8fDbfDf9Cd64D4bD75Db7Dc6Ce30D39D47D48D74D85Da3CfffD13D30Da6Dd0De1Cc20DacDbdDdaDdbCfffD98Cd42D28D52D5eDe5Ca21D71D81D91DcaCfecD5aD67D69D96Cf30D3aD3bD94Db3Cc32D25D2bD34D9bCfffD12D50D70D80D87D89D90D99Da0Db6Dd1De2Cf63D64D72D82Db2DbeC910D9fDafDecDf8Cb66D17D19D1aDa8Ce20D37D49Dd7Dd8CeffD6bD77D97Cd20D6dD7cDc9CffeD4fD60D7aD9aDbaCf52D35D44D53D6eC821D5fD61De4DfbCebbD15DbcDcbDcfDdeCf30D58D73D83D93Cd41D3cD95De7CfffD2eD78Cf53Dc3DcdDd4DebCa20D6fDccCc75D18D24D5cD7bD8aCf30D36D84Cd30D46D59D8bDd5CfffD02D0bD2dD41D76Cf42D26D8eD9eDdcCa32D2cD3dD4eDb9CfedD56Da5Dd2DedDfcCe31D2aD57D5dDeaCc41D43D4cD86DaeCf63D62D92Da2C810DddDf6DfaCa66D16D33Ce30Dc8Cd20D8dD9cD9dDd9CfeeD32DabDe3Df4Cd51D29D7eC822Db1Df5Cea7Db4Dc5Ce30D4aDb8De9Cd40D38Dc4De8Cd53D45D54C911Dce" { + abortProcess (); +} + +macro "On Line Documentation Action Tool - C000Da9DadDb6DbdDc5Dc6Dd3Dd4Dd5Dd6DddC20fD11D12D13D14D15D16D17D18D19D1aD1bD1cD1dD1eD1fC0f3D42D43D44D45D46D47D48D49D4aD4bD4cD4dD4eD4fC0feD32D33D34D35D36D37D38D39D3aD3bD3cD3dD3eC444DdeDefC73fD01Cfd0D62D63D64D65D66D67D68D69D6aD6bD6cD6dD6eCeeeD90D95Da1Da4Db0Db2Db3De0De8Df0Df7DfaC222DeeC06fD22D23D24D25D26D27D28D29D2aD2bD2cD2dD2eC7f0D52D53D54D55D56D57D58D59D5aD5bD5cD5dD5eCcccDbfDf9Cf74D70Ca99D97C888Da8CfffD9bD9cC000Dc4Dd2C64fD10C0f4D41C0ffD31D3fCf40D71D72D73D74D75D76D77D78D79D7aD7bD7cD7dD7eD7fCa7fD00Cfd0D61D6fCfefD91C444Db5DdaDe9C06fD21D2fC7f0D51D5fCeddD96Cf88D82D83D84D85D8bD8cCaaaDccDeaDfdC999DcfCfffD9fDafDb1Db8De1C666Dc7C84fD02D03D04D05D06D07D08D09D0aD0bD0cD0dD0eC333Da6Da7DaaDb9DbcDd9DdcCdddD9aDa2Da3Dc8DdbDecCaaaDabDaeDc1De3De4De5De6Cf89D8dC222DcdDedDfeDffC4ffD30CfffDebDf1Df2Df3Df4Df5Df6DfcC48fD20C4f6D40CeeeD92D93D94Da0DcbDf8DfbCbbbDb4Dd8C9f4D50C555Dc2C73fD0fC333DbbDc3Dc9Dd1CdddDe7Cf89D81D86D8aD8fC111DbaDd7CdeeDa5CbbbDb7Dc0De2Cf99D87D88D89C777DacDcaCcbbD9eCfaaD80C999D98Cf89D8eC999D9dC766D99C555DceC888DbeCfd4D60C777DdfC666Dd0"{ + doc (); +} + +macro "Version and Update Infos Action Tool - CcccD5fD6fD7fD8fD9fC78bD17D19D2aD33D37D3bD42D4cD75D95DceDd5Dd9De6Df7Df9CddeDa3C36bD27D28D3aD57D58D59D66D76D77D86D87Da7Db8Dd6De8De9CeeeD00D01D02D04D06D07D08D09D0bD0dD0fD10D11D12D14D1bD1dD1fD20D21D22D2dD30D31D32D40D46D47D48D49D50D5bD60D70D71D72D74D7dD80D81D82D84D8dD90D91D92D94D9dDa0Da1Da2Da4Db0Db1DbbDc0Dc1Dc6Dc7Dc8Dc9Dd0Dd1Dd2De0De1De2DedDf0Df1Df2Df4DfbDfdDffC8beD3cD3dD4dD5aD6aD79D7aD7bD85D8bD9aDaaDc3Dc4Dd3Dd4CeeeD03D05D0aD0cD0eD13D15D1cD1eD23D2eD3eD4aD55D6cD73D7cD7eD83D8cD8eD93D9cD9eDb5DcaDdeDe3DeeDf3Df5DfcDfeC559D18D26D34D35D36D41D51D61DafDbfDcfDdaDdbDddDeaDf8CcddD2fD5cD6dD6eDabDb2Db4Dc2DefC99bD16D24D39D45D54D56D64D65Da5DacDb6DbcDcbDd7DecDfaCdefD67D8aC59dD29D2bD68D69D78D88D96D97D98D99Da6Da8Da9Db9De5De7CacdD1aD2cD38D4bD4eD5dD5eD6bD89D9bDb3DbaDc5Dd8De4Df6C348D25D43D44Db7DccDdcDebCcccD3fD4fDdf" { + VersionInfos (); +} + +macro "About \"Image, Stack and Timelapse Arrow Labelling\" Action Tool - C000D84Cb9fD25De7CaaaD14D2dDa0DafDecDfaCedfD49D4aD4bD4cD58D68D9bDb9DbaDbbDbcC889D2cDebCddfD52CcccD0bD22CeeeD00D03D0cD0fD10D1fD20D2fD30D40Dc0Dd0DdfDe0DefDf0Df1Df2Df3DfcDfeDffC666D07D70CdcfD34D35Dc4CbacD86D91CfefD6bD6dD7cD8cD8dD8eD9cD9dDadC97aDd3De5CedfD99CeeeD01D02D04D0dD0eD11D12D1eD21D3fDcfDd1De1De2DeeDf4DfdCfefD7dC545D94Da5CdbeDa4Da7CbabD05D50DaeCfefD7eC98aD32Da1CecfD39D3aD3bD46D48D57D67Da8Db6Db8Dc9DcaDcbDccCdcdD81C878D1bD60D65CdcfD29D36D38D47D77Db7Dc8Dd9DdaCcbcD7aDbfDc1De3C98bD16D24D75DeaCedfD56D66D73D76D83D93Da3C212D7bD88D96D97CcaeD26D3cDdbCaaaD3eD5fCfdfD59C889D15D1aD78Dc2CdcfD45Db4Db5Dc6CdddD13D31D4fDdeDedDfbC777D09D7fD85D90Df7CeceDbdCbadD18D55Db2De9Ca9aD5eDcdDceDdcC656D08D64D80D87D8bCdbfD28D2aD37Dc7Dd8CbbbD1cD42Dd2Df5CfdfD5aD5bD5cD5dD69D6aD6cD9aDa9DabDacC999D0aD41DddDf6CdddD1dD2eD9eDb0C888D06D4eD6fD9fDf9CcbdD54D71D98Dc3Ca9dD17D19Dd4De6C000D74D79D95CcafDd5Dd6De8CedfD62D72D92C889D51Db1DbeCedfD53D63Da2CdcdD6eC777D8fDf8CdcfD43D44Db3Dc5CbadD2bD33C99aD23De4C545D89Da6CcbfD27Dd7CbabD61CedfD82DaaC98aD3dCdceD4dD8a" { + about1 (); +} + +macro "Undo Last Arrow [z]"{ + run("Undo"); +} + +///////////////// Functions //////////////////// + +// set the location +function Arrow (curs) { + targetWindow=getImageID(); + if (curs == 1) { + getCursorLoc(x, y, z, flags); + xstart=x; ystart=y; + w = getWidth(); h = getHeight(); + x2=x; y2=y; + while (flags&16!=0) { + getCursorLoc(x, y, z, flags); + if (x!=x2 || y!=y2) { + makeCursor(x,y,w,h); + } + x2=x; y2=y; + wait(10); + }; + } else {xstart =-1; ystart=-1;} + + // choose slice + if (x!=xstart && y!=ystart) { + lastx=x;lasty=y; + nbslice= nSlices;curentSlice= getSliceNumber(); + if (nbslice >1) {chooseStack(curentSlice,nbslice);} else {FSlice=nbslice;TSlice=nbslice;} + if (lookInterface == oldlook) {DrawTheArrows (x,y);} + if (lookInterface == newlook) { + palette=1;dyn=1;reponse=0;cancel=0;cursorok=0; + if (! isOpen("Arrow Palette")) {updatePalette (1);} + setTool(10); + } + } +} + +// set the parameters +function arrow (box) { + // old interface + if (lookInterface == oldlook) { + if (box == 1) { + previewarrow=0; + arrowchoices1=newArray("3","6","10","15","20","25","30"); + arrowchoices2=newArray("10","15","20","25","30"); + arrowchoices3=newArray("6","11","16","21","26","31"); + arrowchoices4=newArray("0","5","10","15","20","25","30"); + arrowchoices5=newArray("0","2","4","6","12"); + arrowchoices7=newArray("North","N-E","East","S-E","South","S-W","West","N-W"); + + Dialog.create("Arrow Size and Form"); + Dialog.addChoice("Arrow length:", arrowchoices2, toString(arrowlenght)); + Dialog.addChoice("Arrow width:", arrowchoices1, toString(arrowwidth)); + Dialog.addChoice("Arrowhead Filling Level:", arrowchoices3, toString(arrowconcav)); + Dialog.addChoice("Tail Size (Length):", arrowchoices4, toString(taillenght)); + Dialog.addChoice("Tail Size (Width):", arrowchoices5, toString(tailwidth)); + Dialog.addChoice("Arrow Color:",colorchoices, tailcolor); + Dialog.addChoice("Arrow Orientation:",arrowchoices7, tailorient); + Dialog.addCheckbox("Preview", false); + Dialog.addMessage(" Press 'z' to Undo (only the last arrow)"); + Dialog.show(); + + arrowlenght = parseFloat (Dialog.getChoice()); + arrowwidth = parseFloat (Dialog.getChoice()); + arrowconcav = parseFloat( Dialog.getChoice()); + taillenght = parseFloat(Dialog.getChoice()); + tailwidth = parseFloat(Dialog.getChoice()); + tailcolor = Dialog.getChoice(); + tailorient = Dialog.getChoice(); + previewarrow = parseFloat (Dialog.getCheckbox()); + } + if (arrowconcav > (arrowlenght+1)) arrowconcav=(arrowlenght+1); + if (tailwidth > arrowwidth) tailwidth = (arrowwidth-3); + arrowline=1;xfleche=x; yfleche=y; + if (previewarrow == true) {preview();} + selectImage(targetWindow); + setupUndo(); + + if (arrowconcav > (arrowlenght+1)) arrowconcav=(arrowlenght+1); + if (tailwidth > arrowwidth) tailwidth = (arrowwidth-3); + + for (a=0;a<4;a++) { + builtarrow (arrowline,xfleche,yfleche,arrowwidth,arrowlenght,tailorient,arrowconcav,tailwidth,taillenght,getRGBcolor (tailcolor)); + } + } + + // new interface + if (lookInterface == newlook) { + arrowline=1;xfleche=x; yfleche=y; + setupUndo(); + for (a=0;a<4;a++) { + builtarrow (arrowline,xfleche,yfleche,arrowwidth,arrowlenght,tailorient,arrowconcav,tailwidth,taillenght,getRGBcolor (tailcolor)); + } + } +} + +function preview () { + prev="Arrow preview"; + newImage(prev,"RGB Black",200,300,1); + image=getImageID(); + xfleche=100;yfleche=75; + setFont("Serif", 12); + builtarrow (arrowline,xfleche,yfleche,arrowwidth,arrowlenght,tailorient,arrowconcav,tailwidth,taillenght,getRGBcolor (tailcolor)); + selectImage(image); + setColor(255,255,255); + drawString("Arrow lenght: "+arrowlenght + " Arrow width: "+arrowwidth, 2,210); + drawString("Arrowhead Filling Level: "+arrowconcav,2,225); + drawString("Tail Lenght: "+taillenght+ " Tail Width: "+tailwidth,2,240); + drawString("Arrow Color: "+tailcolor,2,260); + drawString("Arrow Orientation: "+tailorient,2,275); + exit; +} + +function builtarrow (arrowline,xfleche,yfleche,arrowwidth,arrowlenght,tailorient,arrowconcav,tailwidth,taillenght,couleur) { + // convert into rgv if 8 bit grey + if (bitDepth()==8) {showMessageWithCancel ("Conversion into 24 bit (RGB) will be performed."); run("RGB Color");} + autoUpdate(false); + setColor(rgb[0], rgb[1], rgb[2]); + if (tailorient == "North") {orientangle=0;} + if (tailorient == "N-E") {orientangle=(PI/4);arrowline=2;} + if (tailorient == "East") {orientangle=(PI/2);} + if (tailorient == "S-E") {orientangle=(PI*3/4);arrowline=2;} + if (tailorient == "South") {orientangle=(PI);} + if (tailorient == "S-W") {orientangle=(5*PI/4);arrowline=2;} + if (tailorient == "West") {orientangle=(3*PI/2);} + if (tailorient == "N-W") {orientangle=(-(PI/4));arrowline=2;} + + fleche1=newArray (3); + fleche2=newArray (3); + alpha3a=(PI/2);lineWidth=1;xi=0; + setLineWidth(arrowline); + // arrowhead drawing + moveTo(xfleche, yfleche); + x1=(-1*arrowwidth);y1=(arrowlenght); alpha1a=(atan2(y1,x1)); alpha1b=(alpha1a+orientangle); + getxy (x1,y1,alpha1b); + fleche1[0]=(xfleche+xprime);fleche2[0]=(yfleche+ yprime); + x2=(arrowwidth);y2=(arrowlenght); alpha2a=(atan2(y2,x2));alpha2b=(alpha2a+orientangle); + getxy (x2,y2,alpha2b); + fleche1[2]=(xfleche+xprime);fleche2[2]=(yfleche+yprime); + for (i=2; i1) { + Dialog.addMessage("You are working with a stack of " + nbslices +" slices . Choose \nto draw an arrowonto the current slice or other slices:"); + Dialog.addMessage("the default values correspond to the current slice. Set the\nsame slicenumber to draw an arrow onto a single slice."); + Dialog.addMessage("Arrow drawing"); + Dialog.addChoice("from the slice", SliceMenu,toString(fromSlice)); Dialog.addChoice("to the slice",SliceMenu,toString(toSlice)); + } + Dialog.show(); + fromSlice= Dialog.getChoice(); FSlice=parseFloat (fromSlice); + toSlice= Dialog.getChoice(); TSlice=parseFloat (toSlice); +} + +function openMovie () { + if (ImaDemo != "") { + run("Using QuickTime...", "open..."); + //run("Using QuickTime...", "open=["+ImaDemo+"]"); + } else {run("Using QuickTime...", "open..."); } + ImaDemo=""; +} + +function saveAsAvi () { + theStack= getTitle; + if (nSlices == 1) exit ("You can\'t make a movie with a single image. Fist make a stack."); + folderTreatedpath =getDirectory("current"); + if (ImaDemo != "") folderTreatedpath =ImaDemo; + if (endsWith(theStack, ".tif") == 1) {theStack = substring (theStack,0,(indexOf(theStack, ".tif")));} + if (endsWith(theStack, ".avi") == 1) {theStack = substring (theStack,0,(indexOf(theStack, ".avi")));} + kind=lastIndexOf(theStack, "-Arw-"); + if (kind>0) {theStack = substring (theStack,0,kind);} + n=1; + checkpath= folderTreatedpath + theStack + "-Arw-"+n+".avi"; + while (File.exists(checkpath)) { + n++; + checkpath= folderTreatedpath + theStack + "-Arw-"+n+".avi"; + } + // set the rate speed of the movie (image/sec) + userspeed=15;speed=0; + while (speed < 1 || speed > 60) { + Dialog.create("Save Movie Settings"); + Dialog.addMessage("File destination\:\n"+checkpath); + Dialog.addNumber("Speed of the movie 1 ... 60 ?", defaultspeed, 0, 2, "(image\/sec)"); + Dialog.show(); + speed=Dialog.getNumber(); + + } + defaultspeed=speed; + run("Animation Options...", "speed=["+speed+"]"); + saveAs ("avi", checkpath); +} + +// to draw a arrow at the curent location +function drawArrow() { + if (getTitle =="Arrow Palette" || getTitle =="Last Arrow") exit; + targetWindow=getImageID(); + makeCursor(lastx,lasty,w,h); + if (lastx != -1 && lasty!= -1) { + x=lastx;y=lasty; + Arrow (0); + } else {showMessage ("No current location coordinates found. Choose a location \nusing the \"Set Drawing Arrow\(s\) Location\" sub menu of the \n\"Arrow Drawing Menu Tool\".");} +} + +// called from the user interface tool +function changeColor () { + if (getTitle !="Arrow Palette" && getTitle !="Last Arrow") { + setupUndo(); + getCursorLoc(x, y, z, flags); + doWand(x, y); + Dialog.create("New Color Choice"); + Dialog.addChoice("Color?",colorchoices, toString(newcolor)); + Dialog.addMessage(" Press 'z' to Undo"); + Dialog.show(); + newcolor = Dialog.getChoice(); + rgb=getRGBcolor (newcolor); + setColor(rgb[0], rgb[1], rgb[2]); + fill(); + run("Select None"); + } +} + +function makeCursor(x,y,w,h) { + px[0]=0; py[0]=y; + px[1]=w; py[1]=y; + px[2]=x; py[2]=y; + px[3]=x; py[3]=0; + px[4]=x; py[4]=h; + px[5]=x; py[5]=y; + makeSelection("polgon", px, py); + showStatus("Target coodinates: x="+x+", y="+y); +} + +function restoreLastCursor () { + if (getTitle =="Arrow Palette" || getTitle =="Last Arrow") exit; + if (lastx != -1 && lasty!= -1) { + makeCursor(lastx,lasty,w,h); + } else {exit ("No previous cursor available.");} +} + +// draw the arrows +function DrawTheArrows (x,y) { + nbslice= nSlices;countslc=1; + for (i=FSlice; i<= TSlice; i++) { + setSlice(i); + if (countslc ==1) {arrow (1);} else {arrow (0);} + countslc ++; + } + setSlice(curentSlice); +} + +// download demo movies +function OpenMovieLink(question,demoimagelink,demoim,demoim1) { + setBatchMode(true); + // Check if already downloaded. + if (isOpen(demoim)) exit ("The \"" + demoim + "\" is already opened as a stack."); + demoimalocation = getDirectory("startup"); + ImaDemo1 = demoimalocation+"Downloaded Demo Images"+File.separator; + ImaDemo2 =ImaDemo1 + "Demo Movie Working Folder" + File.separator; + ImaDemo=ImaDemo2; + fildestination = ImaDemo + demoim; + fildestination1= ImaDemo + demoim1; + + // download the demo if not already into the ImageJ folder + if (! File.exists(fildestination) || ! File.exists(fildestination1)) { + if (File.openUrlAsString(urllist) == "") exit("You need an internet access to run this function."); + showMessageWithCancel ("ImageJ will download a demo movie. Continue?"); + run("URL...", "url=["+demoimagelink+"]"); + imageid = getImageID(); + nomdimage = getTitle; + // Create a repertory in ImageJ folder. + File.makeDirectory(ImaDemo1); + if (!File.exists(ImaDemo1)) exit ("Unable to create the directory \""+ImaDemo1+"\" , something wrong in the ImageJ folder"); + // Create a repertory in ImageJ folder. + File.makeDirectory(ImaDemo2); + if (!File.exists(ImaDemo2)) exit ("Unable to create the directory \""+ImaDemo2+"\" , something wrong in the ImageJ folder"); + selectWindow(nomdimage);speed=15; + run("Animation Options...", "speed=["+speed+"]"); + saveAs ("avi", fildestination); + saveAs ("zip", fildestination1); + close(); + } + + // create a working folder with the dowloaded movie + if (File.exists(fildestination) && ! isOpen(demoim)) { + //if (question ==1 ) showMessageWithCancel ("The \"" + demoim + "\" has been downloaded available at the following HD location:\n" + fildestination + "\n and:" + fildestination1+"\nOpen it now as a stack ?\n(Or \"Cancel\" and open it from the \"Open a Movie as Stack\" sub\-menu of the \"Movie and Stack Menu Tool\"\) "); + if (question ==1 ) showMessageWithCancel ("- The \"" + demoim + "\" has been downloaded and available at the following HD location:\n" + fildestination + "\n- A \".zip\" stack version is also available at the following HD location (for computer without required QuickTime resources):\n"+ fildestination1+"\n \nOpen the stack now? "); + //run("Using QuickTime...", "open=["+fildestination+"]"); + open(fildestination1); + } + setBatchMode("exit and display"); +} + +function setMovieSpeed () { + userspeed=15;speed=0; + while (speed < 1 || speed > 60) { + Dialog.create("Movie\/Stack Animation Speed Settings"); + Dialog.addNumber("Speed of the movie\/stack animation 1 ... 60 ?", defaultspeed, 0, 2, "(image\/sec)"); + Dialog.show(); + speed=Dialog.getNumber(); + } + defaultspeed=speed; + run("Animation Options...", "speed=["+speed+"]"); +} + +function AnimateStack() { + run("Start Animation"); +} + +function UndoLast () { + run("Undo"); +} + +function DisplayCo () { + showMessage("X Coordinate: "+x + "\nY Coordinate: "+y); +} + +// graphic interface +function goGraphInt () { + clickx=0;clicky=0; + reponse=0;cancel=0;dyn =0; + if (! isOpen("Arrow Palette")) {reponse=1;cancel=1;} + getCursorLoc(clickx, clicky, z, flags); + + if (Nord(clickx,clicky) ==1) {tailorient="North";updatePalette (0);} + if (Sud (clickx,clicky) ==1) {tailorient="South";updatePalette (0);} + if (Est (clickx,clicky) ==1) {tailorient="East";updatePalette (0);} + if (Ouest (clickx,clicky) ==1) {tailorient="West";updatePalette (0);} + if (NordOuest (clickx,clicky) ==1) {tailorient="N-W";updatePalette (0);} + if (NordEst (clickx,clicky) ==1) {tailorient="N-E";updatePalette (0);} + if (SudEst (clickx,clicky) ==1) {tailorient="S-E";updatePalette (0);} + if (SudOuest (clickx,clicky) ==1) {tailorient="S-W";updatePalette (0);} + + testcolor= coloBoxes(0,1,clickx,clicky); + if (testcolor != "") {tailcolor=testcolor;updatePalette (0);} + + boxstatut=adjustBoxes(box1x,box1y,0,1,clickx,clicky); + if (boxstatut == 2) {arrowlenght=arrowlenght-1;updatePalette (0);} + if (boxstatut == 3) {arrowlenght=arrowlenght+1;updatePalette (0);} + + boxstatut=adjustBoxes(box2x,box2y,0,1,clickx,clicky); + if (boxstatut == 2) {arrowwidth=arrowwidth-1;updatePalette (0);} + if (boxstatut == 3) {arrowwidth=arrowwidth+1;updatePalette (0);} + + boxstatut=adjustBoxes(box3x,box3y,0,1,clickx,clicky); + if (boxstatut == 2) {arrowconcav=arrowconcav-1;updatePalette (0);} + if (boxstatut == 3) {arrowconcav=arrowconcav+1;updatePalette (0);} + + boxstatut=adjustBoxes(box4x,box4y,0,1,clickx,clicky); + if (boxstatut == 2) {taillenght=taillenght-1;updatePalette (0);} + if (boxstatut == 3) {taillenght=taillenght+1;updatePalette (0);} + + boxstatut=adjustBoxes(box5x,box5y,0,1,clickx,clicky); + if (boxstatut == 2) {tailwidth=tailwidth-1;updatePalette (0);} + if (boxstatut == 3) {tailwidth=tailwidth+1;updatePalette (0);} + + if (Cancel (clickx,clicky) == 1) {cancel=1;reponse=1;palette=0;} + if (Apply (clickx,clicky) ==1) {cancel=0;reponse=1;palette=0;apply=1;cursorok=1;} + dyn =1; +} + +function getSample () { + selectImage (targetWindow); + xtemp=getWidth(); ytemp=getHeight(); + run("Select None"); + setBatchMode(true); + run("Duplicate...", "title=temp"); + run("Select All");run("Copy");close (); + newImage("tempSample","RGB Black",xtemp+2*Lprev,ytemp+2*Hprev,1); + setForegroundColor(62,10,113); + run("Select All");run("Fill");run("Select None"); + run("Paste");run("Select None"); + makeRectangle ((x+(Lprev/2)+1), (y+(Lprev/2)+1), Lprev-2, Hprev-2); + run("Copy");close (); +} + +function coloBoxes(draw,detect,clickx,clicky) { + xcolorbox=20;ycolorbox=10;spcol=(Lpalette-8*xcolorbox)/9; + setLineWidth(1);detectcol=-1;democolor=""; + for (a=0;a<8;a++) { + setColor(255,0,93); + if (detect==1) { + if (clicky >(Hpalette-160) && clicky < (Hpalette-160+ycolorbox)) { + if (clickx > (a*xcolorbox+a*spcol+spcol) && clickx < ((a*xcolorbox+a*spcol+spcol)+xcolorbox)) detectcol=a; + } + } + if (draw==1) {drawRect ((a*xcolorbox+a*spcol+spcol), (Hpalette-160), xcolorbox, ycolorbox);run("Select None");} + if (a==0) {getRGBcolor ("Red");if (detect==1 && detectcol==0) {democolor ="Red";}} + if (a==1) {getRGBcolor ("Green");if (detect==1 && detectcol==1) {democolor ="Green";}} + if (a==2) {getRGBcolor ("Blue");if (detect==1 && detectcol==2) {democolor ="Blue";}} + if (a==3) {getRGBcolor ("Cyan");if (detect==1 && detectcol==3) {democolor ="Cyan";}} + if (a==4) {getRGBcolor ("Yellow");if (detect==1 && detectcol==4) {democolor ="Yellow";}} + if (a==5) {getRGBcolor ("Magenta");if (detect==1 && detectcol==5) {democolor ="Magenta";}} + if (a==6) {getRGBcolor ("Black");if (detect==1 && detectcol==6) {democolor ="Black";}} + if (a==7) {getRGBcolor ("White");if (detect==1 && detectcol==7) {democolor ="White";}} + if (draw==1) {setColor(rgb[0], rgb[1], rgb[2]);fillRect ((a*xcolorbox+a*spcol+spcol+1), (Hpalette-160+1), (xcolorbox-2), (ycolorbox-2));run("Select None");} + } + return democolor; +} + +function adjustBoxes(xbx,ybx,draw,detect,clickx,clicky) { + xadjustbox=25;yadjustbox=14; + setLineWidth(1);status=0; + if (detect==1) { + if (clicky >(ybx) && clicky < (ybx+yadjustbox) && clickx > (xbx+xadjustbox/2) && clickx < (xbx+xadjustbox)) {status=3;} + if (clicky >(ybx) && clicky < (ybx+yadjustbox) && clickx > xbx && clickx < (xbx+xadjustbox/2)) {status=2;} + } + if (draw==1) { + setColor(100,50,50);fillRect ((xbx+1), (ybx+1), (xadjustbox-1), (yadjustbox-1));run("Select None"); + setColor(255,0,93);drawRect (xbx, ybx, xadjustbox, yadjustbox); run("Select None"); + drawLine ((xbx+xadjustbox/2-1), ybx, (xbx+xadjustbox/2-1), (ybx+yadjustbox-1)); + setFont("SansSerif", 15,"antialiased");setColor(0,255,0); + drawString("-",(xbx+2),(ybx+15)); + drawString("+",(xbx+xadjustbox/2-1),(ybx+15)); + } + return status; +} + +// location of the different interactive areas +// cancel +function Cancel (clickx,clicky) { + testcancel=0; + if (clickx > distBord && clickx < (distBord+largbuton) && clicky > (Hpalette-disthaut) && clicky < (Hpalette-disthaut+hautbuton)) {testcancel=1;} + return testcancel; +} + +function Nord (clickx,clicky) { + if (clickx > (xpreview-8) && clickx < (xpreview +8) && clicky > ((ypreview+(Hprev/2))+(Lpalette-Hprev)/6) && clicky < ((ypreview+(Hprev/2))+(Lpalette-Hprev)/6+20)) {testpal=1;} else {testpal=0;} return testpal; +} + +function Sud (clickx,clicky) { + if (clickx > (xpreview-8) && clickx < (xpreview +8) && clicky > ((Lpalette-Hprev)/3-20) && clicky < ((Lpalette-Hprev)/3)) {testpal=1;} else {testpal=0;} return testpal; +} + +function Ouest (clickx,clicky) { + if (clickx > (xpreview+(Lprev/2)+(Lpalette-Lprev)/6) && clickx < (xpreview+(Lprev/2)+(Lpalette-Lprev)/6+20) && clicky > (ypreview-8) && clicky < (ypreview+8) ) {testpal=1;} else {testpal=0;} return testpal; +} + +function Est (clickx,clicky) { + if (clickx > ((Lpalette-Lprev)/3-20) && clickx < ((Lpalette-Lprev)/3) && clicky > (ypreview-8) && clicky < (ypreview+8) ) {testpal=1;} else {testpal=0;} return testpal; +} + +function NordOuest (clickx,clicky) { + if (clickx > (xpreview+(Lprev/2)+(Lpalette-Lprev)/6) && clickx < (xpreview+(Lprev/2)+(Lpalette-Lprev)/6+18) && clicky > ((ypreview+(Hprev/2))+(Lpalette-Hprev)/6) && clicky < ((ypreview+(Hprev/2))+(Lpalette-Hprev)/6+18) ) {testpal=1;} else {testpal=0;} return testpal; +} + +function NordEst (clickx,clicky) { + if (clickx > ((Lpalette-Lprev)/3-18) && clickx < ((Lpalette-Lprev)/3) && clicky > ((ypreview+(Hprev/2))+(Lpalette-Hprev)/6) && clicky < ((ypreview+(Hprev/2))+(Lpalette-Hprev)/6+18) ) {testpal=1;} else {testpal=0;} return testpal; +} + +function SudEst (clickx,clicky) { + if (clickx > ((Lpalette-Lprev)/3-18) && clickx < ((Lpalette-Lprev)/3) && clicky > ((Lpalette-Hprev)/3-18) && clicky < ((Lpalette-Hprev)/3) ) {testpal=1;} else {testpal=0;} return testpal; +} + +function SudOuest (clickx,clicky) { + if (clickx > (xpreview+(Lprev/2)+(Lpalette-Lprev)/6) && clickx < (xpreview+(Lprev/2)+(Lpalette-Lprev)/6+18) && clicky > ((Lpalette-Lprev)/3-18) && clicky < ((Lpalette-Lprev)/3) ) {testpal=1;} else {testpal=0;} return testpal; +} + +// apply +function Apply (clickx,clicky) { + testapply=0; + if (clickx > (Lpalette-distBord-largbuton) && clickx < (Lpalette-distBord) && clicky > (Hpalette-disthaut) && clicky < (Hpalette-disthaut+hautbuton)) { + makeRectangle (0,0,Lpalette,(Hpalette-36)); + run("Crop"); + if (isOpen("Last Arrow")) {selectWindow("Last Arrow");close ();} + selectImage (paletteID);rename ("Last Arrow"); + testapply=1; + } + return testapply; +} + +function updatePalette (draw) { + setBatchMode(true); + if (draw ==1) { + setBatchMode(true); + getSample (); + restoreLastCursor (); + setLineWidth(arrowline); + // make the palette window + newImage("Arrow Palette","RGB Black",Lpalette,Hpalette,1); + paletteID=getImageID(); + setForegroundColor(32,0,93); + run("Select All");run("Fill");run("Select None"); + setColor(255,0,93); + drawRect ( (Lpalette-Lprev)/2, (Lpalette-Lprev)/2, Lprev, Hprev);run("Select None"); + xpreview=((Lpalette-Lprev)/2 + Lprev/2); + ypreview=((Lpalette-Lprev)/2 + Hprev/2); + + // draw orientation arrows + + builtarrow (2,(Lpalette-Lprev)/3,ypreview,6,20,"East",15,0,0,getRGBcolor ("Yellow")); + builtarrow (2,(Lpalette-Lprev)/3,(Lpalette-Hprev)/3,6,20,"S-E",15,0,0,getRGBcolor ("Yellow")); + builtarrow (2,xpreview,(Lpalette-Hprev)/3,6,20,"South",15,0,0,getRGBcolor ("Yellow")); + builtarrow (2,xpreview+(Lprev/2)+(Lpalette-Lprev)/6,(Lpalette-Hprev)/3,6,20,"S-W",15,0,0,getRGBcolor ("Yellow")); + builtarrow (2,xpreview+(Lprev/2)+(Lpalette-Lprev)/6,ypreview,6,20,"West",15,0,0,getRGBcolor ("Yellow")); + builtarrow (2,xpreview+(Lprev/2)+(Lpalette-Lprev)/6,(ypreview+(Hprev/2))+(Lpalette-Hprev)/6,6,20,"N-W",15,0,0,getRGBcolor ("Yellow")); + builtarrow (2,xpreview,(ypreview+(Hprev/2))+(Lpalette-Hprev)/6,6,20,"North",15,0,0,getRGBcolor ("Yellow")); + builtarrow (2,(Lpalette-Lprev)/3,(ypreview+(Hprev/2))+(Lpalette-Hprev)/6,6,20,"N-E",15,0,0,getRGBcolor ("Yellow")); + + coloBoxes(1,0,0,0); + + setLineWidth(arrowline); + setColor(255,0,0);// button cancel + drawRect (distBord, (Hpalette-disthaut), largbuton, hautbuton);run("Select None"); + setColor(0,255,0);// button apply + drawRect ((Lpalette-distBord-largbuton), (Hpalette-disthaut), largbuton, hautbuton);run("Select None"); + setColor(100,0,133); + fillRect (distBord+1, Hpalette-disthaut+1, largbuton-2, hautbuton-2); + fillRect (Lpalette-distBord-largbuton+1, Hpalette-disthaut+1, largbuton-2, hautbuton-2); + setFont("SansSerif", 12,"bold"); + setColor(255,60,60); + drawString("Cancel",(distBord+5),(Hpalette-10));run("Select None"); + setColor(0,255,0); + drawString("Apply",(Lpalette-distBord-largbuton+7),(Hpalette-10));run("Select None"); + } + + makeRectangle ( ((Lpalette-Lprev)/2+1), ((Lpalette-Lprev)/2+1), Lprev-2, Hprev-2); + run("Paste");run("Select None"); + if (arrowconcav > (arrowlenght+1)) arrowconcav=(arrowlenght+1); + if (tailwidth > arrowwidth) tailwidth = (arrowwidth-3); + if (arrowwidth < 0) arrowwidth=0; + if (arrowlenght < 0) arrowwidth=0; + if (arrowconcav < 0) arrowconcav=0; + if (tailwidth < 0) tailwidth=0; + if (taillenght < 0) taillenght=0; + builtarrow (arrowline,xpreview,ypreview,arrowwidth,arrowlenght,tailorient,arrowconcav,tailwidth,taillenght,getRGBcolor (tailcolor)); + + setColor(32,0,93); //setColor(150,0,93); + fillRect(0, (Hpalette-140), Lpalette,103); + + adjustBoxes(box1x,box1y,1,0,0,0); + adjustBoxes(box2x,box2y,1,0,0,0); + adjustBoxes(box3x,box3y,1,0,0,0); + adjustBoxes(box4x,box4y,1,0,0,0); + adjustBoxes(box5x,box5y,1,0,0,0); + + setColor(255,255,255); + setFont("SansSerif", 12); + drawString("Arrow Lenght:"+arrowlenght, 2,(Hpalette-120)); + drawString("Arrow Width:"+arrowwidth, 130,(Hpalette-120)); + + drawString("Arrowhead Filling Level:"+arrowconcav,2,(Hpalette-120+20)); + drawString("Tail Lenght:"+taillenght,2,(Hpalette-120+40)); + drawString("Tail Width:"+tailwidth,125,(Hpalette-120+40)); + drawString("Arrow Color:"+tailcolor,2,(Hpalette-120+60)); + + drawString("Arrow Orientation:"+tailorient,2,(Hpalette-120+80)); + setBatchMode("exit and display"); +} + +function RestoreInitColor () { + if (previousColor !="") { + getSelectionColors (previousColor); + run("Colors...", "selection=["+getColorName(Red,Green,Blue)+"]"); + showMessage ("Previous selection color \"" + getColorName(Red,Green,Blue) + "\" has been restored"); + } else {showMessage ("Selection Color has not been changed");} +} + +function GetCurentSelectionColor () { + color= call("ij.gui.Roi.getColor"); + getSelectionColors (color); + showMessage ("Curent selection color: "+ getColorName(Red,Green,Blue) + " \(Red="+Red+" Green="+Green+" Blue="+Blue+"\)"); +} + +// decodes a color in the form "java.awt.Color[r=255,g=255,b=0]" +function getSelectionColors (color) { + Red = substring(color, (indexOf(color, "r=")+2), (indexOf(color, "g=")-1)); + Green= substring(color, (indexOf(color, "g=")+2), (indexOf(color, "b=")-1)); + Blue= substring(color, (indexOf(color, "b=")+2), indexOf(color, "]")); +} + +function getColorName(r,g,b) { + if (r=="255" && g=="255" && b=="0") ColorName ="yellow"; + if (r=="255" && g=="0" && b=="0") ColorName ="red"; + if (r=="0" && g=="255" && b=="0") ColorName ="green"; + if (r=="0" && g=="0" && b=="255") ColorName ="blue"; + if (r=="255" && g=="0" && b=="255") ColorName ="magenta"; + if (r=="0" && g=="255" && b=="255") ColorName ="cyan"; + if (r=="255" && g=="200" && b=="0") ColorName ="orange"; + if (r=="0" && g=="0" && b=="0") ColorName ="black"; + if (r=="255" && g=="255" && b=="255") ColorName ="white"; + return ColorName; +} + +function abortProcess () {setKeyDown("Esc");} + +function about1() { + about=""; + about=about+" -- Image, Stack and Timelapse Arrow Labelling --"; + about=about+"\n* Description:"; + about=about+"\nThis toolset allows to draw, with an interactive graphic interface, \"histological\" arrows on images,\nstacks and movies."; + about=about+"\n* Notice:"; + about=about+"\n - The \"Movie and Stack Menu\" regroups the functions specific to movies and stack:"; + about=about+"\n - \"Open a Movie as Stack\" displays a dialog box to open a movie, using QuickTime resources,\n which will be opened as a stack of images."; + about=about+"\n - \"Save a Stack as an \".avi\" Movie\" records a stack as an avi uncompressed movie into the same\n repertory than the original one, with an incremented suffix number."; + about=about+"\n - \"Download\/Open Demo Timelapse Movie\" and \"Download\/Open Demo Timelapse Movie Arrowed\"\n give respectively a training movie and an example of arrowed movie. Initial movie, obtained by\n LSM microscopy, was provided by Tim Chico (*)."; + about=about+"\n - Set the stack/movie animation speed using \"Animation Speed Setting\"."; + about=about+"\n - Check for the arrow effect on a stack using \"Animate the Stack\". "; + about=about+"\n - The \"Arrow Drawing Menu\" regroups the arrow drawing utilities:"; + about=about+"\n - \"Set Drawing Arrow(s) Location\" is the first step to draw arrows: move, staying clicked, onto the\n image, until the cursor points the correct target of the arrow. Unclick, and adjust settings using the\n menu and the graphic interface which then will appear."; + about=about+"\n - \"Draw Arrow(s) at the Current Location\" draws a arrow at the current location when the user\n graphic interface has been canceled, or the cursor erased for any reason."; + about=about+"\n - \"Restore the Last Cursor Location\" restores a visual (non active) cursor at the last location."; + about=about+"\n - \"New User Graphic Interface\" is the default interface to set the arrow characteristics."; + about=about+"\n - \"Standard User Interface\" allows to use the dialog box interface of the \"ArrowMakerTool\" instead\n of the graphical interface."; + about=about+"\n - \"Display Coordinates\" gives the coordinates x, y of the current location (same as displayed in the\n status bar)."; + about=about+"\n - \"Change the Color of a Arrow\" allows to change the color of a draw arrow, by clicking on it."; + about=about+"\n - \"Undo the Last Arrow\" erases the last drawn arrow (only for single image or slice)."; + about=about+"\n - The \"Cursor Color Menu Menu\" allows to manage the cursor color to make easier the visual location\n of the target area, depending of the background color of the image."; + about=about+"\n - Click on the \"Abort Process\" ImageJ tool bar icon to cancel too long processes."; + about=about+"\n - Click on the \"On Line Documentation\" ImageJ tool bar icon for more details."; about=about+"\n - Click on the \"Version and Update Infos\" ImageJ tool bar icon to look for new beta versions."; + about=about+"\n---------------------------------------------------------------------------------------------"; + about=about+"\nThis toolset based on the \"ArrowMakerTool\" was adapted to stacks and movies at the request of Tim Chico,\nPI in vascular biology at the University of Sheffield, UK. Tim Chico also provided the downloadable movie\nexample."; + about=about + "\n--------------------------------------------------------------------------------------------"; + about=about +"\nAuthor: Gilles Carpentier"+"\nFaculte des Sciences et Technologies"+"\nUniversite Paris 12 Val de Marne, France."; + + showMessage(about); + //print (about); +} + +function doc () { + if (File.openUrlAsString(urllist) == "") exit("You need an internet access to run this function."); + showMessageWithCancel ("A notice is avaible on line. Open it with your default web browser?"); + run("URL...", "url=["+onlinedoclink +"]"); +} + + +// --- End of code of the macro project ---// +// ----------------------------------// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// -------------------*** Additionnal code for on line update resources ***----------------------------- + +//Developer info +//Kind:Toolset +//Title:"Image, Stack and Timelapse Arrow Labelling" +//Version:1.0 +//Date: 28 April 2007 +//Origin:NIH +//End info + +function VersionInfos () { + // variables for on line update resources + beginsign="//Developer info";endsign="//End info"; + kind="toolsets/"; + urlrep="http://image.bio.methods.free.fr/ij/ijmacro/zebrafish/"; + name="Image, Stack and Timelapse Arrow Labelling.txt"; + namedev="Image, Stack and Timelapse Arrow Labelling-dev.txt"; + favoritefoldername= "Image.Bio.Methods"; + + version=versionMessage(); + if (indexOf(version, "install it?" ) > 0 ) { + macrotext=getdistantmacro (namedev,urlrep);macrolocal=""; + macropath=getDirectory("macros")+kind+namedev; + if (File.exists(macropath)) {macrolocal=File.openAsString(macropath);} + if (macrotext != macrolocal) { + //perfom the installation + Dialog.create("New version installation option"); + Dialog.addMessage(version); + Dialog.addCheckbox("Install a Plugin Shortcut?", 0); + Dialog.addMessage("(This option provides a shortcut in the plugins menu of ImageJ, making easier\nthe next use of the new installed version)."); + Dialog.show(); + plugin= Dialog.getCheckbox(); + f= File.open(macropath); + print (f,macrotext); + File.close(f); + if (plugin ==1) {InstallPluginsStarter(namedev);} + message="The installation of the "+giveDevInfo (macrotext,1)+ " "+ giveDevInfo (macrotext,2)+ "is completed."; + message=message+ " Do you want to run it?"; + showMessageWithCancel(message); + run("Install...", "install=["+macropath+"]"); + } + } else {showMessage (version); // comment without installation available} +} + +function versionMessage() { + + version=""; + if (getDirectory("startup") == 0) exit ("Unable to find the startup directory, something wrong in the ImageJ folder"); + if (getDirectory("macros") == 0) exit ("Unable to find the macros directory, something wrong in the ImageJ folder"); + MacroPath=getDirectory("macros");thismacropath=MacroPath+kind+name; + if (! File.exists(thismacropath)) exit ("This macro has to be recorded under the name of \"" +name+"\"\ninto the \"macros/"+kind+"\" folder of ImageJ."); + + macrotext=File.openAsString(thismacropath); + macrotextdistant=getdistantmacro (namedev,urlrep); + + version="";macrolocal=""; + version=version + "\n \nThis version of the " + giveDevInfo (macrotext,1) + " " + giveDevInfo (macrotext,2); + version=version + "is provided by the " + giveDevInfo (macrotext,5)+ " web site."; + version=version + "\nVersion number: " + giveDevInfo (macrotext,3)+ " - " + giveDevInfo (macrotext,4) +"."; + + if (macrotextdistant !="" ) { + new=giveDevInfo (macrotextdistant,3);old=giveDevInfo (macrotext,3); + if (new > old) { + macropath=getDirectory("macros")+kind+namedev; + if (File.exists(macropath)) {macrolocal=File.openAsString(macropath);} + if (macrotextdistant != macrolocal) { + update="\n \nA new beta version "+new+ " is available on the " +giveDevInfo (macrotextdistant,5)+ " web site: "; + update=update+ "\n \nDo you want to install it?"; + } else { + update ="\n \nThe new "+new+" beta version called \"" +namedev+ "\" provided by \nthe "+giveDevInfo (macrotextdistant,5) +" web site has already be installed"; + update = update+ " in the \"" +kind+ "\" repertory \nof ImageJ."; + } + } else { + update="No new Beta version available."; + } + version=version +"\n" + update ; + } + return version; +} + +function giveDevInfo (text,n) { + lines=split(text,"\n"); + if ( (indexOf(text, beginsign)<0) || (indexOf(text, endsign)<0) ) exit ("Not upgradable macro code."); + for (i=0; lines[i] != endsign; i ++) {} + for (j=i; lines[j] != beginsign; j --) {} + infotext=newArray(i-j-1); + for (i=0; i < infotext.length; i ++) {infotext[i]=lines[i+j+1];} + info=infotext[n-1]; signature=":"; + cut = indexOf(info, signature); + info = substring(info,(cut+lengthOf(signature)),lengthOf(info)); + return info; +} + +// Function giving the content of a distant macro (name) located at the distant repertory (urlrep). +function getdistantmacro (name,urlrep) { + macrotextnih=""; + if (File.openUrlAsString("http://rsb.info.nih.gov/ij/macros/Arrays.txt") != "") { + distantmacrolink = urlrep + name; + if (indexOf(distantmacrolink, " ") > -1) { + while (indexOf(distantmacrolink, " ") > -1) { + distantmacrolink=substring(distantmacrolink, 0, (indexOf(distantmacrolink, " ")))+"%20"+substring(distantmacrolink, (indexOf(distantmacrolink, " ")+1),lengthOf(distantmacrolink) ); + } + } + showStatus("Internet link..."); + macrotextnih =File.openUrlAsString(distantmacrolink); + showStatus(""); + } else { showMessage ("No internet connection to looks for beta version.");} + return macrotextnih; +} + +function InstallPluginsStarter(macroname) { + // from MacroPluginShortcutsTool.txt + codestarter = "run\(\"Install...\", \"install=[\"+getDirectory(\"macros\")+\""+kind+ macroname + "\]\"\);"; + if (getDirectory("plugins") == "") exit ("Unable to find the Plugins directory; something wrong in the ImageJ folder."); + if (endsWith(macroname, ".txt") || endsWith(macroname, ".ijm")) pluginname = substring(macroname, 0, (lengthOf(macroname)-4)); + StarterDir = getDirectory("plugins")+favoritefoldername+File.separator; + File.makeDirectory(StarterDir); + if (!File.exists(StarterDir)) exit ("Unable to create "+favoritefoldername+" Macros directory, something wrong in the ImageJ folder."); + starterplugin = StarterDir + pluginname +"_ .ijm"; + f= File.open(StarterDir + pluginname +"_ .ijm"); + print (f,codestarter); + File.close(f); + showMessage ("The plugin shortcut \"" +pluginname+ "\" will be available after\nImageJ restarting, in the \"Plugins->" + favoritefoldername + "\" menu."); +} + +// *** End of additionnal code for on line update ressources *** + + + diff --git a/MT2-project-ImageProcessing/macros/toolsets/Built-in Tools.ijm b/MT2-project-ImageProcessing/macros/toolsets/Built-in Tools.ijm new file mode 100644 index 0000000..01a40b1 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/toolsets/Built-in Tools.ijm @@ -0,0 +1,16 @@ +// This toolset installs 12 custom tools that are built into ImageJ + + macro "Command Finder Built-in Tool" {} + macro "Developer Menu Built-in Tool" {} + macro "Brush Built-in Tool" {} + macro "Flood Filler Built-in Tool" {} + macro "Spray Can Built-in Tool" {} + macro "Arrow Built-in Tool" {} + macro "Pixel Inspector Built-in Tool" {} + macro "Pencil Built-in Tool" {} + macro "Overlay Brush Built-in Tool" {} + macro "Selection Rotator Built-in Tool" {} + macro "Stacks Menu Built-in Tool" {} + macro "LUT Menu Built-in Tool" {} + + diff --git a/MT2-project-ImageProcessing/macros/toolsets/Drawing Tools.ijm b/MT2-project-ImageProcessing/macros/toolsets/Drawing Tools.ijm new file mode 100644 index 0000000..8e7f8fc --- /dev/null +++ b/MT2-project-ImageProcessing/macros/toolsets/Drawing Tools.ijm @@ -0,0 +1,10 @@ +// Drawing tools +// This toolset installs IJ's built-in drawing tools. It supersedes the +// previous macro-based toolset and requires ImageJ 1.47a or later. + +macro "Arrow Built-in Tool" {} +macro "Brush Built-in Tool" {} +macro "Pencil Built-in Tool" {} +macro "Flood Filler Built-in Tool" {} +macro "Spray Can Built-in Tool" {} +macro "Overlay Brush Built-in Tool" {} diff --git a/MT2-project-ImageProcessing/macros/toolsets/Magic Montage.ijm b/MT2-project-ImageProcessing/macros/toolsets/Magic Montage.ijm new file mode 100644 index 0000000..ecb75eb --- /dev/null +++ b/MT2-project-ImageProcessing/macros/toolsets/Magic Montage.ijm @@ -0,0 +1,405 @@ +//--version--1.6 +// 1.6 adds the '?' button that points to the wiki page +// panel labels are now drawn on an overlay +// added overlay commands and copy to system clipboard to the rightclick menu +// Montage tools for easy montage manipulation +// jerome.mutterer at ibmp.fr + +var v=versionCheck(); +function versionCheck() { + requires("1.41f"); + return 1; +} + +macro "Auto Montage Action Tool - C00fF0077C0f0F9977Cf00F9077C888F0977" { + + setBatchMode(true); + b=bitDepth; + if ((b!=24)&&(nSlices==1)) { exit("Stack, Composite, or RGB image required.");} + if ((b==24)&&(nSlices==1)) { run("Make Composite"); b=8;} + Stack.getDimensions(width, height, channels, slices, frames); + getVoxelSize(xp,yp,zp,unit); + if (channels==1) { channels = channels* frames*slices; Stack.setDimensions(channels,1,1); } + id=getImageID; + t=getTitle; + if (b!=24) { + newImage("tempmont", "RGB", width, height,channels); + id2=getImageID; + for (i=1;i<=channels;i++) { + setPasteMode("copy"); + selectImage(id); + Stack.setChannel(i); + getLut(r,g,b); + run("Duplicate...", "title=temp"+i); + setLut(r,g,b); + run("RGB Color"); + run("Copy"); + selectImage(id2); + setSlice(i); + run("Paste"); + } + } + run("Make Montage...", "scale=1 border=0"); + rename(getTitle+" of "+t); + setVoxelSize(xp,yp,zp,unit); + setBatchMode(false); +} + +macro "Select Panels Tool - Cf00R0077R9077C888R9977R0977"{ + run("Select None"); + setPasteMode("copy"); + w = getWidth; + h = getHeight; + getCursorLoc(x, y, z, flags); + id=getImageID; + t=getTitle; + selectImage(id); + xn = info("xMontage"); + yn = info("yMontage"); + if ((xn==0)||(yn==0)) {exit;} + xc = floor(x/(w/xn)); + yc = floor(y/(h/yn)); + makeRectangle(xc*(w/xn),yc*(h/yn),(w/xn),(h/yn)); + xstart = x; ystart = y; + x2=x; y2=y; + x2c=xc;y2c=yc; + while (flags&16 !=0) { + getCursorLoc(x, y, z, flags); + if (x!=x2 || y!=y2) { + x2c = floor(x/(w/xn)); + y2c = floor(y/(h/yn)); + makeRectangle(xc*(w/xn),yc*(h/yn),(w/xn)*(x2c-xc+1),(h/yn)*(y2c-yc+1)); + x2=x; y2=y; + wait(10); + } + } + setPasteMode("add"); +} + +macro "Extract Selected Panels"{ + t=getTitle; + xn = info("xMontage"); + yn = info("yMontage"); + pw = getWidth/xn; + ph = getHeight/yn; + run("Duplicate...", "title=[Extract of "+t+"]"); + setMetadata("Info","xMontage="+getWidth/pw+"\nyMontage="+getHeight/ph+"\n"); +} + + +macro "Montage Shuffler Tool - C888R0077R9977C03fR0977R9077"{ + id=getImageID; + run("Select None"); + setPasteMode("copy"); + w = getWidth; + h = getHeight; + getCursorLoc(x, y, z, flags); + xn = info("xMontage"); + yn = info("yMontage"); + if ((xn==0)||(yn==0)) exit; + xstart = x; ystart = y; + x2=x; y2=y; + while (flags&16 !=0) { + getCursorLoc(x, y, z, flags); + if (x!=x2 || y!=y2) spring(xstart, ystart, x, y); + x2=x; y2=y; + wait(10); + } + if (x!=xstart || y!=ystart) { + xext=0; + yext=0; + if (x>w) xext=1; + if (y>h) yext=1; + if ((xext>0)||(yext>0)) { + run("Canvas Size...", "width="+w+xext*(w/xn)+" height="+h+yext*(h/yn)+" position=Top-Left zero"); + setMetadata("Info","xMontage="+(parseInt(xn)+parseInt(xext))+"\nyMontage="+(parseInt(yn)+parseInt(yext))+"\n"); + exit; + } + sc = floor(xstart/(w/xn)); + tc = floor(x/(w/xn)); + sr = floor(ystart/(h/yn)); + tr = floor(y/(h/yn)); + swap(sc,sr,tc,tr); + + } +} + + +var str="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +var lcas=false; +var antialiasedLabels = true; +var n=0; +var xoffset=0.05; +var yoffset=0.05; +var pos="Clicked quadrant"; + +macro "Annot Tool - C000 T2709A T8709B T1f09C T8f09D" { + xn = info("xMontage"); + yn = info("yMontage"); + + getCursorLoc(x, y, z, flags); + iw = getWidth/xn; + ih = getHeight/yn; + + co = floor(x/iw); + li = floor(y/ih); + + fontsize = ih/10; + if (fontsize<12) fontsize=12; + marque = substring(str,n,n+1); + if (lcas==1) marque= toLowerCase(marque); + opt=""; + + if (pos == "Clicked quadrant") { + xoffset=0.05; yoffset=0.05; + if (x>((co+0.5)*iw)) xoffset=0.90; + if (y<((li+0.5)*ih)) yoffset=0.85; + } + + if (antialiasedLabels==true) opt=opt+"antialiased"; + setFont("SanSerif",fontsize, opt); + fg = getValue("rgb.foreground"); + makeText(marque ,co*iw+xoffset*iw,(li+1)*ih-yoffset*ih-getValue("font.height")); + Roi.setStrokeColor(fg&0xff0000>>16,fg&0x00ff00>>8,fg&0x0000ff); + Overlay.addSelection("",0); + run("Select None"); + n++; if (n>lengthOf(str)) n=0; +} + +macro "Annot Tool Options" { + if (nImages>0) setupUndo; + Dialog.create("Annotation - Options"); + Dialog.addString("Labels",str); + Dialog.addCheckbox("Lowercase labels",lcas); + Dialog.addCheckbox("Reset label counter",true); + Dialog.addCheckbox("Antialiased",true); + Dialog.addChoice("Position",newArray("Clicked quadrant","Lower left","Lower right","Upper right","Upper left"),pos); + Dialog.show; + str = Dialog.getString; + lcas = Dialog.getCheckbox; + resetCounter = Dialog.getCheckbox; + if (resetCounter==true) n=0; + antialiasedLabels = Dialog.getCheckbox; + pos=Dialog.getChoice(); + if (pos=="Lower left") {xoffset=0.05; yoffset=0.05;} + else if (pos=="Lower right") {xoffset=0.90; yoffset=0.05;} + else if (pos=="Upper left") {xoffset=0.05; yoffset=0.85;} + else if (pos=="Upper right") {xoffset=0.90; yoffset=0.85;} + +} + + + + +macro "Montage Sync Tool - C000L48d8L838d" { + w=getWidth; + h= getHeight; + getCursorLoc(x,y,z,flags); + xn = info("xMontage"); + yn = info("yMontage"); + if ((xn==0)||(yn==0)) {run("Set Montage Layout"); exit;} + xc = floor(x/(w/xn)); + yc = floor(y/(h/yn)); + x0 = x-xc*w/xn; + y0 = y-yc*h/yn; + np = 1*xn*yn; + xp =newArray(np); + yp =newArray(np); + for (i=0;i1){ + xa[0]=x0; + ya[0]=y0; + xa[xa.length-1]=x1; + ya[ya.length-1]=y1; + } + makeSelection("freeline",xa,ya); +} + +macro "bar Action Tool - C000L060bLe6ebL09e9L08e8"{ + doCommand("Scale Bar..."); +} + +macro "Magic Montage Help Action Tool - C000T3f15?"{ + run("URL...", "url=http://imagejdocu.tudor.lu/doku.php?id=howto:working:work_with_magic_montage"); +} + + +macro "Add Panel to Manager [F1]" { + roiManager("Add"); + setOption("Show All",true); +} + +macro "Selected panels to stack [F2]" { + id=getImageID; + t=getTitle; + selectImage(id); + roiManager("select",0); + getSelectionBounds(x,y,sw,sh); + setBatchMode(true); + newImage("Extracted Panels of "+t, "RGB", sw,sh,roiManager("count")); + id2=getImageID; + setPasteMode("copy"); + for (i=0;iffp) { + run("Size...", "width="+sw+" height="+sw/ffc+" constrain interpolate"); + run("Canvas Size...", "width="+sw+" height="+sh+" position=Center zero"); + } else { + run("Size...", "width="+sh*ffc+" height="+sh+" constrain interpolate"); + run("Canvas Size...", "width="+sw+" height="+sh+" position=Center zero"); + } + run("Copy"); + close; + selectImage(id); + setBatchMode(false); + setPasteMode("Copy"); + run("Paste"); +} + +macro "Fill Panel with Clipboard content [F5]" { + + getSelectionBounds(x,y,sw,sh); + id=getImageID; + setBatchMode(true); + ffp=sw/sh; + run("Internal Clipboard"); + run("RGB Color"); + ffc=getWidth/getHeight; + if (ffc>ffp) { + run("Size...", "width="+sw*ffc+" height="+sh+" constrain interpolate"); + run("Canvas Size...", "width="+sw+" height="+sh+" position=Center zero"); + } else { + run("Size...", "width="+sw+" height="+sh/ffc+" constrain interpolate"); + run("Canvas Size...", "width="+sw+" height="+sh+" position=Center zero"); + } + run("Copy"); + close; + selectImage(id); + setBatchMode(false); + setPasteMode("Copy"); + run("Paste"); + +} + +macro "Set Montage Layout [F12]" { + Dialog.create("Set Montage Layout"); + Dialog.addNumber("Width:", 2); + Dialog.addNumber("Height:", 2); + Dialog.show; + mw = Dialog.getNumber; + mh = Dialog.getNumber; + setMetadata("Info","xMontage="+mw+"\nyMontage="+mh+"\n"); +} + +var pmCmds = newMenu("Popup Menu", + newArray("Copy", "Paste","-", + "Brightness/Contrast...", "-", + "Extract Selected Panels","-", + "Add Panel to Manager [F1]", "Selected panels to stack [F2]","-","Crop Montage [F3]","-", + "Fit Clipboard content into panel [F4]","Fill Panel with Clipboard content [F5]","-", + "Set Montage Layout [F12]","-", + "Hide Overlay","Show Overlay", "Remove Overlay","-", + "Copy to System")); + +macro "Popup Menu" { + cmd = getArgument; + run(cmd); +} diff --git a/MT2-project-ImageProcessing/macros/toolsets/Scale Bar Tools for Microscopes.txt b/MT2-project-ImageProcessing/macros/toolsets/Scale Bar Tools for Microscopes.txt new file mode 100644 index 0000000..5d35ee9 --- /dev/null +++ b/MT2-project-ImageProcessing/macros/toolsets/Scale Bar Tools for Microscopes.txt @@ -0,0 +1,1001 @@ +///////////////////////////////////////////// +// Scale Bar Tools for Microscope Collection +//////////////////////////////////////////// +// Author: Gilles Carpentier +// Faculte des Sciences et Technologies, +// Universite Paris 12 Val de Marne, France. +// May 2009 + +// documentation at the http://image.bio.methods.free.fr/ImageJ/?Scale-Bar-Tools-for-Microscopes.html +// Image sample, http://rsb.info.nih.gov/ij/macros/images/myotube.tif.zip +// The RGB image sample, is a composite of three microscopic images of the same field in fluorescence mode. +// The example contains a triple lableling of a differentiated mouse myogenic cell line. + +// Cell culture and immunochemistry; Juliette Peltzer. +// Images from the courtesy of Dr Angelica Keller. Scion CFW-1310M CCD camera mounted on an Olympus BH-2 with a +// 0.3x C-mount optical adaptor. +// For more details about the cell line, contact Dr Angelica Keller at keller@univ-paris12.fr +// Faculte des Sciences et Technologies, +// Universite Paris 12 Val de Marne, France. + +// global variables +// Check the net +var errorNetMessage ="Error: "; +var urllist = "http://image.bio.methods.free.fr/ij/ijupdatetest/ListOfMacros.txt";// to check the internet access +// Array containing the calibration data specific to each acquisition device: +var microscope1=newArray(""); +// variable for demo image +var demoimagelink = "http://rsb.info.nih.gov/ij/macros/images/myotube.tif.zip"; +var demoimagelink2 = "http://image.bio.methods.free.fr/ij/ijmacro/scalebar/myotube-sc.tif"; +var demoimagename = "myotube.tif"; +var onlinedoclink = "http://image.bio.methods.free.fr/ImageJ/?Scale-Bar-Tools-for-Microscopes.html"; +var demoimagename2 = "myotube-sc.tif"; +// variable for the objectives data +var objectdata = newArray(16); +var objective = newArray("no choice","Unchanged","Uncalibrated","","","","","","Other"); // list of choice deduced from objectives data +var obj="no choice",reponseUser,model=""; +var nomdimage ="", imageid,imageCalibid,imagex,imagey,blackmarge=0,nblinecom=3,hightnblinecom=15,hightcom=24,TimeString; +var userchoices = newArray(14),pixobj,calibration ="",textcalib="",otherobjecvalue,otherobjective,unit,pixelWidth, userLenght=0,lastCustuserbar=0; +var microscopeCollection="Microscope Profiles Collection",editMode=0; +var pixdist=1,knowndist=0.2, scaleunit="",defaultbar=0,pixobj=1,zoom=1,otherpixdist,otherknowndistance,othermodel="",autosave=0,spacerset=1,metaset=1,scalebarset=1,infoset=1,scaleset=1,noscaleLine=0; +var um = getInfo("micrometer.abbreviation"); // µm + +var xx = requires143d (); // check version at install time +function requires143d() {requires("1.43d"); return 0;} + +macro "Unused Tool- 1" {} // Space (empty tool icon) between native ImageJ tools and tools of this toolset. + +macro "Scale Bar Action Tool - C111D4bD4cD6bCfffD00D08D09D0aD0bD0cD0dD0eD0fD10D18D19D1aD1bD1cD1dD1eD1fD20D21D22D23D25D26D27D28D29D2aD2bD2cD2dD2eD2fD30D31D32D33D35D36D37D38D39D3aD3bD3cD3dD3eD3fD40D41D42D43D45D46D47D48D4eD4fD50D51D52D53D55D56D57D58D59D5aD5dD5eD5fD60D61D62D63D65D66D67D68D6dD6eD6fD70D71D72D73D75D76D77D78D79D7aD7bD7dD7eD7fD80D81D82D83D85D86D87D88D8dD8eD8fD90D91D92D93D95D96D97D98D9aD9bD9cD9dD9eD9fDa0Da1Da2Da3Da5Da6Da7Da8DadDaeDafDb0Db1Db2Db3Db5Db6Db7Db8DbbDbcDbdDbeDbfDc0Dc1Dc2Dc3Dc5Dc6Dc7Dc8DcdDceDcfDd0Dd1Dd2Dd3Dd5Dd6Dd7Dd8Dd9DdaDdbDdcDddDdeDdfDe0De8De9DeaDebDecDedDeeDefDf0Df8Df9DfaDfbDfcDfdDfeDffC222D8bDabC03fD02D03D04D05D06D12D13D14D15D16D24D34D44D54D64D74D84D94Da4Db4Dc4Dd4De4Df2Df3Df4Df5Df6C89fD01D07D11D17De2De3De5De6Df1Df7C222D4aD6aD8aDaaC555D99Db9C999D5cC444Da9C999D6cD8cDacDccCbcfDe1De7C333D49D69D89DcaDcbC666D4dDc9CfffD7cDbaCbbbD5b"{ + setScaleBarre (); +} + +macro "Extract and Edit Image Action Tool - C01538R01fdR23" { + extractAndEditImage (); +} + +var availableMicroProfiles = InstalledProfiles(); + +// installed microscope profiles menu tool +var aCmds = newMenu("Available Microscope Profiles Menu Tool",availableMicroProfiles); +macro "Available Microscope Profiles Menu Tool - CfffD00D01D02D03D04D05D06D07D08D09D0aD0bD0cD0dD0eD0fD10D11D12D13D14D15D16D17D18D19D1aD1bD1cD1dD1eD1fD20D21D22D23D24D25D26D27D28D29D2aD2bD2cD2dD2eD30D31D32D33D34D35D36D37D38D39D3aD3bD3cD3dD40D41D42D43D44D45D46D4bD4cD4dD50D51D52D53D54D55D5cD5dD60D61D62D63D64D67D68D69D70D71D72D73D77D78D79D89D8cD8dD99D9cDa0Da1Da2Da3Da4Da5Da6Da7Da8Da9DacDb0Db1Db2Db3Db4Db5Db6Db7Db8Db9DbcDbdDc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9DcbDccDcdDceDd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9DdaDdbDdcDddDdeDdfDe0De1De2De3De4De5De6De7De8De9DeaDebDecDedDeeDefDf0Df1Df2Df3Df4Df5Df6Df7Df8Df9DfaDfbDfcDfdDfeDffC38fD2fD3eD3fD48D49D4aD4eD4fD56D57D58D59D5aD5bD5eD5fD66D6aD6bD6cD6dD6fD75D76D7aD7bD7cD7dD7fD80D81D82D83D84D85D86D87D88D8fD90D98D9fC25fD74C24fD6eD7eD8eD91D92D96D9aD9eDaaDaeC37fD47D65D8aD8bD93D94D95D97D9bD9dDabDadDafDbbDbfC32fDbaDbeDca"{ + cmd = getArgument(); + if (cmd!="-" && cmd !="No microscope profile found" && cmd != "Record this tool into the \"toolsets\" folder, to use this menu tool." ) { + var microscope1=GetArrayFromProfile(cmd); + } +} + +var mCmds = newMenu("Microscope Profiles Manager Menu Tool",newArray("Get Current Microscope Profile Infos","Get Meta-Label","Get Meta-Infos","-","Create a New Microscope Profile","Edit & Modify a Microscope Profile","-","Erase a Microscope Profile","Restore a Microscope Profile from a Scaled Image","-","Update the Microscope Profiles Menu")); +macro "Microscope Profiles Manager Menu Tool - CcccD55D57D5aD66D6aD7bD81D85D8aD93Da6DadDbdDc6Dd6C333Db1Dc2Dd3CeeeD34D35D4cD69D77Dc9Dd9CdddD32D33D42D43D47D52D53D59D63D64D73D7aD87D89D97D99D9bDa9Db9DcaDd8CbbbD58D75D7dD8bD96D9dDa4CfffD00D01D02D03D04D05D06D07D08D09D0aD0bD0cD0dD0eD0fD10D11D12D13D14D15D16D17D18D19D1aD1bD1cD1dD1eD1fD20D21D22D23D24D25D26D27D28D29D2aD2bD2cD2dD2eD2fD30D3bD3cD3dD3eD40D4eD50D5eD60D6eD70D7eD80D8eD90D9eDa0DaeDb0DbeDc0Dc1DceDd0Dd1Dd2De0De1De2De3De4De5De6De7De8De9DeaDebDecDedDeeDefDf0Df1Df2Df3Df4Df5Df6Df7Df8Df9DfaDfbDfcDfdDfeDffCdddD31D41D44D4aD4bD51D54D5bD62D67D72D74D83D84D8dDa7Db2Db7Dc7DcbDcdDd7CaaaD95Db5CfffD38D39D3aD6cD7cD8cDb3DbcDccDdbDdcDddDdeCbbbD45D5dD68D6bD78D88D92D9aDaaDabDb4Db8DbbDc8CcccD46D48D4dD56D61D6dD71D76D82D86D94Da1Da2Da3DbaDc3Dc4Dd4C777D3fD4fD5fD6fD7fD8fD9fDafDbfDcfDdfCeeeD36D37D49D5cD79D9cDacDdaCaaaD65D91D98Da5Da8Db6Dc5Dd5"{ + cmd = getArgument(); + if (cmd!="-" && cmd == "Get Current Microscope Profile Infos") { + infos=testGetArrayFromProfile(); + if (infos != "" ) {print("\\Clear");print(infos);} else {exit ("No microscope profile selected");} + } + if (cmd!="-" && cmd == "Create a New Microscope Profile") editMicProfile ("new"); + if (cmd!="-" && cmd == "Edit & Modify a Microscope Profile") editMicProfile ("edit"); + if (cmd!="-" && cmd == "Restore a Microscope Profile from a Scaled Image") testSaveaProfile (); + if (cmd!="-" && cmd == "Erase a Microscope Profile") {editMode=1; rmProfFromProfileCat (); } + if (cmd!="-" && cmd == "Get Meta-Label") { + metafromima=getMetaLabel (); + if (metafromima != "") {print("\\Clear");print ("Metadata of the Image Title\:");print (getMetaLabel ());} + if (metafromima == "") showMessage ("No metadata label available in this image"); + } + if (cmd!="-" && cmd == "Get Meta-Infos") { + metafromima=getMetaInfosIma (); + if (metafromima != "") {print("\\Clear");print ("Metadata Infos Concerning the Image\:");print (getMetaInfosIma ());} + metafromprof=getMetaInfosMic (); + if (metafromprof != "") {print ("Metadata Concerning the Microscope Profile\:");print (getMetaInfosMic ());} + if (metafromima == "" && metafromima =="") showMessage ("No metadata infos available in this image"); + } + if (cmd!="-" && cmd == "Update the Microscope Profiles Menu") UpdateProfileList(); + if (cmd!="-") {if (isOpen("Log")) selectWindow ("Log");} +} + +var dCmds = newMenu("On Line Documentation & Demo Menu Tool",newArray ("Open On Line Documentation","Download Unscaled Sample Image","Download a Scaled Sample Image","-","Install a Demo Microscope Profiles Set")); +macro "On Line Documentation & Demo Menu Tool - C000D89D8dD96D9dDa5Da6Db3Db4Db5Db6DbdC06fD12D13D14D15D16D17D18D19D1aD1bD1cD1dD1eC0f3D32D33D34D35D36D37D38D39D3aD3bD3cD3dD3eD3fCeeeD80C444DbeDcfC73fD01Cfd0D42D43D44D45D46D47D48D49D4aD4bD4cD4dD4eCfffD7cD7fD8fD91D98Dc1DceDd1Dd3DdeDdfDe0De1De2De3De4De5De6De7De8De9DeaDebDecDedDeeDefDf0Df1Df2Df3Df4Df5Df6Df7Df8Df9DfaDfbDfcDfdDfeDffC222C0feD22D23D24D25D26D27D28D29D2aD2bD2cD2dD2eC888D88CfffD71D90DcbDd0Dd2Dd4Dd5Dd6DdcCf74D50CcccD9fCbbbD97Da0Dc2C000Da4Db2C06fD11D1fC0f4D31CeeeD70D75D81D84D92D93Dc0Dc8Dd7DdaDdbCf40D51D52D53D54D55D56D57D58D59D5aD5bD5cD5dD5eD5fCa7fD00Cfd0D41D4fC444D95DbaDc9C0ffD21D2fC4f6D30CfffD7bCf88D62D63D64D65D6bD6cCeeeD72D73D74DabDbbDccDd8Cf89D6dC666Da7C84fD02D03D04D05D06D07D08D09D0aD0bD0cD0dD0eC333D86D87D8aD99D9cDb9DbcCaaaD8eDa1Dc3Dc4Dc5Dc6CeddD76Cf89D61D66D6aD6eD6fC222DadDcdC48fD10Cfd4D40C4ffD20CaaaDacDcaDddCfaaD60C555Da2C73fD0fC333D9bDa3Da9Db1C999D7dCdddD7aD83Da8Dc7CbbbDb8C111D9aDb7CaaaD8bCf99D67D68D69C777D8cDaaCdeeD82D85C999DafCdddDd9C766D79C555DaeC999D78CcccD7eD94C888D9eC777DbfC666Db0Ca99D77"{ + cmd = getArgument(); + + if (cmd!="-" && cmd == "Open On Line Documentation") { + netTest (); + doc (); + } + if (cmd!="-" && cmd == "Download Unscaled Sample Image") { + OpenImageLink(demoimagelink,demoimagename,1); + } + if (cmd!="-" && cmd == "Download a Scaled Sample Image") { + OpenImageLink(demoimagelink2,demoimagename2,1); + } + if (cmd!="-" && cmd == "Install a Demo Microscope Profiles Set") instalDemoCollection (); +} + +// click right menu +// menu popup summering most used commands of the toolset (click right) +var pmCmds = newMenu("Popup Menu", newArray("Scale Bar","-","Extract and Edit Image","About \"Scale Bar Tools for Microscopes\"")); + +// click right menu, (ctrl click) +macro "Popup Menu" { + cmd = getArgument(); + if (cmd !="-" && cmd =="Scale Bar") {setScaleBarre ();} + if (cmd !="-" && cmd =="Extract and Edit Image") {extractAndEditImage ();} + if (cmd !="-" && cmd =="About \"Scale Bar Tools for Microscopes\"") {aboutTheTools ();} +} + +macro "About \"Scale Bar Tools for Microscopes\" Action Tool - C000D84Cb9fD25De7CaaaD14D2dDa0DafDecDfaCedfD49D4aD4bD4cD58D68D9bDb9DbaDbbDbcC889D2cDebCddfD52CcccD0bD22CeeeD00D03D0cD0fD10D1fD20D2fD30D40Dc0Dd0DdfDe0DefDf0Df1Df2Df3DfcDfeDffC666D07D70CdcfD34D35Dc4CbacD86D91CfefD6bD6dD7cD8cD8dD8eD9cD9dDadC97aDd3De5CedfD99CeeeD01D02D04D0dD0eD11D12D1eD21D3fDcfDd1De1De2DeeDf4DfdCfefD7dC545D94Da5CdbeDa4Da7CbabD05D50DaeCfefD7eC98aD32Da1CecfD39D3aD3bD46D48D57D67Da8Db6Db8Dc9DcaDcbDccCdcdD81C878D1bD60D65CdcfD29D36D38D47D77Db7Dc8Dd9DdaCcbcD7aDbfDc1De3C98bD16D24D75DeaCedfD56D66D73D76D83D93Da3C212D7bD88D96D97CcaeD26D3cDdbCaaaD3eD5fCfdfD59C889D15D1aD78Dc2CdcfD45Db4Db5Dc6CdddD13D31D4fDdeDedDfbC777D09D7fD85D90Df7CeceDbdCbadD18D55Db2De9Ca9aD5eDcdDceDdcC656D08D64D80D87D8bCdbfD28D2aD37Dc7Dd8CbbbD1cD42Dd2Df5CfdfD5aD5bD5cD5dD69D6aD6cD9aDa9DabDacC999D0aD41DddDf6CdddD1dD2eD9eDb0C888D06D4eD6fD9fDf9CcbdD54D71D98Dc3Ca9dD17D19Dd4De6C000D74D79D95CcafDd5Dd6De8CedfD62D72D92C889D51Db1DbeCedfD53D63Da2CdcdD6eC777D8fDf8CdcfD43D44Db3Dc5CbadD2bD33C99aD23De4C545D89Da6CcbfD27Dd7CbabD61CedfD82DaaC98aD3dCdceD4dD8a" { + aboutTheTools (); +} + +function aboutTheTools () { + requires("1.42k"); + about="------------------------ \"Scale Bar Tools for Microscopes\" --------------------------\n"; + about= about+"The \"Scale Bar Tools for Microscopes\" allows drawing of scale bars in image margins, for"; + about= about+"\n several microscopes profiles stored on the computer. It also allows calibration of images, and"; + about= about+"\n keeps set informations in metadata. The integrity of the image area is so preserved, and margin"; + about= about+"\n can be removed by a single click."; + about=about + "\n---------------------------------------------------------------------------------"; + about= about+"\nInstallation: the tools file has to be stored in the \"ImageJ\/macros\/toolset\" repertory"; + about=about + "\n---------------------------------------------------------------------------------"; + about= about+"\nShort documentation:"; + about=about+"\n"; + about= about+"\n - \"Scale Bar tool icon\": creates a scaled and calibrated image once a microscope profile has been"; + about= about+"\n choosen from the \"Available Microscope Profiles\" tool bar menu icon."; + about= about+"\n - \"Extract and Edit\" Image tool icon: creates an image with original name from a scaled image"; + about= about+"\n without margin and metadata."; + about= about+"\n - \"Available Microscope Profiles\" tool bar menu icon: choice of the appropriate microscope profile"; + about= about+"\n to use, before drawing a scale bar."; + about= about+"\n - \"Microscope Profiles Manager\" tool bar menu icon contains every functions required to create or"; + about= about+"\n modify the microscope profiles. It also contains some functions to read the \"Label\" and \"Info\""; + about= about+"\n metadata set to the scaled image (see online documentation for more details)."; + about= about+"\n - \"Online Documentation and Demo\" tool bar menu gives some internet ressources\; documentation,"; + about= about+"\n scaled and unscaled images samples and a demo set of microscope profiles for training."; + about= about+"\n - Click on the \"Version and Update Infos\" ImageJ tool bar icon to look for new versions."; + about=about + "\n---------------------------------------------------------------------------------"; + about=about +"\nAuthor : Gilles Carpentier"+"\nFaculte des Sciences et Technologies"+"\nUniversite Paris 12 Val de Marne, France."; + about=about + "\n---------------------------------------------------------------------------------\n"; + about=about +"\nThis tool is inspired from the scalling functionalities of the \"3FluoLablelingExploringTools\" available "; + about=about +"\non the ImageJ web site: http://rsb.info.nih.gov/ij/macros/tools/3FluoLablelingExploringTools.txt"; + about=about + "\n---------------------------------------------------------------------------------\n"; + + about=about+ testGetArrayFromProfile(); + showMessage(about); + // from PrintToTextWindow macro available at the http://rsbweb.nih.gov/ij/macros/PrintToTextWindow.txt + // author: Wayne Rasband + title1 = "Infos for the \"Scale Bar Tools for Microscopes\""; + title2 = "["+title1+"]"; + f = title2; + if (isOpen(title1)) { + print(f, "\\Update:"); // clears the window + print(f, about); + selectWindow (title1); + } else { + run("New... ", "name="+title2+" type=[Text File] width=80 height=16"); + print(f, about); + } +} + +macro "Version and Update Infos Action Tool - CcccD5fD6fD7fD8fD9fC78bD17D19D2aD33D37D3bD42D4cD75D95DceDd5Dd9De6Df7Df9CddeDa3C36bD27D28D3aD57D58D59D66D76D77D86D87Da7Db8Dd6De8De9CeeeD00D01D02D04D06D07D08D09D0bD0dD0fD10D11D12D14D1bD1dD1fD20D21D22D2dD30D31D32D40D46D47D48D49D50D5bD60D70D71D72D74D7dD80D81D82D84D8dD90D91D92D94D9dDa0Da1Da2Da4Db0Db1DbbDc0Dc1Dc6Dc7Dc8Dc9Dd0Dd1Dd2De0De1De2DedDf0Df1Df2Df4DfbDfdDffC8beD3cD3dD4dD5aD6aD79D7aD7bD85D8bD9aDaaDc3Dc4Dd3Dd4CeeeD03D05D0aD0cD0eD13D15D1cD1eD23D2eD3eD4aD55D6cD73D7cD7eD83D8cD8eD93D9cD9eDb5DcaDdeDe3DeeDf3Df5DfcDfeC559D18D26D34D35D36D41D51D61DafDbfDcfDdaDdbDddDeaDf8CcddD2fD5cD6dD6eDabDb2Db4Dc2DefC99bD16D24D39D45D54D56D64D65Da5DacDb6DbcDcbDd7DecDfaCdefD67D8aC59dD29D2bD68D69D78D88D96D97D98D99Da6Da8Da9Db9De5De7CacdD1aD2cD38D4bD4eD5dD5eD6bD89D9bDb3DbaDc5Dd8De4Df6C348D25D43D44Db7DccDdcDebCcccD3fD4fDdf" { + VersionInfos (); +} + +function setScaleBarre () { + requires("1.42n"); + // check for a previous calibration by this tool + metalabel=getMetadata("Label"); + metainfo=getMetadata("Info"); + if (metalabel != "" && (indexOf(metainfo, "") >=0)) exit ("This image has already been scaled\:\n"+metalabel); + if (microscope1[0] == "") exit ("First select a microscope profile from the blue microscope menu"); + var calibdata = microscope1; + setBatchMode(true); + imageid=getImageID(); + depth = bitDepth; nbslice = getSliceNumber(); + objectlist = getlistobj (calibdata); + if (otherobjecvalue != 0){ + objectlist[6] = otherobjective; + } else { + model=objectdata[0]; + } + reponseUser=0; + while (reponseUser==0) {resultchoices=userparameters (imageid);} + if (pixobj==6) { + resultchoices[7]=otherobjective; + objectlist[6]=otherobjective; + } else { + model=objectdata[0]; + } + //blackmarge =(hightcom*nblinecom); + //hightnblinecom : hight of a line of info + //nbline : nb of line of info + //hightcom : hight of the scale + if (scaleset == 1 || scalebarset ==1) {blackmarge =(hightnblinecom* (nblinecom * infoset) + hightcom); noscaleLine = 0;} + if (scaleset == 0 && scalebarset ==0) {blackmarge =(hightnblinecom* (nblinecom * infoset)); noscaleLine = 1;} + makeBottomMargin (imageid); + selectImage (imageCalibid); + run("Set Scale...", resultchoices[9]); + SetBar (imageCalibid,resultchoices[7],resultchoices[10],-1,imagex,imagey); + if (autosave == 1) AutoSaveCalib (imageid,imageCalibid); + setBatchMode("exit and display"); +} + +function extractAndEditImage () { + initScaled=getImageID(); + xsc = getWidth(); ysc = getHeight(); + namesc= getTitle; + setBatchMode(true); + metalabel=getMetadata("Label"); + metainfo=getMetadata("Info"); + pref= ""; suff =""; + if (metalabel == "" && (indexOf(metainfo, "") < 0)) {exit ("This image has not been treated by this tool");} + if (indexOf(metainfo,pref) >0 && indexOf(metainfo,suff) >0) { + blackmargeValue = parseFloat (substring (metainfo, (indexOf(metainfo, pref)+lengthOf(pref)), indexOf(metainfo, suff))); + } else {exit ("The metadata seems to be corrupted");} + pref = "" ; suff = ""; + if (indexOf(metainfo,pref) >0 && indexOf(metainfo,suff) >0) { + xsizeValue = parseFloat (substring (metainfo, (indexOf(metainfo, pref)+lengthOf(pref)), indexOf(metainfo, suff))); + } else {exit ("The metadata seems to be corrupted");} + pref = "" ; suff = ""; + if (indexOf(metainfo,pref) >0 && indexOf(metainfo,suff) >0) { + ysizeValue = parseFloat (substring (metainfo, (indexOf(metainfo, pref)+lengthOf(pref)), indexOf(metainfo, suff))); + } else {exit ("The metadata seems to be corrupted");} + if ((xsc != xsizeValue) || (ysc != (ysizeValue + blackmargeValue))) {exit ("The size of the image doesn't correspond to the original");} + newName=namesc; + if (indexOf(namesc,"-sc") > 0) {newName = substring (namesc, 0, indexOf(namesc, "-sc")); } + selectImage (initScaled); + run("Duplicate...", "title=["+newName+"]"); + setMetadata("Info", ""); + if (blackmargeValue > 0) { + makeRectangle(0, 0, xsizeValue, ysizeValue); + run("Crop"); + run("Select None"); + } + setBatchMode("exit and display"); +} + +// function removing a microscope profile file +function rmProfFromProfileCat () { + UpdateProfileList();ok=1; + nameofprofiles=InstalledProfiles(); + choix = catalogMicroPref (nameofprofiles,"remove"); + ijlocation = getDirectory("startup"); + filetodelete = ijlocation+ microscopeCollection + File.separator+ choix ; + if (File.exists(filetodelete )) showMessageWithCancel ("You will delete the \""+ choix + "\" microscope profile file\. Continue?"); + trydelete= File.delete(filetodelete); + if (trydelete == 1) {print("\\Clear");print ("The \""+ choix+ "\" microscope profile file has been deleted");} + else {print("\\Clear");print ("The \""+ choix+ "\" microscope profile file can't be delete for unknown reason");} + UpdateProfileList(); +} + +// function editing for modification a microscope profile +function editMicProfile (kind) { + choice="";toutok=0; + ijlocation = getDirectory("startup"); + if (kind == "edit") { + UpdateProfileList(); + nameofprofiles=InstalledProfiles(); + choice = catalogMicroPref (nameofprofiles,"edit-modify"); + ijlocation = getDirectory("startup"); + contentOfProf=GetArrayFromProfile(choice); + } + if (kind == "new") {contentOfProf=newArray(21);} + while (toutok == 0) { + Dialog.create("Editing of the \""+choice+"\" Microscope profile"); + Dialog.addMessage("Modify the values as explained in the documentation. Changing name creates a new profile"); + Dialog.addString("Microscope profile name", contentOfProf[0],30); + + Dialog.addString("Objective 1", contentOfProf[1],15); + Dialog.addNumber("Distance in pixels", contentOfProf[2], 0, 5, "pixels"); + Dialog.addNumber("Known Distance in "+um, contentOfProf[3], 3, 8, um); + Dialog.addNumber("Default bar size in "+um, contentOfProf[4], 3, 8, um); + + Dialog.addString("Objective 2", contentOfProf[5],15); + Dialog.addNumber("Distance in pixels", contentOfProf[6], 0, 5, "pixels"); + Dialog.addNumber("Known Distance in "+um, contentOfProf[7], 3, 8, um); + Dialog.addNumber("Default bar size in "+um, contentOfProf[8], 3, 8, um); + + Dialog.addString("Objective 3", contentOfProf[9],15); + Dialog.addNumber("Distance in pixels", contentOfProf[10], 0, 5, "pixels"); + Dialog.addNumber("Known Distance in "+um, contentOfProf[11], 3, 8, um); + Dialog.addNumber("Default bar size in "+um, contentOfProf[12], 3, 8, um); + + Dialog.addString("Objective 4", contentOfProf[13],15); + Dialog.addNumber("Distance in pixels", contentOfProf[14], 0, 5, "pixels"); + Dialog.addNumber("Known Distance in "+um, contentOfProf[15], 3, 8, um); + Dialog.addNumber("Default bar size in "+um, contentOfProf[16], 3, 8, um); + + Dialog.addString("Objective 5", contentOfProf[17],15); + Dialog.addNumber("Distance in pixels", contentOfProf[18], 0, 5, "pixels"); + Dialog.addNumber("Known Distance in "+um, contentOfProf[19], 3, 8, um); + Dialog.addNumber("Default bar size in "+um, contentOfProf[20], 3, 8, um); + Dialog.show(); + // ansvers + contentOfProf[0] =Dialog.getString(); + // objective 1 + contentOfProf[1] =Dialog.getString(); + contentOfProf[2] =Dialog.getNumber(); + contentOfProf[3] =Dialog.getNumber(); + contentOfProf[4] =Dialog.getNumber(); + // objective 2 + contentOfProf[5] =Dialog.getString(); + contentOfProf[6] =Dialog.getNumber(); + contentOfProf[7] =Dialog.getNumber(); + contentOfProf[8] =Dialog.getNumber(); + // objective 3 + contentOfProf[9] =Dialog.getString(); + contentOfProf[10] =Dialog.getNumber(); + contentOfProf[11] =Dialog.getNumber(); + contentOfProf[12] =Dialog.getNumber(); + // objective 4 + contentOfProf[13] =Dialog.getString(); + contentOfProf[14] =Dialog.getNumber(); + contentOfProf[15] =Dialog.getNumber(); + contentOfProf[16] =Dialog.getNumber(); + // objective 5 + contentOfProf[17] =Dialog.getString(); + contentOfProf[18] =Dialog.getNumber(); + contentOfProf[19] =Dialog.getNumber(); + contentOfProf[20] =Dialog.getNumber(); + for (i=0; i= 0 ){ + metainfoimage = substring (metaInfos, (indexOf(metaInfos, pref)+lengthOf(pref)), indexOf(metaInfos, suff)); + } + return metainfoimage; +} + +function getMetaInfosMic () { + // extract metainfos from the microscope profile + metaInfos = getMetadata("Info"); metainfomicprofile=""; + pref=""; suff =""; + if ((indexOf(metaInfos, pref)) >= 0 ) { + metainfomicprofile = substring (metaInfos, (indexOf(metaInfos, pref)+lengthOf(pref)), indexOf(metaInfos, suff)); + } + return metainfomicprofile; +} + +function testGetArrayFromProfile() { + // from the curent microscope profile name, return a profile info recorded on the hd + if (microscope1[0] != "") { + linesOfProfile = getFileContents (microscope1[0]); + profilArray= getArrayFromProfile (linesOfProfile); + curentprofileInfo="\n Current Microcope Profile\:\n \n"; + if (profilArray[0] != 0) curentprofileInfo=curentprofileInfo + profilArray[0] + "\n"; + for (i=1; i") < 0)) {exit ("This image has not been treated by this tool");} + pref = ""; suff =""; + if (indexOf(metainfo,pref) <0 || indexOf(metainfo,suff) <0) {exit ("The metadata seems to be corrupted");} + pref = ""; suff =""; + microprof=getMetaInfosMic (); + var microscope1=newArray (21); + for (i=0; i<21; i++) { + microscope1 [i]= substring (microprof, (indexOf(microprof, pref)+lengthOf(pref)), indexOf(microprof, suff)); + microprof=substring (microprof, (indexOf(microprof, suff) +lengthOf(suff)),lengthOf(microprof)); + } + testProfil=getProfileFromArray (microscope1); + saveMicroPref (testProfil[0],testProfil[1]); + UpdateProfileList(); +} + +function makeBottomMargin (imageid) { + selectImage(imageid); nomdimage = getTitle; compo=0; + width = getWidth(); height = getHeight(); + imagex=width; imagey=height; + //if name contains "." or other extention: + if (lastIndexOf(nomdimage, ".") > 0) {nomdimage=substring (nomdimage,0,lastIndexOf(nomdimage, "."));} + nomdimage= nomdimage + "-sc"; + selectImage (imageid); + if (is("composite")==1) { + showMessage ("The scaled image will be 24 bit RGB encoded.");run("RGB Color"); depth = bitDepth; + run("Select All");run("Copy");run("Select None");close (); + } else { + run("Select None"); + run("Duplicate...", "title=dup_"+nomdimage); + depth = bitDepth; + if (depth == 16 || depth == 32) {showMessage ("The scaled image will be 8 bit grey encoded.");run("8-bit"); depth = bitDepth;} + run("Select None");run("Select All");run("Copy");run("Select None");close (); + } + if (depth == 24) tipeu="\"RGB Black\""; + if (depth == 8) tipeu="\"8-bit Black\""; + newImage(nomdimage, tipeu, width, (height+blackmarge), nbslice); + makeRectangle(0, 0, width, height); + setPasteMode("Copy"); + run("Paste"); run("Select None"); + if (blackmarge !=0 ) { + setLineWidth(1);setColor(255,255,255) ; + drawLine(0, height,width, height); + } + imageCalibid=getImageID(); +} + +function AutoSaveCalib (init,calib) { + selectImage(init); + chemin=getDirectory("image"); + if (chemin != "") { + selectImage(calib); + nom=getTitle; + path=chemin+nom; format ="tiff"; + saveAs (format, path); + } +} + +// Function creating working arrays from the (calibdata) array contaning the microscope(n) data (n=1). +// return calibration data in the global array objectdata + +function getlistobj (microdata) { + for (i=0;i<5;i++) { + ii=(i*4+1); + objective[i+3]=microdata[ii]; + } + objectdata[0]=microdata[0]; + a=0; + for (ii=0;ii<5;ii++) { + for (i=1;i<4;i++){ + a=a+1; + objectdata[a]=microdata[ii*4+i+1]; + } + } + nbobj = 6; + objectlist = newArray(nbobj+1); + objectlist[0]="Obj ?"; + + for (ob = 1; ob <= nbobj; ob ++) { + objectlist[ob]=objective[ob+2]; + } + return objectlist; +} + +function getCalib (image) { + selectImage(image); + getPixelSize(unit, pixelWidth, pixelHeight); + if (unit !=um) {calibration = um+" uncalibrated";} else {calibration = " "+ d2s(pixelWidth,4) +" "+unit+" /pixel";} + textinfo="Current spatial calibration is ("+calibration+" )" ; + return textinfo; +} + +function userparameters (image) { + // Current calibration (pixel are supposed to be squared) : + if (model == "") {model=objectdata[0];} + textcalib=getCalib (image); + if ( model != "" && model != objectdata[0]) {diaMicro="Other for Microscope Model: "+ model;} else {diaMicro="Calibrating for Microscope Model: "+ model;} + Dialog.create("User settings for the image acquisition."); + Dialog.addMessage (diaMicro); + Dialog.addChoice(textcalib, objective,obj); + Dialog.addCheckbox("Draw a scale bar", scalebarset); + Dialog.addCheckbox("Write scale", scaleset); + Dialog.addCheckbox("Write infos", infoset); + Dialog.addCheckbox("Auto-Save the scaled image", autosave); + Dialog.show(); + obj = Dialog.getChoice(); + scalebarset = Dialog.getCheckbox(); + scaleset = Dialog.getCheckbox(); + infoset = Dialog.getCheckbox(); + autosave = Dialog.getCheckbox(); + userchoices[7] = obj; + defaultbar=""; pixdist=""; scaleunit=""; knowndist=""; spcalibration=""; + if (obj == objectlist[1]) { + pixdist= objectdata[1]; knowndist=objectdata[2];scaleunit=um;defaultbar=objectdata[3]; pixobj=1; + } + if (obj == objectlist[2]) { + pixdist= objectdata[4]; knowndist=objectdata[5];scaleunit=um;defaultbar=objectdata[6]; pixobj=2; + } + if (obj == objectlist[3]) { + pixdist= objectdata[7]; knowndist=objectdata[8];scaleunit=um;defaultbar=objectdata[9]; pixobj=3; + } + if (obj == objectlist[4]) { + pixdist= objectdata[10]; knowndist=objectdata[11];scaleunit=um;defaultbar=objectdata[12]; pixobj=4; + } + if (obj == objectlist[5]) { + pixdist= objectdata[13]; knowndist=objectdata[14];scaleunit=um;defaultbar=objectdata[15]; pixobj=5; + } + if (obj == "Uncalibrated") { + pixdist= 0; knowndist=0;scaleunit="pixel";defaultbar=100;pixobj=0; + } + if (obj == "Unchanged" ) { + pixdist= 100; knowndist=(pixelWidth*100);scaleunit=unit;defaultbar=50;pixobj=0; + } + if (obj == "Other") { + other (image); + } + if (unit !=um && obj == "Unchanged") userchoices[8] = 0; + if (pixobj > 0 && pixobj< 6) model = objectdata[0]; + spcalibration= "distance="+pixdist+" known="+knowndist+" pixel=1 unit="+scaleunit; + userchoices[9] =spcalibration; + userchoices[10]=defaultbar; + getPixelSize(unit, pixelWidth, pixelHeight); + if (obj== "Uncalibrated") { + objectcode= 0; + userchoices[8] = 0; + } + if (obj != "no choice") reponseUser =1; + if (obj == "-") {obj="no choice"; userchoices[7]="no choice";reponseUser =0;} + return userchoices; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function for spacial calibration with other data than these contained in the microscope specific array. +///////////////////////////////////////////////////////////////////////////////////////////////// + +function other (image) { + if (objectdata[0] == model) model =""; + textcalib=getCalib (image); + if (otherpixdist <= 0) pixdist= 1; else {pixdist = otherpixdist;} + if (otherknowndistance <= 0) knowndist=0.2; else {knowndist = otherknowndistance;} + if (othermodel != "") model=othermodel; + scaleunit=um; defaultbar=10; pixobj=6; + Dialog.create("Other settings for the calibration."); + Dialog.addMessage(textcalib); + Dialog.addNumber("Magnify factor of the objective (< 100, with the number format: xx.x) ? ",otherobjecvalue); + Dialog.addNumber("Distance in pixels ? ",pixdist); + Dialog.addNumber("Known distance (in the following format: x.xx) ? ",knowndist); + Dialog.addNumber("Zoom factor (lsm) ? ",zoom); + Dialog.addString("Microscope model ? ", model); + Dialog.show(); + otherobjecvalue = Dialog.getNumber(); + pixdist = Dialog.getNumber(); + knowndist = Dialog.getNumber(); + otherpixdist=pixdist;otherknowndistance=knowndist; + zoom=Dialog.getNumber(); + model=Dialog.getString();othermodel=model; + otherobjective="Obj "+otherobjecvalue+"x"; + pixdist=pixdist*100; + knowndist=knowndist*100; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// Function drawing a scale bar in the lower black margin. +//////////////////////////////////////////////////////////////////////////////////////////// + +function SetBar (targetid,objec,baresize,spacer,imagex,imagey) { + metaLabelMicro=""; + metaInfoMicro=""; + single=0; + if (spacer == -1) single=1; + selectImage (targetid); + largimage = getWidth(); + hautimage =getHeight(); + getPixelSize(unit, pixelWidth, pixelHeight); + pixbar= floor(baresize/pixelWidth); + if (pixbar >= (largimage/5)) { + while (pixbar >= (largimage/5)) { + pixbar= floor(baresize/pixelWidth); + baresize = floor(baresize / 2); + } + } + if (single==0) maxcustbar= floor((pixelWidth*(largimage + 3*spacer))/4); + if (single==1) maxcustbar= floor((pixelWidth*largimage )/4); + if (maxcustbar == 0) maxcustbar =1; + custuserbar = 0; + if (scalebarset == 1) { + while (custuserbar < 1 || custuserbar > maxcustbar){ + if (baresize == 0) baresize =1; + message="Advised size of the bar, for "+objec+" : " + baresize + " "+unit+". You can set a custom size to from 1 to "+ maxcustbar + " "+unit+ " - Current value ="; + if (lastCustuserbar != 0 && lastCustuserbar <= maxcustbar) {baresize = lastCustuserbar;} + Dialog.create("Custom user scale bar size."); + Dialog.addNumber(message, baresize); + Dialog.show(); + custuserbar = Dialog.getNumber(); + } + } + baresize = custuserbar; lastCustuserbar=baresize; + barx=newArray(1); bary=newArray(1); + bar="width="+baresize+" height=2 font=12 color=Yellow location=[At Selection] bold"; + barx[0]=10; + bary[0]=(hautimage-(blackmarge - 5)); + if (scalebarset == 1) { + makeSelection("point", barx, bary); + run("Scale Bar...",bar); + run("Select None"); + } + thescale = "Scale: "+ d2s (pixelWidth, 3) +" "+unit+ " / pixel"; + if ((largimage - ((baresize / pixelWidth) - 20)) > 150) { + xobjec=((baresize/pixelWidth) + 20); yobjec=(imagey + hightnblinecom +hightnblinecom/2); + if (scalebarset == 0) xobjec=10; + setColor(0, 255, 0); + setFont("SansSerif", 12,"bold"); + if (scaleset == 1) {drawString(thescale, xobjec, yobjec);} + } + if (infoset == 1) { + // Insert objective in the black margin (line 1). + setColor(0, 255, 255); + if ((largimage+130) > 50) { + xobjec=10; yobjec=(imagey + (blackmarge/nblinecom + hightnblinecom *(1-noscaleLine))); + drawString(objec, xobjec, yobjec); + } + if (pixobj==6){ + // Insert zoom and additional info in the black margin (line 1). + setColor(0, 255, 255); + message="Zoom factor (lsm): "+zoom; + if (largimage > 290) { + xobjec=70; yobjec=(imagey + (blackmarge/nblinecom + hightnblinecom *(1-noscaleLine))); + drawString(message, xobjec, yobjec); + } + } + // Insert the date in the black margin (line 2). + thedate = GetTime (); + setColor(150, 150, 255); + if (largimage > 290) { + xobjec=10; yobjec=(imagey + (blackmarge/nblinecom +(2-noscaleLine)*hightnblinecom )); + drawString(TimeString, xobjec, yobjec); + } + // Insert the model of microscope corresponding to the scaling values in the black margin (line 3). + setColor(150, 150, 255); + message="Microscope model: "+model; + if (largimage > 290) { + xobjec=10; yobjec=(imagey + (blackmarge/nblinecom +(3-noscaleLine)*hightnblinecom )); + drawString(message, xobjec, yobjec); + } + } + if (metaset == 1) { + // compile meta label: + metaLabelMicro= metaLabelMicro + model + " \; " + objec + " \; "; + if (pixobj==6){metaLabelMicro = metaLabelMicro + "Zoom: "+zoom + " \; ";} + metaLabelMicro = metaLabelMicro + thescale +" "; + setMetadata("Label", metaLabelMicro); + // compile meta infos for current image + metaInfoMicro=metaInfoMicro + ""; + metaInfoMicro=metaInfoMicro + "" +model+ ""; + metaInfoMicro=metaInfoMicro + "" +objec + ""; + metaInfoMicro=metaInfoMicro + "" +zoom + ""; + metaInfoMicro=metaInfoMicro + "" +d2s (pixelWidth, 3) + ""; + metaInfoMicro=metaInfoMicro + "" + unit + ""; + metaInfoMicro=metaInfoMicro + "" + baresize + ""; + metaInfoMicro=metaInfoMicro + "" + blackmarge + ""; + metaInfoMicro=metaInfoMicro + "" + imagex + ""; + metaInfoMicro=metaInfoMicro + "" + imagey + ""; + metaInfoMicro=metaInfoMicro + ""; + // compile meta infos for the current image microscope profile + metaInfoMicro=metaInfoMicro +""; + for (i=0; i" + microscope1 [i] + "";} + metaInfoMicro=metaInfoMicro + ""; + setMetadata("Info", metaInfoMicro); + } +} + +function GetTime () { + MonthNames = newArray("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); + DayNames = newArray("Sun", "Mon","Tue","Wed","Thu","Fri","Sat"); + getDateAndTime(year, month, dayOfWeek, dayOfMonth, hour, minute, second, msec); + TimeString ="Treatment date: "+DayNames[dayOfWeek]+" "; + if (dayOfMonth<10) {TimeString = TimeString+"0";} + TimeString = TimeString+dayOfMonth+"-"+MonthNames[month]+"-"+year+" Time: "; + if (hour<10) {TimeString = TimeString+"0";} + TimeString = TimeString+hour+":"; + if (minute<10) {TimeString = TimeString+"0";} + TimeString = TimeString+minute+":"; + if (second<10) {TimeString = TimeString+"0";} + TimeString = TimeString+second; + return TimeString; +} + +function saveMicroPref (profileName,profileContents) { + microlocation = getDirectory("startup"); + filedestination = microlocation+ microscopeCollection + File.separator+ profileName ; + if (File.exists(filedestination + "-MicProf"+".txt")) showMessageWithCancel ("A \"" + profileName + "\" microscope profile already exists. Overwrite it?"); + // Create a (name contened in the variable repertory microscopeCollection) in ImageJ folder. + microDir = microlocation + microscopeCollection + File.separator; + File.makeDirectory(microDir ); + if (!File.exists(microDir)) exit("Unable to create directory, something wrong in the ImageJ folder"); + pathProf = filedestination + "-MicProf"+".txt"; + theprofile = File.open(pathProf); + print (theprofile,profileContents); + File.close(theprofile); +} + +function catalogMicroPref (listerm,action) { + if (listerm.length > 0 && listerm[0] != "No microscope profile found") { + Dialog.create("List of Microscope Profiles"); + message="Choose the microscope profile to "+ action; + Dialog.addChoice(message, listerm); + Dialog.show(); + chosenProfile = Dialog.getChoice(); + return chosenProfile; + } else {exit ("No microscope profile found");} +} + +// Function giving the number (NumberOfProfiles) of profiles contained a file list (lprofile). +function getProfileNumber (lprofile) { + NumberOfProfiles=0; + for (i=0; i lengthOf("-MicProf.txt")) NumberOfProfiles ++; + } + return NumberOfProfiles; +} + +// Function giving a text profile from a profile array +function getProfileFromArray (arrayToTreat) { + pref=""; suff =""; + textFomArray=newArray (2); // 0 contains the title of the array, 1 contains the profile text itself + textFomArray[0]=arrayToTreat[0]; text=""; + for (i=1; i lengthOf("-MicProf.txt")) { + catalogue [nbProf]=listoffiles[i]; + shortCat [nbProf]=replace(catalogue [nbProf], "-MicProf.txt", ""); + nbProf++; + } + } + } else { + var catalogue= newArray ("No microscope profile found"); + var shortCat= newArray ("No microscope profile found"); + } + if (editMode ==0) return shortCat; + if (editMode ==1) return catalogue; +} + + +function instalDemoCollection () { + microscope1 = newArray("Axiovert 10 CCD Axiocam MRm","Obj 5x achro","772","1000","100","Obj 5x neofluo","759","1000","100","Obj 10x achro","755","500","50","Obj 10x neofluo","763","500","50","Obj 20x achro","612","200","25"); + demoProfil=getProfileFromArray (microscope1); + saveMicroPref (demoProfil[0],demoProfil[1]); + microscope1 = newArray("Olympus BH-2 CCD Scion","Obj 4x","832","1000","100","Obj 10x","207","100","50","Obj 20x","417","100","50","Obj 40x","833","100","10","Obj 100x","185","9","10"); + demoProfil=getProfileFromArray (microscope1); + saveMicroPref (demoProfil[0],demoProfil[1]); + microscope1 = newArray("Leica Palermo","Obj 10x","658","500","50", "Obj 20x","525","200","50","Obj 40x","530","100","10", "Obj 63x","827","100","10", "Obj 100x","1312","100","10"); + demoProfil=getProfileFromArray (microscope1); + saveMicroPref (demoProfil[0],demoProfil[1]); + microscope1 = newArray("Leitz Aristoplan CCD CoolSnap ","Obj 6,3x","436","500","100","Obj 10x plan","549","400","50","Obj 25x Fluotar","1035","300","50","Obj 40x Fluotar","1103","200","10","Obj 100x oil Fluotar","1103","80","10"); + demoProfil=getProfileFromArray (microscope1); + saveMicroPref (demoProfil[0],demoProfil[1]); + microscope1 = newArray("Nikon TE2000 Salpetriere CCD Hamamatsu","Obj 10x ph1","1160","500","50", "Obj 20x plan fluo","928","200","50","-","1","1","1", "-","1","1","1","-","1","1","1"); + demoProfil=getProfileFromArray (microscope1); + saveMicroPref (demoProfil[0],demoProfil[1]); + UpdateProfileList(); +} + +function UpdateProfileList() { + // update the profile list + kind="toolsets";macroname="Scale Bar Tools for Microscopes.txt"; + macropath=getDirectory("macros") + kind + File.separator+ macroname; + if (!File.exists(macropath)) {exit ("Record this tool into the \"ImageJ\/macros\/toolset\" repertory folder\nwith the name \"" +macroname+ "\", to use it.");} + run("Install...", "install=["+macropath+"]"); +} + +function netTest () { + erNetMessage ="Error: "; + testlink = "http://rsb.info.nih.gov/ij/macros/Arrays.txt"; + if (indexOf (File.openUrlAsString(urllist), errorNetMessage) >0) exit("You need an internet access to run this function."); +} + +function OpenImageLink(link,name,question) { + // Check if already downloaded. + demoimalocation = getDirectory("startup"); + fildestination = demoimalocation+ "Downloaded Demo Images/" + name; + if (File.exists(fildestination)) { + if (question ==1 ) showMessageWithCancel ("The \"" + name + "\" has already been downloaded. Open it?"); + open(fildestination); + } + else { + netTest (); + showMessageWithCancel ("ImageJ will download a demo image. Continue?"); + run("URL...", "url=["+link+"]"); + imageid = getImageID(); + nomdimage = getTitle; + // Create a repertory in ImageJ folder. + ImaDemo = demoimalocation+"Downloaded Demo Images"+File.separator; + File.makeDirectory(ImaDemo); + if (!File.exists(ImaDemo)) exit("Unable to create directory, something wrong in the ImageJ folder"); + selectWindow(nomdimage); + save(""+ImaDemo+""+ nomdimage +""); + } +} + +function doc () { + netTest (); + showMessageWithCancel ("A notice is avaible on line. Open it with your default web browser?"); + run("URL...", "url=["+onlinedoclink +"]"); +} + + +// -------------------*** Additionnal code for on line update resources ***----------------------------- + +//Developer info +//Kind:Toolset +//Title:"Scale Bar Tools for Microscopes" +//Version:1.0 +//Date: 11/05/2009 +//Origin:NIH +//End info + +function VersionInfos () { + // variables for on line update resources + beginsign="//Developer info";endsign="//End info"; + kind="toolsets/"; + urlrep="http://image.bio.methods.free.fr/ij/ijmacro/scalebar/"; + name="Scale Bar Tools for Microscopes.txt"; + namedev="Scale Bar Tools for Microscopes-dev.txt"; + favoritefoldername= "Image.Bio.Methods"; + version=versionMessage(); + if (indexOf(version, "install it?" ) > 0 ) { + macrotext=getdistantmacro (namedev,urlrep);macrolocal=""; + macropath=getDirectory("macros")+kind+namedev; + if (File.exists(macropath)) {macrolocal=File.openAsString(macropath);} + if (macrotext != macrolocal) { + //perfom the installation + Dialog.create("New version installation option"); + Dialog.addMessage(version); + Dialog.addCheckbox("Install a Plugin Shortcut?", 0); + Dialog.addMessage("(This option provides a shortcut in the plugins menu of ImageJ, making easier\nthe next use of the new installed version)."); + Dialog.show(); + plugin= Dialog.getCheckbox(); + f= File.open(macropath); + print (f,macrotext); + File.close(f); + if (plugin ==1) {InstallPluginsStarter(namedev);} + message="The installation of the "+giveDevInfo (macrotext,1)+ " "+ giveDevInfo (macrotext,2)+ "is completed."; + message=message+ " Do you want to run it?"; + showMessageWithCancel(message); + run("Install...", "install=["+macropath+"]"); + } + } else {showMessage (version); // comment without installation available} +} + +function versionMessage() { + version=""; + if (getDirectory("startup") == 0) exit ("Unable to find the startup directory, something wrong in the ImageJ folder"); + if (getDirectory("macros") == 0) exit ("Unable to find the macros directory, something wrong in the ImageJ folder"); + MacroPath=getDirectory("macros");thismacropath=MacroPath+kind+name; + if (! File.exists(thismacropath)) exit ("This macro has to be recorded under the name of \"" +name+"\"\ninto the \"macros/"+kind+"\" folder of ImageJ."); + macrotext=File.openAsString(thismacropath); + macrotextdistant=getdistantmacro (namedev,urlrep); + version="";macrolocal=""; + version=version + "\n \nThis version of the " + giveDevInfo (macrotext,1) + " " + giveDevInfo (macrotext,2); + version=version + "is provided by the " + giveDevInfo (macrotext,5)+ " web site."; + version=version + "\nVersion number: " + giveDevInfo (macrotext,3)+ " - " + giveDevInfo (macrotext,4) +"."; + if (macrotextdistant !="" ) { + new=giveDevInfo (macrotextdistant,3);old=giveDevInfo (macrotext,3); + if (new > old) { + macropath=getDirectory("macros")+kind+namedev; + if (File.exists(macropath)) {macrolocal=File.openAsString(macropath);} + if (macrotextdistant != macrolocal) { + update="\n \nA new version "+new+ " is available on the " +giveDevInfo (macrotextdistant,5)+ " web site: "; + update=update+ "\n \nDo you want to install it?"; + } else { + update ="\n \nThe latest "+new+" version called \"" +namedev+ "\" provided by \nthe "+giveDevInfo (macrotextdistant,5) +" web site has already be installed"; + update = update+ " in the \"" +kind+ "\" repertory \nof ImageJ."; + } + } else { + update="No new version available."; + } + version=version +"\n" + update ; + } + return version; +} + +function giveDevInfo (text,n) { + lines=split(text,"\n"); + if ( (indexOf(text, beginsign)<0) || (indexOf(text, endsign)<0) ) exit ("Not upgradable macro code."); + for (i=0; lines[i] != endsign; i ++) {} + for (j=i; lines[j] != beginsign; j --) {} + infotext=newArray(i-j-1); + for (i=0; i < infotext.length; i ++) {infotext[i]=lines[i+j+1];} + info=infotext[n-1]; signature=":"; + cut = indexOf(info, signature); + info = substring(info,(cut+lengthOf(signature)),lengthOf(info)); + return info; +} + +// Function giving the content of a distant macro (name) located at the distant repertory (urlrep). +function getdistantmacro (name,urlrep) { + macrotextnih=""; + erNetMessage ="Error: "; + testlink = "http://rsb.info.nih.gov/ij/macros/Arrays.txt"; + if (indexOf (File.openUrlAsString(testlink), erNetMessage) < 0) { + distantmacrolink = urlrep + name; + if (indexOf(distantmacrolink, " ") > -1) { + while (indexOf(distantmacrolink, " ") > -1) { + distantmacrolink=substring(distantmacrolink, 0, (indexOf(distantmacrolink, " ")))+"%20"+substring(distantmacrolink, (indexOf(distantmacrolink, " ")+1),lengthOf(distantmacrolink) ); + } + } + showStatus("Internet link..."); + macrotextnih =File.openUrlAsString(distantmacrolink); + showStatus(""); + } else { showMessage ("No internet connection to looks for new version.");} + return macrotextnih; +} + +function InstallPluginsStarter(macroname) { + // from MacroPluginShortcutsTool.txt + codestarter = "run\(\"Install...\", \"install=[\"+getDirectory(\"macros\")+\""+kind+ macroname + "\]\"\);"; + if (getDirectory("plugins") == "") exit ("Unable to find the Plugins directory; something wrong in the ImageJ folder."); + if (endsWith(macroname, ".txt") || endsWith(macroname, ".ijm")) pluginname = substring(macroname, 0, (lengthOf(macroname)-4)); + StarterDir = getDirectory("plugins")+favoritefoldername+File.separator; + File.makeDirectory(StarterDir); + if (!File.exists(StarterDir)) exit ("Unable to create "+favoritefoldername+" Macros directory, something wrong in the ImageJ folder."); + starterplugin = StarterDir + pluginname +"_ .ijm"; + f= File.open(StarterDir + pluginname +"_ .ijm"); + print (f,codestarter); + File.close(f); + showMessage ("The plugin shortcut \"" +pluginname+ "\" will be available after\nImageJ restarting, in the \"Plugins->" + favoritefoldername + "\" menu."); +} + +// *** End of additionnal code for on line update ressources *** + + + diff --git a/MT2-project-ImageProcessing/macros/toolsets/Stack Tools.ijm b/MT2-project-ImageProcessing/macros/toolsets/Stack Tools.ijm new file mode 100644 index 0000000..c100e7e --- /dev/null +++ b/MT2-project-ImageProcessing/macros/toolsets/Stack Tools.ijm @@ -0,0 +1,37 @@ +// "Stack Tools" + + var sCmds = newMenu("Stacks Menu Tool", + newArray("Add Slice", "Delete Slice", "Next Slice [>]", "Previous Slice [<]", "Set Slice...", "-", + "Convert Images to Stack", "Convert Stack to Images", "Make Montage...", "Reslice [/]...", "Z Project...", + "3D Project...", "Plot Z-axis Profile", "-", "Start Animation", "Stop Animation", "Animation Options...", + "-", "MRI Stack (528K)")); + + macro "Stacks Menu Tool - C037T0b11ST8b09tTcb09k" { + cmd = getArgument(); + if (cmd!="-") run(cmd); + } + + macro "First Slice Action Tool - C037T0d14" { + run("Next Slice [>]"); + } + + macro "Last Slice Action Tool - C037T0d14>T7d14>" { + setSlice(nSlices); + } + + macro "Add Slice Action Tool - C037T4d14+" { + run("Add Slice"); + } + + macro "Delete Slice Action Tool - C037T4c14-T7c14-" { + run("Delete Slice"); + } + diff --git a/MT2-project-ImageProcessing/src/Setup_Test.java b/MT2-project-ImageProcessing/src/Setup_Test.java new file mode 100644 index 0000000..a4ef781 --- /dev/null +++ b/MT2-project-ImageProcessing/src/Setup_Test.java @@ -0,0 +1,10 @@ +import ij.IJ; +import ij.plugin.PlugIn; + +public class Setup_Test implements PlugIn { + @Override + public void run(String s) { + IJ.showMessage("If you can read this, the Project-Setup most likely worked. \n " + + " Happy Coding :) "); + } +} diff --git a/MT2-project-ImageProcessing/src/Task_1_Threshold.java b/MT2-project-ImageProcessing/src/Task_1_Threshold.java new file mode 100644 index 0000000..b706428 --- /dev/null +++ b/MT2-project-ImageProcessing/src/Task_1_Threshold.java @@ -0,0 +1,47 @@ +import ij.ImagePlus; +import ij.gui.GenericDialog; +import ij.plugin.filter.PlugInFilter; +import ij.process.Blitter; +import ij.process.ByteProcessor; +import ij.process.FloatProcessor; +import ij.process.ImageProcessor; + +public class Task_1_Threshold implements PlugInFilter { + @Override + public int setup(String s, ImagePlus imagePlus) { + return DOES_8G; + } + + @Override + public void run(ImageProcessor ip) { + + /* + GenericDialog gd = new GenericDialog("Thresholding"); + gd.addNumericField("Threshold value:", 128, 0); + gd.addCheckbox("Correct uneven illumination", false); + gd.showDialog(); + + //check if the dialog was canceled + if (gd.wasCanceled()) + return; + + //get user choices + int threshold = (int) gd.getNextNumber(); + boolean correct = gd.getNextBoolean(); + + //correct illumination if selected + ImageProcessor ipCopy; + if (correct) { + ipCopy = correctIllumination(ip); + } else { + ipCopy = ip; + } + // threshold the image + ByteProcessor thresholdedIp = threshold(ipCopy, threshold); + ImagePlus thresholdedImage = new ImagePlus("Thresholded Image", thresholdedIp); + thresholdedImage.show(); + + */ + } + +} diff --git a/MT2-project-ImageProcessing/src/Task_2_EvaluateSegmentation.java b/MT2-project-ImageProcessing/src/Task_2_EvaluateSegmentation.java new file mode 100644 index 0000000..edf4799 --- /dev/null +++ b/MT2-project-ImageProcessing/src/Task_2_EvaluateSegmentation.java @@ -0,0 +1,15 @@ +import ij.ImagePlus; +import ij.plugin.filter.PlugInFilter; +import ij.process.ImageProcessor; + +public class Task_2_EvaluateSegmentation implements PlugInFilter { + @Override + public int setup(String s, ImagePlus imagePlus) { + return DOES_8G; + } + + @Override + public void run(ImageProcessor imageProcessor) { + + } +} diff --git a/MT2-project-ImageProcessing/src/Task_3_Otsu.java b/MT2-project-ImageProcessing/src/Task_3_Otsu.java new file mode 100644 index 0000000..6f64b8e --- /dev/null +++ b/MT2-project-ImageProcessing/src/Task_3_Otsu.java @@ -0,0 +1,40 @@ +import ij.ImagePlus; +import ij.plugin.filter.PlugInFilter; +import ij.process.ByteProcessor; +import ij.process.ImageProcessor; + +import java.awt.*; + +public class Task_3_Otsu implements PlugInFilter { + + @Override + public int setup(String s, ImagePlus imagePlus) { + return DOES_8G; + } + + @Override + public void run(ImageProcessor imageProcessor) { + + } + + /* + + public double[] getHistogram(ImageProcessor in) {} + + public double[] getP1(double[] histogram) {} + + public double[] getP2(double[] P1) {} + + public double[] getMu1(double[] histogram, double[] P1) {} + + public double[] getMu2(double[] histogram, double[] P2) {} + + public double[] getSigmas(double[] P1, double[] P2, double[] mu1, double[] mu2) {} + + public int getMaximum(double[] sigmas) {} + + public ByteProcessor otsuSegmentation(ImageProcessor ip) {} + + */ + +} diff --git a/MT2-project-ImageProcessing/src/Task_4_Filters.java b/MT2-project-ImageProcessing/src/Task_4_Filters.java new file mode 100644 index 0000000..a9073df --- /dev/null +++ b/MT2-project-ImageProcessing/src/Task_4_Filters.java @@ -0,0 +1,25 @@ +import ij.ImagePlus; +import ij.plugin.filter.PlugInFilter; +import ij.process.ImageProcessor; + +public class Task_4_Filters implements PlugInFilter { + + protected int[][] SobelX = {{1,0,-1},{2,0,-2},{1,0,-1}}; + protected int[][] SobelY = {{1,2,1},{0,0,0},{-1,-2,-1}}; + + protected int[][] ScharrX = {{47,0,-47},{162,0,-162},{47,0,-47}}; + protected int[][] ScharrY = {{47,162,47},{0,0,0},{-47,-162,-47}}; + + protected int[][] PrewittX = {{1,0,-1},{1,0,-1},{1,0,-1}}; + protected int[][] PrewittY = {{1,1,1},{0,0,0},{-1,-1,-1}}; + + @Override + public int setup(String s, ImagePlus imagePlus) { + return DOES_8G; + } + + @Override + public void run(ImageProcessor imageProcessor) { + + } +} diff --git a/MT2-project-ImageProcessing/src/Task_5_CannyEdgeDetection.java b/MT2-project-ImageProcessing/src/Task_5_CannyEdgeDetection.java new file mode 100644 index 0000000..5f66da4 --- /dev/null +++ b/MT2-project-ImageProcessing/src/Task_5_CannyEdgeDetection.java @@ -0,0 +1,27 @@ +import ij.ImagePlus; +import ij.plugin.filter.PlugInFilter; +import ij.process.ByteProcessor; +import ij.process.ImageProcessor; + +public class Task_5_CannyEdgeDetection implements PlugInFilter { + + @Override + public void run(ImageProcessor imageProcessor) { + int[][] SobelX = {{1,0,-1},{2,0,-2},{1,0,-1}}; + int[][] SobelY = {{1,2,1},{0,0,0},{-1,-2,-1}}; + + } + + public boolean hasNeighbours(ByteProcessor BP, int x, int y ){ + int count = (BP.getPixel(x+1,y)+BP.getPixel(x-1,y)+BP.getPixel(x,y+1)+BP.getPixel(x,y-1)+BP.getPixel(x+1,y+1)+ + BP.getPixel(x-1,y-1)+BP.getPixel(x-1,y+1)+BP.getPixel(x+1,y-1)); + count/=255; + return (count>0) ; + } + + + @Override + public int setup(String s, ImagePlus imagePlus) { + return DOES_8G; + } +} diff --git a/MT2-project-ImageProcessing/src/User_Interface.java b/MT2-project-ImageProcessing/src/User_Interface.java new file mode 100644 index 0000000..9f33f0e --- /dev/null +++ b/MT2-project-ImageProcessing/src/User_Interface.java @@ -0,0 +1,78 @@ +import ij.ImagePlus; +import ij.gui.GenericDialog; +import ij.plugin.filter.PlugInFilter; +import ij.process.ImageProcessor; + +public class User_Interface implements PlugInFilter { + + Task_3_Otsu Otsu = new Task_3_Otsu(); + + + + @Override + public int setup(String s, ImagePlus imagePlus) { + return DOES_8G; + } + + @Override + public void run(ImageProcessor imageProcessor) { + + Task_1_Threshold Threshold = new Task_1_Threshold(); + Task_2_EvaluateSegmentation Evaluate = new Task_2_EvaluateSegmentation(); + Task_3_Otsu Otsu = new Task_3_Otsu(); + Task_4_Filters Filters = new Task_4_Filters(); + Task_5_CannyEdgeDetection Canny = new Task_5_CannyEdgeDetection(); + + + GenericDialog GD = new GenericDialog("Selection panel"); + String[] firstChoice ={"Thresholding","Edge-Detection"}; + GD.addChoice("Choose an action: ", firstChoice,firstChoice[0]); + GD.showDialog(); + + if (GD.wasCanceled()){ + return; + } + + int firstChoiceIdx = GD.getNextChoiceIndex(); + + if (firstChoiceIdx ==0){ + + String[] ThreshChoice ={"regular Thresholding","Otsu"}; + GD.addChoice("Choose Thresholding-technique:",ThreshChoice,ThreshChoice[0]); + GD.addCheckbox("Evaluate Segmentation?",false); + GD.showDialog(); + + int temp = GD.getNextChoiceIndex(); + int ThreshChoiceIdx = GD.getNextChoiceIndex(); + boolean eval = GD.getNextBoolean(); + + if (ThreshChoiceIdx == 0){ + Threshold.run(imageProcessor); + } + else{ + Otsu.run(imageProcessor); + } + + if (eval){ + Evaluate.run(imageProcessor); + } + + } + + else{ + String[] EDChoice ={"Primitive","Canny-Edge-Detection"}; + GD.addChoice("Choose edge-detection-technique:",EDChoice,EDChoice[0]); + GD.showDialog(); + int temp = GD.getNextChoiceIndex(); + int EDChoiceIdx = GD.getNextChoiceIndex(); + + if (EDChoiceIdx == 0){ + Filters.run(imageProcessor); + } + else{ + Canny.run(imageProcessor); + } + } + } +} +