Measuring changes in size/area in a time-series

I have a time-series (binary) with more that one object. The objects don´t move much but change size over time --> a similar dataset can be mimmicked with slice 71-76 from the bat cochlear example.

I am looking for an easy way to measure the area of each individual object over time. Possibly something like MTrack2 with area measurements in addition to the coordinates for each object in each slice. Or something completely different.

The macro below might illustrate what I mean.

Any suggestion is welcome.

run("Bat Cochlea Volume (19K)");
run("Duplicate...", "duplicate range=71-76");
run("MTrack2 ", "minimum=1 maximum=999999 maximum_=12 minimum_=2");
1 Like

I finally came up with a solution using the connected components analysis of MorpholibJ instead of MTrack2. I forgot to post this back in May, but only realize this now since this topic is taken up again in another post.

/*
 * in this example, the size of three ROIs is measured 
 * in 6 slices. Results are written to a table.
 * The macro makes use of MorpholibJ (connected compontents analysis) --> IJBP-Plugins update site needs to be activated
 * 
 */


run("Bat Cochlea Volume (19K)");
run("Duplicate...", "duplicate range=71-76");
original = getImageID();

run("Connected Components Labeling", "connectivity=26 type=[8 bits]");
run("Set Label Map", "colormap=[Mixed Colors] background=Black shuffle");
img_L = getTitle;// L = label --> each glom has its unique label (=value)

// measure the size of first ROI in all slices, write area into a table, then next ROI
// prepare results table
	slice = Array.getSequence(nSlices);  
	table1 = "Measurements";
	Table.create(table1);
	Table.setColumn("slice number", slice);

	selectWindow(img_L);

	//get number of ROIs in the image
	getMinAndMax(min, max); // max = number of labels (w/o background, background has the label number 0) = number of ROIs

// loop through all ROIs

rc = 0; //set the roiCounter rc to zero
for (i = 1; i < max+1; i++) {
	// i=1 --> ROI1
	selectWindow(img_L);
	run("Duplicate...", "duplicate");//stack is duplicated
		
	dup = getImageID;
	setThreshold(i, i);// i = label number of this ROI
	run("Convert to Mask", "method=Default background=Dark");// no new image. duplicated lbl image is converted to mask
	//run("Grays");// Lut was inverted
	// the duplicated and thresholded image contains only 1 ROI (in all slices)
	
	run("Analyze Particles...", "size=12-Infinity add stack");

	// loop through all with the label "i" ROIs	
	// --> rename rois 
	// --> measure are of this ROI at every time point, write into Table
	for (k = rc; k < roiManager("count"); k++) {
		roiManager("select", k);
		name = "ROI"+i+"_slice"+(k-rc+1);
		roiManager("rename", name);
		List.setMeasurements;
		area = List.getValue("Area");
		Table.set("ROI"+i, k-rc, area);
	}
	rc = roiManager("count");
	selectImage(dup);
	close();
	run("Select None");
	
} //next i (= next ROI, i.e. ROI(i) in all slices)

Table.update(table1);

selectImage(original);
roiManager("UseNames", "true");
roiManager("Show All with labels");
1 Like

Hi Martin,

Thank you for your generous help! However, I’m very new to this entire ImageJ thing and I really don’t know much about programming aside from MATLAB, so I am not sure what to do with your code. Do you mind giving a more specific instruction regarding the process please? Many thanks in advance!

As a start you could copy this code to the Fiji scipt editor (Plugins > New > Macro) and simply hit Run at the bottom of the scipt editor . (don´t forget to activate the IJPB-plugins update site – see chapter “installation” here).
The macro will load a sample image and measure the area of three ROIs in 6 slices and writes the results into a table.
Maybe you have more specific questions once you see what this macro actually does.

1 Like

Hi Martin,

Thanks so much for the help! It worked, but is does it have the functionality to track the position like MTrack2?

One can add any kind of measurement for the individual ROIs.
In the version below, I added measurement of the centroid coordinates for each ROI.

/*
 * in this example, the size and center coordinates of three ROIs is measured 
 * in 6 slices. 
 * Results are written to a table.
 * The macro makes use of MorpholibJ (connected compontents analysis) --> IJBP-Plugins update site needs to be activated
 * 
 */


run("Bat Cochlea Volume (19K)");
run("Duplicate...", "duplicate range=71-76");
original = getImageID();

run("Connected Components Labeling", "connectivity=26 type=[8 bits]");
run("Set Label Map", "colormap=[Mixed Colors] background=Black shuffle");
img_L = getTitle;// L = label --> each glom has its unique label (=value)

// measure the size of first ROI in all slices, write area into a table, then next ROI

// prepare results table
	slice = Array.getSequence(nSlices);  
	table1 = "Measurements";
	Table.create(table1);
	Table.setColumn("slice number", slice);

	selectWindow(img_L);

	//get number of ROIs in the image
	getMinAndMax(min, max); // max = number of labels (w/o background, background has the label number 0) = number of ROIs

// loop through all ROIs

rc = 0; //set the roiCounter rc to zero
for (i = 1; i < max+1; i++) {
	// i=1 --> ROI1
	selectWindow(img_L);
	run("Duplicate...", "duplicate");//stack is duplicated
		
	dup = getImageID;
	setThreshold(i, i);// i = label number of this ROI
	run("Convert to Mask", "method=Default background=Dark");// no new image. duplicated lbl image is converted to mask
	//run("Grays");// Lut was inverted
	// the duplicated and thresholded image contains only 1 ROI (in all slices)
	
	run("Analyze Particles...", "size=12-Infinity add stack");

	// loop through all with the label "i" ROIs	
	// --> rename rois 
	// --> measure are of this ROI at every time point, write into Table
	for (k = rc; k < roiManager("count"); k++) {
		roiManager("select", k);
		name = "ROI"+i+"_slice"+(k-rc+1);
		roiManager("rename", name);
		List.setMeasurements;
		area = List.getValue("Area");
		X = List.getValue("X");
		Y = List.getValue("Y");
		Table.set("ROI"+i+"_area", k-rc, area);
		Table.set("ROI"+i+"center_X", k-rc, X);
		Table.set("ROI"+i+"_center_Y", k-rc, Y);
	}
	rc = roiManager("count");
	selectImage(dup);
	close();
	run("Select None");
	
} //next i (= next ROI, i.e. ROI(i) in all slices)

Table.update(table1);

selectImage(original);
roiManager("UseNames", "true");
roiManager("Show All with labels");
1 Like