// BioVoxxel Macro Menu // http://www.biovoxxel.de/macros.html var filemenu = newMenu("BioVoxxel Macros Menu Tool", newArray("Advanced Particle Analyzer", "Binary Feature Extractor", "Speckle Inspector", "Watershed Irregular Features", "EDM Erode", "EDM Dilate", "Auto Binary Masking", "-", "Threshold Checker", "-", "Contrast Detection", "Difference of Gaussian", "Difference from Median", "-", "Hyperstack Color Coding", "About")); macro "BioVoxxel Macros Menu Tool - C000C010C020C030C040C050Df9C050D62C050D75C060D87C060D76C060D61C060Db8C060D63C060D74Da8Dc8C060D50De9C060D81C060De7C060D91Dc2C060D77Dd4Dd8C060De8C070D71D97Dd3C070D73D78C070D51D60De6C070D06D5aD69Db2C070D4bD86Dd5C070D3dD98Da7C070D64Da2C070D3cD72D82D83D84D85D92D93D94D95D96Da1Da3Da4Da5Da6Db3Db4Db5Db6Db7Dc3Dc4Dc5Dc6Dc7Dd6Dd7C070D2dC070Dd9C070C080D2cC080D15D19Dd2C080D88C080D18C080D24DafC080D33C080D2bC080D42D65C080De5C080D52C080D4cC080D17D41D68C080C090D2aD59C090D9fDb1Dc9C090D32D4aD5bC090D1aD3bC090D16D53D66C090D25D29D5eD6eDf8C090D26D27D28D34D35D36D37D38D39D3aD43D44D45D46D47D48D49D54D55D56D57D58D67DeaC090D6aC090DbeC090D07C090D23DdbC090D70D7eDcdC090D79DccC0a0D4eDb9C0a0DbdDdcC0a0D14C0a0D8eDaeC0a0D4dD8fC0a0D05Da9C0a0DebC0b0Dc1DfaC0b0D9eC0b0D5cD5dD99DdaC0b0D6bD6cD6dD7aD7bD7cD7dD89D8aD8bD8cD8dD9aD9bD9cD9dDaaDabDacDadDbaDbbDbcDcaDcbC0b0De4C0b0D1bD3eC0b0D80C0b0C0c0Df7C0c0D08C0c0D7fC0c0C0d0D2eC0d0Dd1C0d0D6fC0d0C0e0C0f0D5fC0f0"{ BVCmd = getArgument(); if (BVCmd!="-" && BVCmd!="****:" ) { if (BVCmd=="Advanced Particle Analyzer") { AdvancedParticleAnalyzer(); } else if (BVCmd=="Binary Feature Extractor") { FeatureExtractor(); } else if (BVCmd=="Speckle Inspector") { SpeckleInspector(); } else if (BVCmd=="Watershed Irregular Features") { ImprovedWatershed(); } else if (BVCmd=="EDM Erode") { EDMerosion(); } else if (BVCmd=="EDM Dilate") { EDMdilate(); } else if (BVCmd=="Auto Binary Masking") { AutoMasking(); } else if (BVCmd=="Threshold Checker") { ThresholdChecker(); } else if (BVCmd=="Difference of Gaussian") { DifferenceOfGaussian(); } else if (BVCmd=="Difference from Median") { DifferenceOfMedian(); } else if (BVCmd=="Contrast Detection") { ContrastDetection(); } else if (BVCmd=="Hyperstack Color Coding") { HyperstackColorCoding(); } else if (BVCmd=="About") { About(); } } } //-------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------- //BioVoxxel Macro Menu; developed by Jan Brocher/BioVoxxel, 2013 //-------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------------------------------------- //Analyze Particles according to shape discriptor limitations //Author: Jan Brocher/BioVoxxel //First version 0.1 (25/04/2013) function AdvancedParticleAnalyzer() { original=getTitle(); if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } if(is("binary")==false) { exit("works only on binary images"); } run("Set Measurements...", "area mean standard modal min centroid center perimeter bounding fit shape feret's integrated median skewness kurtosis area_fraction stack display redirect=None decimal=3"); //Setup including shape descriptors Dialog.create("Advanced Particle Analyzer"); Dialog.addString("Area (pixel^2)", "0-Infinity"); Dialog.addString("Perimeter", "0.00-Infinity"); Dialog.addString("Circularity", "0.00-1.00"); Dialog.addString("Solidity", "0.00-1.00"); Dialog.addString("Aspect ratio (AR)", "0.00-Infinity"); Dialog.addString("Ellipsoid angle (degree)", "0.00-180"); Dialog.addString("Max. Feret", "0.00-Infinity"); Dialog.addString("Feret's angle (degree)", "0.00-180"); Dialog.addChoice("Show", newArray("Nothing", "Outlines", "Bare Outlines", "Ellipses", "Masks", "Count Masks", "Overlay Outlines", "Overlay Masks"), "Outlines"); Dialog.addCheckboxGroup(3, 2, newArray("Display results", "Summarize", "Add to Manager", "Exclude edges", "Include holes"), newArray(true, false, false, false, false)); Dialog.addHelp("www.biovoxxel.de/macros.html"); Dialog.show(); Area=Dialog.getString(); Perimeter=Dialog.getString(); Circularity=Dialog.getString(); Solidity=Dialog.getString(); AR=Dialog.getString(); EllipsoidAngle=Dialog.getString(); MaxFeret=Dialog.getString(); FeretAngle=Dialog.getString(); Output=Dialog.getChoice(); DisplayResults=Dialog.getCheckbox(); if(DisplayResults==true) {DisplayResults=" display";} else {DisplayResults="";} Summarize=Dialog.getCheckbox(); if(Summarize==true) {Summarize=" summarize";} else {Summarize="";} AddToManager=Dialog.getCheckbox(); if(AddToManager==true) {AddToManager=" add";} else {AddToManager="";} ExcludeEdges=Dialog.getCheckbox(); if(ExcludeEdges==true) {ExcludeEdges=" exclude";} else {ExcludeEdges="";} IncludeHoles=Dialog.getCheckbox(); if(IncludeHoles==true) {IncludeHoles=" include";} else {IncludeHoles="";} setBatchMode(true); setForegroundColor(0,0,0); selectWindow(original); run("Analyze Particles...", "size=["+Area+"] pixel circularity=["+Circularity+"] show=Masks" + " clear" + ExcludeEdges + IncludeHoles); temp=getTitle(); run("Invert LUT"); initList=nResults; for(n=0; n<initList; n++) { end=false; selectWindow(temp); if(Perimeter!="0-Infinity" && end==false) { PerimeterMin=substring(Perimeter, 0, (indexOf(Perimeter, "-"))); PerimeterMax=substring(Perimeter, (indexOf(Perimeter, "-")+1)); if(getResult("Perim.", n)<PerimeterMin || getResult("Perim.", n)>PerimeterMax) { X=getResult("X", n); Y=getResult("Y", n); doWand(X,Y); run("Fill"); end=true; } } if(Solidity!="0.00-1.00" && end==false) { SolidityMin=substring(Solidity, 0, (indexOf(Solidity, "-"))); SolidityMax=substring(Solidity, (indexOf(Solidity, "-")+1)); if(getResult("Solidity", n)<SolidityMin || getResult("Solidity", n)>SolidityMax) { X=getResult("X", n); Y=getResult("Y", n); doWand(X,Y); run("Fill"); end=true; } } if(AR!="0.00-Infinity" && end==false) { ARMin=substring(AR, 0, (indexOf(AR, "-"))); ARMax=substring(AR, (indexOf(AR, "-")+1)); if(getResult("AR", n)<ARMin || getResult("AR", n)>ARMax) { X=getResult("X", n); Y=getResult("Y", n); doWand(X,Y); run("Fill"); end=true; } } if(EllipsoidAngle!="0-360" && end==false) { EllipsoidAngleMin=substring(EllipsoidAngle, 0, (indexOf(EllipsoidAngle, "-"))); EllipsoidAngleMax=substring(EllipsoidAngle, (indexOf(EllipsoidAngle, "-")+1)); if(getResult("Angle", n)<EllipsoidAngleMin || getResult("Angle", n)>EllipsoidAngleMax) { X=getResult("X", n); Y=getResult("Y", n); doWand(X,Y); run("Fill"); end=true; } } if(MaxFeret!="0.00-Infinity" && end==false) { MaxFeretMin=substring(MaxFeret, 0, (indexOf(MaxFeret, "-"))); MaxFeretMax=substring(MaxFeret, (indexOf(MaxFeret, "-")+1)); if(getResult("Feret", n)<MaxFeretMin || getResult("Feret", n)>MaxFeretMax) { X=getResult("X", n); Y=getResult("Y", n); doWand(X,Y); run("Fill"); end=true; } } if(FeretAngle!="0.00-Infinity" && end==false) { FeretAngleMin=substring(FeretAngle, 0, (indexOf(FeretAngle, "-"))); FeretAngleMax=substring(FeretAngle, (indexOf(FeretAngle, "-")+1)); if(getResult("FeretAngle", n)<FeretAngleMin || getResult("FeretAngle", n)>FeretAngleMax) { X=getResult("X", n); Y=getResult("Y", n); doWand(X,Y); run("Fill"); end=true; } } } setBatchMode(false); selectWindow(temp); run("Select None"); run("Analyze Particles...", "size=Area pixel circularity=Circularity show=["+Output+"]" + DisplayResults +" clear" + Summarize + AddToManager + ExcludeEdges + IncludeHoles); rename("PartAnal_"+original); close(temp); exit(); } //--------------------------------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------- // Feature Extractor, developed by Jan Brocher/BioVoxxel, 2013 // Developed after a description from J. Russ (The Image Processing Handbook, 6th Ed.) //-------------------------------------------------------------------------------------- function FeatureExtractor() { if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } run("Wand Tool...", "mode=Legacy tolerance=0"); setForegroundColor(255,255,255); setBackgroundColor(0,0,0); run("Options...", "iterations=1 count=1 black edm=Overwrite do=Nothing"); // "choose target image" --------------------------------------------------------------------------------------- waitForUser("Click on image containing (main) freatures and press Ok"); binary1 = is("binary"); if (binary1!=1) { exit("works only with binary images"); } getDimensions(width1, height1, channels1, slices1, frames1); features = getTitle(); // "choose reference image" --------------------------------------------------------------------------------------- waitForUser("Click on image containing Selector and press Ok"); binary2 = is("binary"); if (binary2!=1) { exit("works only with binary images"); } getDimensions(width2, height2, channels2, slices2, frames2); if (width1!=width2 || height1!=height2) { exit("images need to be of same dimensions"); } else { setBatchMode(true); selector = getTitle(); run("Duplicate...", "title=mask"); selectWindow("mask"); up = getTitle(); run("Set Measurements...", "area bounding display redirect=None decimal=3"); selectWindow(features); setPasteMode("AND"); run("Select All"); run("Copy"); selectWindow(up); run("Paste"); run("Make Binary"); run("Ultimate Points"); setAutoThreshold("Default dark"); //run("Threshold..."); setThreshold(1, 255); run("Convert to Mask"); //analyze ultimate points run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Nothing display clear record"); //get ultimate point positions newImage("Extracted from "+features, "8-bit Black", width2, height2, 1); output=getTitle(); setTool("wand"); setPasteMode("Copy"); rows=nResults(); for (i=0;i<rows;i++) { selectWindow(features); x=getResult("BX",i); y=getResult("BY",i); toUnscaled(x, y); //mark ultimate points in query image doWand(x, y); run("Copy"); selectWindow(output); run("Restore Selection"); run("Paste"); setTool("rectangle"); } run("Select None"); setBatchMode(false); selectWindow("Results"); run("Close"); print(rows + " Features extracted"); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Improved Watershed segmentation, developed by Jan Brocher/BioVoxxel, 2012 // Developed after a description from J. Russ (The Image Processing Handbook, 6th Ed.) //---------------------------------------------------------------------------- function ImprovedWatershed() { original=getTitle(); if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } selectWindow(original); //erosion dialog Dialog.create("Erosion cycles"); Dialog.addNumber("Choose erosion cycle number:", 2); Dialog.addHelp("www.biovoxxel.de/macros.html"); Dialog.show(); cycles=Dialog.getNumber(); selectWindow(original); run("Duplicate...", "title=erosion"); run("Duplicate...", "title=watershed"); rename("Watershed of " + original); setBatchMode(true); watershed = getTitle(); selectWindow("erosion"); run("Options...", "iterations=cycles count=1 black edm=Overwrite do=Erode"); selectWindow(watershed); run("Watershed"); run("Duplicate...", "title=separators"); // setPasteMode("XOR"); selectWindow(original); run("Select All"); run("Copy"); selectWindow("separators"); run("Paste"); WSExtraction(); selectWindow("erosion"); close(); selectWindow("separators"); close(); selectWindow("Output"); run("Select All"); run("Copy"); close(); setPasteMode("OR"); selectWindow("Results"); run("Close"); setBatchMode(false); selectWindow(watershed); run("Paste"); function WSExtraction() { run("Wand Tool...", "mode=Legacy tolerance=0"); setForegroundColor(255,255,255); setBackgroundColor(0,0,0); run("Options...", "iterations=1 count=1 black edm=Overwrite do=Nothing"); // "choose target image" --------------------------------------------------------------------------------------- selectWindow("separators"); getDimensions(width1, height1, channels1, slices1, frames1); features = getTitle(); // "choose reference image" --------------------------------------------------------------------------------------- selectWindow("erosion"); getDimensions(width2, height2, channels2, slices2, frames2); if (width1!=width2 || height1!=height2) { exit("images need to be of same size"); } else { selector = getTitle(); run("Duplicate...", "title=mask"); selectWindow("mask"); up = getTitle(); run("Set Measurements...", "area bounding display redirect=None decimal=3"); selectWindow(features); setPasteMode("AND"); run("Select All"); run("Copy"); selectWindow(up); run("Paste"); run("Make Binary"); run("Ultimate Points"); setAutoThreshold("Default dark"); //run("Threshold..."); setThreshold(1, 255); run("Convert to Mask"); //analyze ultimate points run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Nothing display clear record"); //get ultimate point positions newImage("Output", "8-bit Black", width2, height2, 1); setTool("wand"); setPasteMode("Copy"); rows=nResults(); for (i=0;i<rows;i++) { selectWindow(features); x=getResult("BX",i); y=getResult("BY",i); //mark ultimate points in query image doWand(x, y); run("Copy"); selectWindow("Output"); run("Restore Selection"); run("Paste"); setTool("rectangle"); } } } } //----------------------------------------------------------------------------- // Speckle Inspector; developed by Jan Brocher/BioVoxxel, 2013 v1.1 // Future versions will work on stacks and inside ROIs //----------------------------------------------------------------------------- function SpeckleInspector() { //Define variables positive=0; negative=0; less=0; more=0; PosPart=0; NegLess=0; NegMore=0; sizemax="infinity"; list=0; if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } //Define Preferences!!! Dialog.create("Setup"); Dialog.addNumber("Speckles no. min: ", 0); Dialog.addNumber("Speckles no. max: ", 99999); Dialog.addNumber("Speckles size min: ", 0); Dialog.addNumber("Speckles size max: ", 99999); Dialog.addNumber("Feature size min: ", 0); Dialog.addNumber("Feature size max: ", 99999); Dialog.addNumber("Circularity min: ", 0.00); Dialog.addNumber("Circularity max: ", 1.00); Dialog.addCheckbox("exclude edge particles", true); Dialog.addCheckbox("show speckle list", false); Dialog.addHelp("www.biovoxxel.de/macros.html"); Dialog.show(); min=Dialog.getNumber(); max=Dialog.getNumber(); SpeckleMin=Dialog.getNumber(); SpeckleMax=Dialog.getNumber(); sizemin=Dialog.getNumber(); sizemaximum=Dialog.getNumber(); if (sizemaximum==9999) { sizemax="Infinity"; } CircMin=Dialog.getNumber(); CircMax=Dialog.getNumber(); edge=Dialog.getCheckbox(); SpeckleList=Dialog.getCheckbox(); // "choose image containing the small features (speckles)" ----------------------------------------------------- waitForUser("Click on image containing speckles and Ok"); getDimensions(width1, height1, channels1, slices1, frames1); target = getTitle(); binary1 = is("binary"); if (binary1!=1) { exit("works only with binary images"); } run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); run("Select None"); // "choose image containing the big features enclosing the speckles" ---------------------------------------------------------------------------------------cell waitForUser("Click on image containing features and Ok"); getDimensions(width2, height2, channels2, slices2, frames2); reference=getTitle(); binary1 = is("binary"); if (binary1!=1) { exit("works only with binary images"); } run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); run("Select None"); if (width1!=width2 || height1!=height2) { exit("images need to be of same size"); } else { run("Set Measurements...", "area bounding centroid center redirect=None decimal=3"); selectWindow(reference); //analyze center points of features List.clear; roiManager("reset"); if (edge==0) { run("Analyze Particles...", "size=sizemin-sizemax circularity=CircMin-CircMax show=Nothing display clear record"); } else if (edge==1) { run("Analyze Particles...", "size=sizemin-sizemax circularity=CircMin-CircMax show=Nothing display exclude clear record"); } rows=nResults(); //get center point positions selectWindow(reference); for (i=0;i<rows;i++) { x=getResult("X",i); y=getResult("Y",i); doWand(x, y); roiManager("Add"); roiManager("Select", i); roiManager("Rename",(i+1)); } IJ.renameResults("CentroidList"); if (SpeckleList==1) {run("Table...", "name=Speckles width=300 height=500");} //analyze particle number in target image List.clear selectWindow(target); for (t=0;t<rows;t++) { roiManager("Select", t); run("Analyze Particles...", "size=SpeckleMin-SpeckleMax circularity=0.00-1.00 show=Nothing display clear record"); particles=nResults(); List.set(t, particles); if (SpeckleList==1) { print("[Speckles]","Feature: "+(t+1)+" Speckle no.: "+particles); } } //mark reference slide selectWindow(reference); run("Select None"); run("Duplicate...", "title=Output"); selectWindow("Output"); run("RGB Color"); for (RefObj=0;RefObj<rows;RefObj++) { PartAnal=List.getValue(RefObj); roiManager("Select", RefObj); //included objects if (PartAnal>=min && PartAnal<=max) { setForegroundColor(255,0,255); roiManager("Fill"); positive=positive+1; PosPart=PosPart+PartAnal; } //excluded objects else if (PartAnal<min) { setForegroundColor(0,0,255); roiManager("Fill"); less=less+1; NegLess=NegLess+PartAnal; } else if (PartAnal>max) { setForegroundColor(0,93,0); roiManager("Fill"); more=more+1; NegMore=NegMore+PartAnal; } } selectWindow("Results"); run("Close"); //result selectWindow("Output"); end=roiManager("count"); IJ.renameResults("CentroidList","Results") selectWindow("Output"); for (label=0;label<end;label++) { CX=getResult("X",label); CY=getResult("Y",label); PartNum=List.getValue(label); setColor(255,255,255); setFont("SansSerif", 10, "bold"); drawString((label+1)+"-("+PartNum+")",CX-12,CY+7); } selectWindow("Results"); run("Close"); //Statistics output print("Speckle no. limit min: " + min + " / max: " + max); print("Speckle size limit min: " + SpeckleMin + " / max: " + SpeckleMax); print("Feature size limit min: " + sizemin + " / max: " + sizemaximum); print("Circularity limit min: " + CircMin + " / max: " + CircMax); print("----------------------------------------------------"); print("White features are excluded from the analysis"); print("All Features: " + rows); print("All Speckles: " + (PosPart+NegLess+NegMore)); print("Aver. speckle no/feature (all): " + ((PosPart+NegLess+NegMore)/rows)); print("----------------------------------------------------"); print("Selected Features (magenta): " + positive); print(" All speckles in pos. features: " + PosPart); print(" Aver. speckle no/pos feature: " + (PosPart/positive)); print(""); print("Features with speckle no. smaller min (blue): " + less); print(" All speckles: " + NegLess); print(" Aver. speckle no/feature: " + (NegLess/less)); print(""); print("Features with speckle no. higher max (green): " + more); print(" All speckles: " + NegMore); print(" Aver. speckle no/feature: " + (NegMore/more)); print("----------------------------------------------------"); print(" Speckle Inspector developed by BioVoxxel/Dr. Jan Brocher, 2013 (v1.1)"); selectWindow("Output"); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // Difference of Gaussian, by Jan Brocher/BioVoxxel 2012 // Developed after a description from J. Russ (The Image Processing Handbook, 6th Ed.) //------------------------------------------------------------------------------ function DifferenceOfGaussian() { title=getTitle(); if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } selectWindow(title); newtitle="DoG of " + title; Dialog.create("Gaussian Blur"); Dialog.addMessage("Choose Gaussian Blur settings"); Dialog.addNumber("smaller sigma:", 1); Dialog.addNumber("greater sigma (3-6x higher):", 3); Dialog.show(); sig1 = Dialog.getNumber(); sig2 = Dialog.getNumber(); //factor = Dialog.getChoice(); setBatchMode(true); run("Duplicate...", "title=DoG"); rename(newtitle); run("Duplicate...", "title=intermediate"); selectWindow("intermediate"); run("Gaussian Blur...", "sigma=sig2"); run("Select All"); run("Copy"); selectWindow(newtitle); run("Gaussian Blur...", "sigma=sig1"); setPasteMode("Subtract"); setBatchMode(false); run("Paste"); exit(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //Difference of Median, by Jan Brocher 2012 //------------------------------------------------------------------------------ function DifferenceOfMedian() { title=getTitle(); if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } selectWindow(title); Dialog.create("Median Blur"); Dialog.addMessage("Choose Median Blur settings"); Dialog.addNumber("sigma:", 2); sig = Dialog.getNumber(); Dialog.show(); setBatchMode(true); selectWindow(title); run("Duplicate...", "title=DoMed"); newtitle="DoMed of " + title; rename(newtitle); run("Median...", "sigma=sig"); selectWindow(title); run("Select All"); run("Copy"); selectWindow(newtitle); setPasteMode("Difference"); setBatchMode(false); run("Paste"); exit(); } //------------------------------------------------------------------------------ // EDM Erosion //------------------------------------------------------------------------------ function EDMerosion() { title=getTitle(); if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } selectWindow(title); getLocationAndSize(x, y, width, height); Dialog.create("EDM Erosion"); Dialog.addNumber("Pixels to erode:", 1); Dialog.show(); erosion=Dialog.getNumber(); run("Options...", "iterations=1 count=1 black edm=8-bit do=Nothing"); run("Distance Map"); rename("Eroded " + title); //run("Threshold..."); setThreshold(1+erosion, 255); run("Convert to Mask"); setLocation(x+50, y+50); exit(); } //------------------------------------------------------------------------------ // EDM Dilation //------------------------------------------------------------------------------ function EDMdilate() { title=getTitle(); if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } selectWindow(title); getLocationAndSize(x, y, width, height); Dialog.create("EDM Dilate"); Dialog.addNumber("Pixels to dilate:", 1); Dialog.show(); dilate=Dialog.getNumber(); run("Options...", "iterations=1 count=1 black edm=8-bit do=Nothing"); selectWindow(title); run("Invert"); run("Distance Map"); setLocation(x+50, y+50); rename("Dilated " + title); //run("Threshold..."); setThreshold(0, dilate); run("Convert to Mask"); selectWindow(title); run("Invert"); selectWindow("Dilated " + title); exit(); } //-------------------------------------------------------------------------------------------------- // The macro masks images and stacks with binary counterparts // developed by Jan Brocher/BioVoxxel 2013 // first version 0.2 (26/04/2013) //-------------------------------------------------------------------------------------------------- function AutoMasking() { if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } Dialog.create("Masking Setup"); Dialog.addChoice("Set transparent", newArray("white", "black"), "white"); Dialog.show(); transparence=Dialog.getChoice(); // "choose first image" --------------------------------------------------------------------------------------- waitForUser("Select image containing features and click Ok"); name1 = getTitle(); type1 = bitDepth(); getDimensions(width1, height1, channels1, slices1, frames1); if(Stack.isHyperstack==true) { exit("does not work on hyperstacks"); } // "choose second image" --------------------------------------------------------------------------------------- waitForUser("Select the mask and click Ok"); dir = getDirectory("image"); name2 = getTitle(); type2 = bitDepth(); getDimensions(width2, height2, channels2, slices2, frames2); if(Stack.isHyperstack==true) { exit("does not work on hyperstacks"); } if (width1!=width2 || height1!=height2 || channels1!=channels2 || slices1!=slices2 || frames1!=frames2) { exit("Stacks need to have the same dimensions"); } else { n = 1; setBatchMode(true); selectWindow(name1); run("Select None"); run("Duplicate...", "title=["+name1+"-masked] duplicate channels=1-channels1 slices=1-slices1 frames=1-frames1"); //try to make it work with hyperstacks //can use image calculator on hyperstacks but only transparent-zero available while (n<=slices1) { selectWindow(name1); if (type1!=24) { run("RGB Color"); } setSlice(n); setPasteMode("Copy"); run("Select All"); run("Copy"); selectWindow(name1+"-masked"); setSlice(n); run("Select All"); run("Paste"); selectWindow(name2); if (type2!=24) { run("RGB Color"); } setSlice(n); if (transparence=="white") { setPasteMode("Transparent-white"); } else if (transparence=="black"){ setPasteMode("Transparent-zero"); } run("Select All"); run("Copy"); selectWindow(name1+"-masked"); setSlice(n); run("Select All"); run("Paste"); n = n + 1; } selectWindow(name1+"-masked"); setSlice(1); setBatchMode(false); } } //--------------------------------------------------------------------------------------- // Automatic Threshold Checker, developed by Jan Brocher/BioVoxxel 2012 //--------------------------------------------------------------------------------------- function ThresholdChecker() { if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } run("Options...", "iterations=1 count=1 black edm=Overwrite"); // "choose original image" ----------------------------------------------------- waitForUser("Click on original image and Ok"); getDimensions(width1, height1, channels1, slices1, frames1); original = getTitle(); run("Select None"); // "choose threshold montage" -------------------------------------------------- waitForUser("Click on montage of thresholds and Ok"); getDimensions(width2, height2, channels2, slices2, frames2); montage=getTitle(); run("HiLo"); run("Select None"); Dialog.create("Montage Dimensions"); Dialog.addNumber("images per row", 4); Dialog.addNumber("images per column", 4); Dialog.addNumber("% saturation", 0); Dialog.addCheckbox("dark feature on bright background", false); Dialog.show; row=Dialog.getNumber(); col=Dialog.getNumber(); sat=Dialog.getNumber(); dark=Dialog.getCheckbox(); setBatchMode(true); selectWindow(montage); run("Montage to Stack...", "images_per_row=row images_per_column=col border=1"); rename("Threshold Check"); stack=getTitle(); slices=nSlices(); run("RGB Color"); setPasteMode("Blend"); selectWindow(original); run("Duplicate...", "title=Duplicate"); selectWindow("Duplicate"); if(dark==1) { run("Invert"); } run("Green"); run("Enhance Contrast...", "saturated="+sat+" normalize"); run("Select All"); run("Copy"); selectWindow(stack); run("Restore Selection"); makeRectangle(0, 0, width1, height1); for (i=1;i<=slices;i++) { setSlice(i); run("Paste"); } setSlice(1); setBatchMode(false); exit(); } //------------------------------------------------------------------------------------------------------------------------------------- // Contrast Detection, developed by Jan Brocher/BioVoxxel 2013 //------------------------------------------------------------------------------------------------------------------------------------- function ContrastDetection() { if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } setPasteMode("Copy"); original=getTitle(); getDimensions(width, height, channels, slices, frames); type=bitDepth(); if(slices>1) { exit("works only with individual images so far"); } Dialog.create("Contrast Setup"); Dialog.addNumber("radius", 1); Dialog.addCheckbox("enhance edges in original", false); Dialog.addCheckbox("enhance contrast", true); Dialog.addNumber("contrast saturation", 1); Dialog.addCheckbox("final maxima filter", false); Dialog.addCheckbox("inverse", false); Dialog.show(); r=Dialog.getNumber(); sharpen=Dialog.getCheckbox(); contrast=Dialog.getCheckbox(); satur=Dialog.getNumber(); finalFilter=Dialog.getCheckbox(); inverse=Dialog.getCheckbox(); setBatchMode(true); run("Duplicate...", "title=Minimum"); run("Conversions...", "scale weighted"); if(type==24) { run("8-bit"); } Minimum=getTitle(); run("Duplicate...", "title=Maximum"); if(type==24) { run("8-bit"); } Maximum=getTitle(); selectWindow(Minimum); run("Minimum...", "radius=r"); selectWindow(Maximum); run("Maximum...", "radius=r"); setPasteMode("Difference"); selectWindow(original); run("Select All"); run("Copy"); selectWindow(Minimum); run("Paste"); selectWindow(Maximum); run("Paste"); setPasteMode("Subtract"); if(inverse==true || sharpen==true) { selectWindow(Minimum); } else { selectWindow(Maximum); } run("Select All"); run("Copy"); if(inverse==true || sharpen==true) { selectWindow(Maximum); rename(original + "_Minima_r("+r+")"); } else { selectWindow(Minimum); rename(original + "_Maxima_r("+r+")"); } resultWindow=getTitle(); run("Paste"); if(sharpen==true) { selectWindow(resultWindow); run("Select All"); run("Copy"); selectWindow(original); run("Duplicate...", "title=Enhanced_"+original); run("Select All"); run("Paste"); } if(contrast==true && sharpen==false) { selectWindow(resultWindow); run("Enhance Contrast...", "saturated=satur normalize"); } if(finalFilter==true) { run("Minimum...", "radius=0.5"); } setBatchMode(false); } //----------------------------------------------------------------------------------------------------------------------------------------- //Hyperstack Color-coding //Based on the idea of the temporal color coding from the macro of Kota Miura and Johannes Schindelin //Offers the choice to code time or volume in a hyperstack //Keeps the color coded Hyperstack in addition to a color coded Z-projection stack. Z-Projection type can be selected //Author: Jan Brocher/BioVoxxel, 2013 //Version: 0.1 (25/04/2013) //----------------------------------------------------------------------------------------------------------------------------------------- function HyperstackColorCoding() { //read input original=getTitle(); type=Stack.isHyperstack; BitDepth=bitDepth(); run("Select None"); if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } if (BitDepth!=8) { exit("works only with 8-bit images"); } getLut(r, g, b); getDimensions(width, height, channels, slices, frames); if(channels>1) { exit("does not work with multi-channel stacks"); } setPasteMode("Copy"); //Setup dialog Dialog.create("Dimension Choice"); if(type==true) { Dialog.addChoice("Color code", newArray("Time", "Volume"), "Time"); } else if (slices==1) { Dialog.addChoice("Color code", newArray("Time")); } else if (frames==1) { Dialog.addChoice("Color code", newArray("Volume")); } Dialog.addChoice("LUT", newArray("Spectrum", "Rainbow RGB", "Fire", "Ice", "16_colors", "cool", "Green Fire Blue"), "Spectrum"); if(slices>1) { Dialog.addCheckbox("Z-Projection", true); Dialog.addChoice("Projection type", newArray("Average Intensity", "Max Intensity", "Min Intensity", "Sum Slices", "Standard Deviation", "Median"), "Max Intensity"); Dialog.addCheckbox("All time frames", true); } Dialog.addCheckbox("Calibration bar", false); Dialog.show(); Dimension=Dialog.getChoice(); LUT=Dialog.getChoice(); if(slices>1) { ZProject=Dialog.getCheckbox(); ProjectType=Dialog.getChoice(); ProjectionFrames=Dialog.getCheckbox(); } else { ZProject=false; } CalBar=Dialog.getCheckbox(); //creation of output stack run("Hyperstack...", "title=Colored_"+Dimension+"_"+original+" type=RGB display=Composite width="+width+" height="+height+" channels="+channels+" slices="+slices+" frames="+frames); output=getTitle(); selectWindow(original); run(LUT); getLut(Oreds, Ogreens, Oblues); //calling the color coding function ColorCoding(); if (CalBar==true) { CalibrationBar(); } function ColorCoding() { if (Dimension=="Time") { n=frames; runs=slices; } else if (Dimension=="Volume") { n=slices; runs=frames; } reds=newArray(256); greens=newArray(256); blues=newArray(256); setBatchMode(true); for (hyper=1; hyper<=runs; hyper++) { for (i=1; i<=n; i++) { if (Dimension=="Time") { Stack.setSlice(hyper); Stack.setFrame(i); } else if (Dimension=="Volume") { Stack.setFrame(hyper); Stack.setSlice(i); } color=floor((255/n)*i); for (loop=0; loop<256; loop++) { f=(loop/255); reds[loop]=round(Oreds[color]*f); greens[loop]=round(Ogreens[color]*f); blues[loop]=round(Oblues[color]*f); } selectWindow(original); if (Dimension=="Time") { Stack.setSlice(hyper); Stack.setFrame(i); } else if (Dimension=="Volume") { Stack.setFrame(hyper); Stack.setSlice(i); } setLut(reds, greens, blues); run("Select All"); run("Copy"); selectWindow(output); if (Dimension=="Time") { Stack.setSlice(hyper); Stack.setFrame(i); } else if (Dimension=="Volume") { Stack.setFrame(hyper); Stack.setSlice(i); } run("Paste"); } } Stack.setFrame(1); Stack.setSlice(1); if (ZProject==true) { selectWindow(output); if(ProjectionFrames==true) { run("Z Project...", "start=1 stop="+slices+" projection=["+ProjectType+"] all"); } else { run("Z Project...", "start=1 stop="+slices+" projection=["+ProjectType+"]"); } } setBatchMode(false); selectWindow(original); setLut(r, g, b); Stack.setFrame(1); Stack.setSlice(1); } function CalibrationBar() { if (Dimension=="Time") { n=frames; } else if (Dimension=="Volume") { n=slices; } newImage("Calibration Bar", "8-bit Ramp", 256, 35, 1); run(LUT); setBackgroundColor(255, 255, 255); run("RGB Color"); run("Canvas Size...", "width=256 height=50 position=Top-Center"); setFont("SansSerif", 12, "bold"); setColor(0, 0, 0); if (Dimension=="Time") { drawString("1", 2, 49); if(n<100) { drawString(n, 240, 49); } else { drawString(n, 230, 49); } } else if (Dimension=="Volume") { run("Rotate 90 Degrees Right"); drawString("1", 1, 13); drawString(n, 1, 255); } } } //----------------------------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------------------------- function About() { if(isOpen("Log")==1) { selectWindow("Log"); run("Close"); } Dialog.create("About"); Dialog.addMessage("All Macros/Plugins in this BioVoxxel Menu were written\nby Jan Brocher/BioVoxxel.\n \nYou can freely use, redistribute, and alter this software if it serves your purpose.\nNotice of own improvements or suggestions for improvements are wellcome.\nIf you publish results gained by the use of this toolset\nplease acknowledge Jan Brocher and BioVoxxel! \n \nFor questions please contact: jan.brocher@biovoxxel.de\n \nMore information under: www.biovoxxel.de or click on 'Help'"); Dialog.addHelp("www.biovoxxel.de/macros.html"); Dialog.show(); }