Color particles in 3D depending on their volume

Hello everyone!

I have stacks of binarized files containing particles. I can plot those particles in 3D using the 3D viewer (or Volume viewer, or object counter…), and measure their volume and several other characteristics using all the tools in Fiji.
However, I didn’t find any way to generate a 3D plot that colors the particles depending on their volume?

I managed to get a colored 3D plot using the Analyse>3D Object counter, but it just colors particles on a pre determined color scale, only depending on their number.

Here is an example of the reconstructed 3D stack using the 3D viewer, but all the particles are green. How can I color them depending on their volume?

You can do that with MorphoLibJ using the Assign Measure to Label plugin (under Plugins > MorphoLibJ > Label Images).


Thanks for your answer! Could you be a little more specific?
I know assign measure to label needs a table to work. I tried generating a table using Analyse>analyse particle 3D but it only finds ONE particle out of the 63 (inverting the black and white does not help).
The input file is a tiff stack in black and white (binarized). It looks like all particles are only considered as one.

I can also get a table with the volumes listed with the 3D Object Counter, but then the Assign measure to label plugin returns me a fully black stack.

What input should I give the Assign Measure To Label in order to obtain my particles in 3D colorized depending on their volume?

Hello @almenia ,

You need to label first all your objects using the Connected Component Labeling plugin (under Plugins > MorphoLibJ > Binary Images). That way you will get a label image with a different voxel value for each of your 63 particles. Then you will continue with the Particle Analysis 3D plugin to extract the measures of each particle, and finally the Assign Measure to Label plugin to obtain a new image where each particle will contain your selected measure as voxel intensity.

I hope everything is more clear now!


Hi @almenia,

The solution proposed by @iarganda is very elegant and generic, just for sake of being complete on this forum, note that you have a alternative tool that do will do the same using macro programming using 3D Manager, check the sample macros.




Thank you very much, it’s much more clear now :slight_smile:

One remaining issue is that one of the particles is so big that it totally overshadows the color of the smallest ones once I assign them values equal to their volumes. Only the biggest particle is visible once i assign them their volume and use a colormap.
This can be countered by using a log scale (or square root) on the image stack after assigning measures to the labels, so that the values are closer to each other.

You can also remove the largest label automatically (Plugins > MorphoLibJ > Label Images > Remove Largest Label). I use it a lot to remove the background label if needed :wink:

Hi Ignacio,

Is there a way to use the label assignment in IJ macro - with the setting of the values?

when I record the command I get the user interface and my selection of values is not recorded:

run("Assign Measure to Label");

Is there a way to set the choice of table,column and min/max values in a macro (IJ macro language) ?


Hello @Ofra_Golani,

I can replicate the problem. Let me work on it and I will be back to you.

Thanks for reporting!


That part of the code was written by @dlegland and it seems correct. The GenericDialog is properly created so I’m not sure what is happening. It might be related to the dialog listener by I am struggling to make it work.

Maybe @imagejan or @ctrueden run into this problem before?

Hi @dlegland @iarganda @imagejan @ctrueden

I wonder if any of you had a chance to look at this ?
I tried to construct a macro line myself to control the "“Assign Measure to Label” dialog with

run(“Assign Measure to Label”, “Results=”+TableName+" Column="+ColName+" Min="+MinVal+" Max="+MaxVal);

but still the default parameters are used and not those that I gave it.
Is there any workaround ?

Is there any other tool in Fiji which can color-code a labeled image by measured feature - from an IJ macro without manual selection of values from the dialog ?


I agree this behavior is unexpected and unfortunate. But I have not seen it before, and do not have an idea for why it’s happening. One possible way forward would be to debug from an IDE, putting a breakpoint on the showDialog method of GenericDialog to inspect the call stack when the run command happens from a macro.

I just followed this breadcrumb and can confirm that commenting out this line solves the recording problem. Afterwards, the recorder records properly. Does anybody know why the DialogListener is necessary?

This is btw minimal example code for checking the execution/choise of parameters issue. I wasn’t able to reproduce the default-value issue. It takes the values I entered…

run("Blobs (25K)");
setOption("BlackBackground", true);
run("Convert to Mask");
run("Analyze Particles...", "  show=[Count Masks] display");
run("Assign Measure to Label", "results=Results column=Area min=1.000 max=5");


1 Like

Hey @Ofra_Golani,

I know it’s a bit old school, but how about replacing the label pixel values with a plain piece of macro code? A workaround at least until the bug is fixed…

This macro should do the job:

column = "Area";
getDimensions(width, height, channels, slices, frames);

for (c = 0; c < channels; c++) {
	if (channels > 1) {
		Stack.setChannel(c + 1);
	for (z = 0; z < slices; z++) {
		if (slices > 1) {
			Stack.setSlice(z + 1);
		for (t = 0; t < frames; t++) {
			if (frames > 1) {
				Stack.setFrame(t + 1);
			for (x = 0; x < width; x++) {
				for (y = 0; y < height; y++) {
					pixelValue = getPixel(x, y);
					if (pixelValue > 0) {
						newValue = getResult(column, pixelValue - 1);
						setPixel(x, y, newValue);



I have no idea why this does not work from a macro…

The Dialog Listener is used to update the content of the widgets within the dialog when the user changes the table or the dialog. Maybe some additional work is necessary to keep the new values for recorder. I’ll try to have a look.

1 Like

Thanks Robert,

The macro command works indeed, and this solves the issue :smiley:
The problem with my code was using Uppercase letters for the parameters names (Column/Min/Max) instead of lowercase letters. So the following line is working well:

run(“Assign Measure to Label”, “results=”+TableName+" column="+ColName+" min="+MinVal+" max="+MaxVal);


1 Like

BoneJ’s Particle Analyser can do this: