Hi guys,
I have gray sem images of gold nanoparticles on a glass surface. Due to various aspects of the SEM, it tends to be rather difficult for us to get extremely clear resolution for particle boundaries, and the sizes of the particles are quite sensitive to manual thresholding. I know that there are a few builtin tools (like watershedding) to help resolve the separation of neighboring particles, and there are likely several plugins that I'm not aware of that could be useful helpful. My goal is basically as follows: Choose the "optimal" threshold that retains small particle-particle separations but does not undersize the particles. Higher thresholds encapsulate the full particles but also degrade specificity in boundaries. I'm basically amenable to any plugins or tools that could help me get more accurate particle counts and size estimations, and thought maybe you guys would know of some plugins/filters or other tools that I'm not aware of. And on a final note, can you guys think of a way to identify x-sized regions that are unoccupied? You can see in the image there are a few big spaces where not particles occupy the area. If I had a scale set and wanted imagej to find any region with no particles in it that exceeds, say, 100 square nanometers, is something like this directly possible? Thanks. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Try the following (recorded with the macro recorder):
run("Smooth"); run("Smooth"); run("Find Maxima...", "noise=5 output=[Segmented Particles] exclude"); imageCalculator("AND create", "sem_test.png","sem_test.png Segmented"); I attached the result of the AND and the output of the find maxima command. Edge maxima are excluded. Depending on the variation between images , you may need to vary the noise threshold. --aryeh On 3/11/13 11:11 PM, Adam Hughes wrote: > Hi guys, > > I have gray sem images of gold nanoparticles on a glass surface. Due to > various aspects of the SEM, it tends to be rather difficult for us to get > extremely clear resolution for particle boundaries, and the sizes of the > particles are quite sensitive to manual thresholding. > > I know that there are a few builtin tools (like watershedding) to help > resolve the separation of neighboring particles, and there are likely > several plugins that I'm not aware of that could be useful helpful. > > My goal is basically as follows: > > Choose the "optimal" threshold that retains small particle-particle > separations but does not undersize the particles. > > Higher thresholds encapsulate the full particles but also degrade > specificity in boundaries. > > I'm basically amenable to any plugins or tools that could help me get more > accurate particle counts and size estimations, and thought maybe you guys > would know of some plugins/filters or other tools that I'm not aware of. > > And on a final note, can you guys think of a way to identify x-sized > regions that are unoccupied? You can see in the image there are a few big > spaces where not particles occupy the area. If I had a scale set and > wanted imagej to find any region with no particles in it that exceeds, say, > 100 square nanometers, is something like this directly possible? > > Thanks. > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- Aryeh Weiss Faculty of Engineering Bar Ilan University Ramat Gan 52900 Israel Ph: 972-3-5317638 FAX: 972-3-7384051 -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html ![]() ![]() |
Thanks!
On Tue, Mar 12, 2013 at 1:14 AM, Aryeh Weiss <[hidden email]> wrote: > Try the following (recorded with the macro recorder): > > run("Smooth"); > run("Smooth"); > run("Find Maxima...", "noise=5 output=[Segmented Particles] exclude"); > imageCalculator("AND create", "sem_test.png","sem_test.png Segmented"); > > I attached the result of the AND and the output of the find maxima command. > Edge maxima are excluded. > > Depending on the variation between images , you may need to vary the noise > threshold. > > --aryeh > > > > On 3/11/13 11:11 PM, Adam Hughes wrote: > >> Hi guys, >> >> I have gray sem images of gold nanoparticles on a glass surface. Due to >> various aspects of the SEM, it tends to be rather difficult for us to get >> extremely clear resolution for particle boundaries, and the sizes of the >> particles are quite sensitive to manual thresholding. >> >> I know that there are a few builtin tools (like watershedding) to help >> resolve the separation of neighboring particles, and there are likely >> several plugins that I'm not aware of that could be useful helpful. >> >> My goal is basically as follows: >> >> Choose the "optimal" threshold that retains small particle-particle >> separations but does not undersize the particles. >> >> Higher thresholds encapsulate the full particles but also degrade >> specificity in boundaries. >> >> I'm basically amenable to any plugins or tools that could help me get more >> accurate particle counts and size estimations, and thought maybe you guys >> would know of some plugins/filters or other tools that I'm not aware of. >> >> And on a final note, can you guys think of a way to identify x-sized >> regions that are unoccupied? You can see in the image there are a few big >> spaces where not particles occupy the area. If I had a scale set and >> wanted imagej to find any region with no particles in it that exceeds, >> say, >> 100 square nanometers, is something like this directly possible? >> >> Thanks. >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.**html<http://imagej.nih.gov/ij/list.html> >> >> > > -- > Aryeh Weiss > Faculty of Engineering > Bar Ilan University > Ramat Gan 52900 Israel > > Ph: 972-3-5317638 > FAX: 972-3-7384051 > > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.**html<http://imagej.nih.gov/ij/list.html> > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Aryeh Weiss
Hello,
You will find enclosed a macro to run on your image. Using “Laplacian of Gaussian” we create a mask and then identify particles. From the coordinates of these particles, the macro draws a mask to connect particles that are closer, to each other, than a user defined threshold (40 pixels). This allows for the identification of empty areas (define a Threshold size, 500 pixel^2). We just “chose” values for parameters mentioned above; you may have to adjust them. We hope this would help, Thanks a lot for this study case :D Romain and Olivier ///////////////////////////////////////////////////////////////////////////////// //macro_start //clear Results, ROIs, set Foreground White run("Clear Results"); roiManager("Reset"); setForegroundColor(255, 255, 255); //GetImageTitle, create a newImage with same dimensions title=getTitle(); getDimensions(width, height, channels, slices, frames); run("Duplicate...", "title=16-bit"); newImage("Draw", "8-bit Black", width, height, 1); selectWindow(title); //Image is RGB, convert to 16-bit run("16-bit"); //Extracting blob-like Features using "Lapalcian of Gaussian" run("FeatureJ Laplacian", "compute smoothing=2"); rename("Mask"); //Threshold, Watershed and Erode (improve blob separation) setAutoThreshold("Default"); run("Convert to Mask"); run("Watershed"); run("Options...", "iterations=2 count=4 black edm=Overwrite do=Erode"); //Analyze particles run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Nothing display exclude summarize add"); roiManager("Show All without labels"); roiManager("Show All"); ////////////////////////////////////////////// // Identify empty areas // Adjust these values to your needs //Set "distance threshold" value //and Empty Area minimal size distanceThreshold = 40; emptyMinimalArea=500; //get center of Mass of each particles roiNumber = roiManager("count"); xCoordinates = newArray(roiNumber); yCoordinates = newArray(roiNumber); for (i=0; i< roiNumber ; i++){ xCoordinates[i]= getResult("XM",i) ; yCoordinates[i]= getResult("YM",i) ; } //Measure Distance, if under a distance Threshold => draw a line. setBatchMode(true); for (ii=0; ii< roiNumber ; ii++){ xRef = xCoordinates[ii]; yRef = yCoordinates[ii]; distance = newArray(roiNumber); for (iii=ii+1; iii< roiNumber ; iii++){ distance[iii]=sqrt(pow((xRef-xCoordinates[iii] ),2) + pow((yRef-yCoordinates[iii]),2)); if (distance[iii] < distanceThreshold){ selectWindow("Draw"); drawLine(xRef, yRef, xCoordinates[iii], yCoordinates[iii]); } } } setBatchMode(false); selectWindow("Draw"); run("Duplicate...", "title=Empty Areas"); //threshold and binary Open to "thicken" drawn lines. (help analyze particles) setThreshold(0, 128); run("Convert to Mask"); run("Options...", "iterations=1 count=1 black pad edm=Overwrite do=Erode"); //Analyze particles find empty areas run("Analyze Particles...", "size="+emptyMinimalArea+"-Infinity circularity=0.00-1.00 show=Nothing display exclude summarize add"); selectWindow(title); roiManager("Show All without labels"); roiManager("Show All"); //macro_end /////////////////////////////////////////////////////////////////////////////////////////// --------------------------------------------------------------- Dr. Romain Guiet Bioimaging and Optics Platform (PT-BIOP) Ecole Polytechnique Fédérale de Lausanne (EPFL) Faculty of Life Sciences Station 19, AI 0241 CH-1015 Lausanne Phone: [+4121 69] 39629 http://biop.epfl.ch/ --------------------------------------------------------------- ________________________________________ De : ImageJ Interest Group [[hidden email]] de la part de Aryeh Weiss [[hidden email]] Date d'envoi : mardi 12 mars 2013 06:14 À : [hidden email] Objet : Re: Optimal plugins and tools to this type of image Try the following (recorded with the macro recorder): run("Smooth"); run("Smooth"); run("Find Maxima...", "noise=5 output=[Segmented Particles] exclude"); imageCalculator("AND create", "sem_test.png","sem_test.png Segmented"); I attached the result of the AND and the output of the find maxima command. Edge maxima are excluded. Depending on the variation between images , you may need to vary the noise threshold. --aryeh On 3/11/13 11:11 PM, Adam Hughes wrote: > Hi guys, > > I have gray sem images of gold nanoparticles on a glass surface. Due to > various aspects of the SEM, it tends to be rather difficult for us to get > extremely clear resolution for particle boundaries, and the sizes of the > particles are quite sensitive to manual thresholding. > > I know that there are a few builtin tools (like watershedding) to help > resolve the separation of neighboring particles, and there are likely > several plugins that I'm not aware of that could be useful helpful. > > My goal is basically as follows: > > Choose the "optimal" threshold that retains small particle-particle > separations but does not undersize the particles. > > Higher thresholds encapsulate the full particles but also degrade > specificity in boundaries. > > I'm basically amenable to any plugins or tools that could help me get more > accurate particle counts and size estimations, and thought maybe you guys > would know of some plugins/filters or other tools that I'm not aware of. > > And on a final note, can you guys think of a way to identify x-sized > regions that are unoccupied? You can see in the image there are a few big > spaces where not particles occupy the area. If I had a scale set and > wanted imagej to find any region with no particles in it that exceeds, say, > 100 square nanometers, is something like this directly possible? > > Thanks. > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- Aryeh Weiss Faculty of Engineering Bar Ilan University Ramat Gan 52900 Israel Ph: 972-3-5317638 FAX: 972-3-7384051 -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Aryeh Weiss
Hello,
You will find below a macro to run on your image ( I encounted ome trouble with the previous mail...) Using “Laplacian of Gaussian” we create a mask and then identify particles. From the coordinates of these particles, the macro draws a mask to connect particles that are closer, to each other, than a user defined threshold (40 pixels). This allows for the identification of empty areas (define a Threshold size, 500 pixel^2). We just “chose” values for parameters mentioned above; you may have to adjust them. We hope this would help, Thanks a lot for this study case :D Romain and Olivier ///////////////////////////////////////////////////////////////////////////////// //macro_start //clear Results, ROIs, set Foreground White run("Clear Results"); roiManager("Reset"); setForegroundColor(255, 255, 255); //GetImageTitle, create a newImage with same dimensions title=getTitle(); getDimensions(width, height, channels, slices, frames); run("Duplicate...", "title=16-bit"); newImage("Draw", "8-bit Black", width, height, 1); selectWindow(title); //Image is RGB, convert to 16-bit run("16-bit"); //Extracting blob-like Features using "Lapalcian of Gaussian" run("FeatureJ Laplacian", "compute smoothing=2"); rename("Mask"); //Threshold, Watershed and Erode (improve blob separation) setAutoThreshold("Default"); run("Convert to Mask"); run("Watershed"); run("Options...", "iterations=2 count=4 black edm=Overwrite do=Erode"); //Analyze particles run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Nothing display exclude summarize add"); roiManager("Show All without labels"); roiManager("Show All"); ////////////////////////////////////////////// // Identify empty areas // Adjust these values to your needs //Set "distance threshold" value //and Empty Area minimal size distanceThreshold = 40; emptyMinimalArea=500; //get center of Mass of each particles roiNumber = roiManager("count"); xCoordinates = newArray(roiNumber); yCoordinates = newArray(roiNumber); for (i=0; i< roiNumber ; i++){ xCoordinates[i]= getResult("XM",i) ; yCoordinates[i]= getResult("YM",i) ; } //Measure Distance, if under a distance Threshold => draw a line. setBatchMode(true); for (ii=0; ii< roiNumber ; ii++){ xRef = xCoordinates[ii]; yRef = yCoordinates[ii]; distance = newArray(roiNumber); for (iii=ii+1; iii< roiNumber ; iii++){ distance[iii]=sqrt(pow((xRef-xCoordinates[iii] ),2) + pow((yRef-yCoordinates[iii]),2)); if (distance[iii] < distanceThreshold){ selectWindow("Draw"); drawLine(xRef, yRef, xCoordinates[iii], yCoordinates[iii]); } } } setBatchMode(false); selectWindow("Draw"); run("Duplicate...", "title=Empty Areas"); //threshold and binary Open to "thicken" drawn lines. (help analyze particles) setThreshold(0, 128); run("Convert to Mask"); run("Options...", "iterations=1 count=1 black pad edm=Overwrite do=Erode"); //Analyze particles find empty areas run("Analyze Particles...", "size="+emptyMinimalArea+"-Infinity circularity=0.00-1.00 show=Nothing display exclude summarize add"); selectWindow(title); roiManager("Show All without labels"); roiManager("Show All"); //macro_end /////////////////////////////////////////////////////////////////////////////////////////// --------------------------------------------------------------- Dr. Romain Guiet Bioimaging and Optics Platform (PT-BIOP) Ecole Polytechnique Fédérale de Lausanne (EPFL) Faculty of Life Sciences Station 19, AI 0241 CH-1015 Lausanne Phone: [+4121 69] 39629 http://biop.epfl.ch/ --------------------------------------------------------------- ________________________________________ De : ImageJ Interest Group [[hidden email]] de la part de Aryeh Weiss [[hidden email]] Date d'envoi : mardi 12 mars 2013 06:14 À : [hidden email] Objet : Re: Optimal plugins and tools to this type of image Try the following (recorded with the macro recorder): run("Smooth"); run("Smooth"); run("Find Maxima...", "noise=5 output=[Segmented Particles] exclude"); imageCalculator("AND create", "sem_test.png","sem_test.png Segmented"); I attached the result of the AND and the output of the find maxima command. Edge maxima are excluded. Depending on the variation between images , you may need to vary the noise threshold. --aryeh On 3/11/13 11:11 PM, Adam Hughes wrote: > Hi guys, > > I have gray sem images of gold nanoparticles on a glass surface. Due to > various aspects of the SEM, it tends to be rather difficult for us to get > extremely clear resolution for particle boundaries, and the sizes of the > particles are quite sensitive to manual thresholding. > > I know that there are a few builtin tools (like watershedding) to help > resolve the separation of neighboring particles, and there are likely > several plugins that I'm not aware of that could be useful helpful. > > My goal is basically as follows: > > Choose the "optimal" threshold that retains small particle-particle > separations but does not undersize the particles. > > Higher thresholds encapsulate the full particles but also degrade > specificity in boundaries. > > I'm basically amenable to any plugins or tools that could help me get more > accurate particle counts and size estimations, and thought maybe you guys > would know of some plugins/filters or other tools that I'm not aware of. > > And on a final note, can you guys think of a way to identify x-sized > regions that are unoccupied? You can see in the image there are a few big > spaces where not particles occupy the area. If I had a scale set and > wanted imagej to find any region with no particles in it that exceeds, say, > 100 square nanometers, is something like this directly possible? > > Thanks. > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- Aryeh Weiss Faculty of Engineering Bar Ilan University Ramat Gan 52900 Israel Ph: 972-3-5317638 FAX: 972-3-7384051 -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Adam Hughes
Hi Adam,
The macro from Romain and Olivier (which was a great idea) inspired me to try something similar. Here's the output. Just some specifications: 1.) it enables you to directly input the minimal size of the empty spaces you want to measure 2.) it pre-processes the image slightly (see macro code) 3.) it uses a Difference of Gaussian instead of Laplacian and lets you specify the Gaussian blurring steps (1 and 3 are default and worked fine for your sample image) --> in my opinion thus the objects/particles are thresholded a little better (but that's subjective perception). 4.) most importantly it skips the drawing step and thus defines the empty spaces only in areas which do not overlap with the objects 5.) the output shows you the interspaces characterized as overlay over the original image, you have those still in the ROI manager and get result tables for all objects as well as the characterized interspaces. Additionally you could also get an outline map of the objects with numbers by changing the "Nothing" statement in the run("Analyze..." code line to Outlines. If something does not work as expected, just send me an e-mail. And I'm sorry for the little bit chaotic code. Hope it helps you and others! Best regards, Jan (www.biovoxxel.de) And here's the code: //macro start------------------------------------------------------------------------------------------------------------------ //option settings setBatchMode(true); run("Options...", "iterations=1 count=1 black edm=Overwrite"); run("Set Measurements...", "area mean standard modal min centroid center perimeter bounding fit shape feret's integrated median skewness kurtosis area_fraction stack redirect=None decimal=3"); title=getTitle(); //Dialog to define minimal interspace size Dialog.create("Define minimal interspace size"); Dialog.addNumber("minimal interspace size (pixel^2)", 1000); Dialog.show(); minSize = Dialog.getNumber(); //Pre-processing of original image run("16-bit"); run("Median...", "radius=2"); run("Enhance Contrast...", "saturated=0 normalize"); //Calling the "Difference of Gaussian" function DifferenceOfGaussian(); //thresholding and analyzing objects selectWindow("DoG of "+title); objects=getTitle(); setAutoThreshold("Otsu dark"); run("Convert to Mask"); run("Watershed"); run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Nothing display clear"); IJ.renameResults("Objects"); //thresholding and analyzing of interspaces selectWindow(objects); run("Duplicate...", "title=Interspaces"); run("Invert"); run("Watershed"); run("Analyze Particles...", "size="+minSize+"-Infinity circularity=0.00-1.00 show=Nothing display clear add"); IJ.renameResults("Interspaces"); //Indicate interspaces over original image selectWindow(title); run("Revert"); roiManager("Show All with labels"); roiManager("Show All"); function DifferenceOfGaussian() { title=getTitle(); 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); sig1 = Dialog.getNumber(); sig2 = Dialog.getNumber(); //factor = Dialog.getChoice(); Dialog.show(); 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"); } //end------------------------------------------------------------------------------------------------------------------ -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
These suggestions are all very impressive guys. I will try some of them
out here asap. Thanks very much. On Tue, Mar 12, 2013 at 12:29 PM, Jan Brocher - BioVoxxel < [hidden email]> wrote: > Hi Adam, > > The macro from Romain and Olivier (which was a great idea) inspired me to > try something similar. Here's the output. > Just some specifications: > 1.) it enables you to directly input the minimal size of the empty spaces > you want to measure > 2.) it pre-processes the image slightly (see macro code) > 3.) it uses a Difference of Gaussian instead of Laplacian and lets you > specify the Gaussian blurring steps (1 and 3 are default and worked fine > for your sample image) --> in my opinion thus the objects/particles are > thresholded a little better (but that's subjective perception). > 4.) most importantly it skips the drawing step and thus defines the empty > spaces only in areas which do not overlap with the objects > 5.) the output shows you the interspaces characterized as overlay over the > original image, you have those still in the ROI manager and get result > tables for all objects as well as the characterized interspaces. > > Additionally you could also get an outline map of the objects with numbers > by changing the "Nothing" statement in the run("Analyze..." code line to > Outlines. > > If something does not work as expected, just send me an e-mail. And I'm > sorry for the little bit chaotic code. > > Hope it helps you and others! > Best regards, > Jan (www.biovoxxel.de) > > And here's the code: > > > //macro > start------------------------------------------------------------------------------------------------------------------ > //option settings > setBatchMode(true); > run("Options...", "iterations=1 count=1 black edm=Overwrite"); > run("Set Measurements...", "area mean standard modal min centroid center > perimeter bounding fit shape feret's integrated median skewness kurtosis > area_fraction stack redirect=None decimal=3"); > title=getTitle(); > > //Dialog to define minimal interspace size > Dialog.create("Define minimal interspace size"); > Dialog.addNumber("minimal interspace size (pixel^2)", 1000); > Dialog.show(); > minSize = Dialog.getNumber(); > > //Pre-processing of original image > run("16-bit"); > run("Median...", "radius=2"); > run("Enhance Contrast...", "saturated=0 normalize"); > > //Calling the "Difference of Gaussian" function > DifferenceOfGaussian(); > > //thresholding and analyzing objects > selectWindow("DoG of "+title); > objects=getTitle(); > setAutoThreshold("Otsu dark"); > run("Convert to Mask"); > run("Watershed"); > run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 > show=Nothing display clear"); > IJ.renameResults("Objects"); > > //thresholding and analyzing of interspaces > selectWindow(objects); > run("Duplicate...", "title=Interspaces"); > run("Invert"); > run("Watershed"); > run("Analyze Particles...", "size="+minSize+"-Infinity > circularity=0.00-1.00 show=Nothing display clear add"); > IJ.renameResults("Interspaces"); > > //Indicate interspaces over original image > selectWindow(title); > run("Revert"); > roiManager("Show All with labels"); > roiManager("Show All"); > > > function DifferenceOfGaussian() { > > title=getTitle(); > 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); > sig1 = Dialog.getNumber(); > sig2 = Dialog.getNumber(); > //factor = Dialog.getChoice(); > Dialog.show(); > 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"); > > } > > > //end------------------------------------------------------------------------------------------------------------------ > > > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |