Hi everyone,
I am using segmentation and the Analyze Particles tool to successfully measure the geometry parameters of epithelial cells. I was wondering if someone could suggest a way on FIJI that I could plot the cell geometry values that were calculated by Analyze Particles on the segmented image? In particular I would like to draw on each segmented object an arrow representing the aspect ratio vector (direction representing long axis, length representing aspect ratio).
Any help much appreciated.
Not sure how to display exactly what you want without coding it - but you can look into the BioVoxxel toolbox. There is a great tool using Shape Descriptor Maps that should work for displaying/plotting your aspect ratio calculations:
I hope this can help!
Too - there are tons of great tools in Biovoxxel - including an Extended Particle Analyzer you might find helpful.
eta
I recommend to create an Overlay to do this.
Provided you have a Results table with the measurements for Centroid, Shape descriptors and Feret’s diameter (see Analyze > Set Measurements…), you can use the following Groovy script (simply run it from the script editor after choosing Language > Groovy):
// @ImagePlus imp
import ij.gui.Arrow
import ij.gui.Overlay
import ij.measure.ResultsTable
def Arrow getArrow(x, y, angle, length) {
dx = length * Math.cos(Math.toRadians(angle))
dy = length * Math.sin(Math.toRadians(angle))
return new Arrow(x, y, x+dx, y+dy)
}
rt = ResultsTable.getResultsTable()
overlay = new Overlay()
for (i in 0..<rt.getCounter()) {
x = rt.getValue("X", i)
y = rt.getValue("Y", i)
angle = rt.getValue("FeretAngle", i)
length = rt.getValue("AR", i) * 10
arrow = getArrow(x, y, 180-angle, length)
arrow.setHeadSize(5.0)
overlay.add(arrow)
}
imp.setOverlay(overlay)
For the Blobs sample image, this will result in something like this:
Nice!
Here’s a slightly updated version based on the fit ellipses, with normalized arrows length.
// @ImagePlus imp
import ij.gui.Arrow
import ij.gui.Overlay
import ij.measure.ResultsTable
def Arrow getArrow(x, y, angle, length) {
dx = length * Math.cos(Math.toRadians(angle)) / 2
dy = length * Math.sin(Math.toRadians(angle)) / 2
return new Arrow(x-dx, y-dy, x+dx, y+dy)
}
rt = ResultsTable.getResultsTable()
// Check if fit ellipse was evaluated
if(!(rt.getColumnHeadings().contains("Major"))){
throw new IllegalArgumentException("No fit ellipse measurement found in the Results Table.")
}
overlay = new Overlay()
for (i in 0..<rt.getCounter()) {
x = rt.getValue("X", i)
y = rt.getValue("Y", i)
angle = rt.getValue("Angle", i)
length = rt.getValue("Major", i) - rt.getValue("Minor", i)
arrow = getArrow(x, y, 180-angle, length)
arrow.setHeadSize(5.0)
overlay.add(arrow)
}
imp.setOverlay(overlay)