How to overlay analyzed particles with geometry measurements?

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.

@tmf32

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 :slight_smile:

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:

2 Likes

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)
1 Like