Batch Processing: Color Threshold + Measure

Hi everyone,
We’re new to Fiji and don’t have much experience in coding. We are having trouble with getting a macro to work. Basically, we want our macro to take images in a folder, apply a colour threshold and select the particles in the images. Then we want to take the following measurements: Area, Mean, StdDev, Mode, Min, Max, Perim, IntDen, Median, RawIntDen; and save all the results as a csv file.

We’ve tried to use generic batch processing macros, but it doesn’t seem to work.

My macro is the following:

//"BatchProcess"
//
//This macro will process all the files in a folder and any subfolders
//in that folder. It will select the area of a particle using a 
//colour threshold, then run the Measure command to calculate the
//raw integrated density of TIFF files. 

requires ("1.33s");
//Insert the directory of your folder in below
dir = getDirectory("/Users/jacklinkwan/Desktop/sample2_stack"); 
setBatchMode(true);
count = 0;
countFiles(dir);
n = 0;
processFiles(dir);
//print(count + "files processed");

function countFiles(dir) {
	//create a list of files in the folder
	list = getFileList(dir);
	for (i=0; i<list.length; i++) {
		if (endsWith(list[i], "/"))
			countFiles(" "+dir+list[i]);
		else
			count++;
	}
}

function processFiles(dir) {
	list = getFileList(dir);
	for (i=0; i<list.length; i++) {
		if (endsWith(list[i], "/"))
			processFiles(" "+dir+list[i]);
		else {
			showProgress(n++, count);
			path = dir+list[i];
			processFile(path);
		}
	}
}

function processFile(path){
	//Process files which end in 'jpg'
	if (endsWith(path, ".jpg")) {
		open(path);
		//Run commands. Put your macros into here.
		run("Color Threshold...");
		// Color Thresholder 2.0.0-rc-69/1.52p
		// Autogenerated macro, single images only!
		min=newArray(3);
		max=newArray(3);
		filter=newArray(3);
		a=getTitle();
		run("HSB Stack");
		run("Convert Stack to Images");
		selectWindow("Hue");
		rename("0");
		selectWindow("Saturation");
		rename("1");
		selectWindow("Brightness");
		rename("2");
		min[0]=0;
		max[0]=255;
		filter[0]="pass";
		min[1]=0;
		max[1]=255;
		filter[1]="pass";
		min[2]=4;
		max[2]=255;
		filter[2]="pass";
		for (i=0;i<3;i++){
		  selectWindow(""+i);
		  setThreshold(min[i], max[i]);
		  run("Convert to Mask");
		  if (filter[i]=="stop")  run("Invert");
		}
		imageCalculator("AND create", "0","1");
		imageCalculator("AND create", "Result of 0","2");
		for (i=0;i<3;i++){
		  selectWindow(""+i);
		  close();
		}
		selectWindow("Result of 0");
		close();
		selectWindow("Result of Result of 0");
		rename(a);
		// Colour Thresholding-------------
		run("Close");

		run("Set Measurements...", "area mean standard modal min perimeter integrated median redirect=None decimal=3");

		run("Measure");
		save(path);
		saveAs("Results", "/Users/jacklinkwan/Desktop/Results.csv");
		close();
	}
}

When we try to run the macro, the following error message pops up:

We’re not too sure where to go from here. Any help would be greatly appreciated!

Here is an example stack with two images. The particles we’re analysing are very very small, so they may not be visible to the human eye, but they are in these images.
sample2_stack.zip (10.3 KB)

Thank you,
Jacklin and Antri

Welcome to the forum,

this error indicates that you try to convert an image from one type to another. However, the type conversion is not allowed or implemented.

The error occurs at this line: run("HSB Stack");
An image can only converted to the HSB color space if it is present as RGB image. As per supported conversions.

But your image is a single channel 8-bit grayscale tif image with 2 slices. Thus a conversion to HSB is not possible. I also don’t really understand the first part of the macro it seems not really necessary…

As I read the intention of the macro you just want to threshold each slice by some value and then add the binary masks together and then do some measurements in the original image slices?

Maybe I just misunderstand, could you explain a bit what you want to achieve? :slight_smile:

You do not need the line:

	run("Color Threshold...");

if you then pressed the “macro” button to generate the code that follows (which replicates the colour thresholder settings at that time).
Also, the HSB filters are set to: Hue 0-255, Saturation 0-255 and Brightness 4-255. It looks like the macro is only removing pixels with brightness 0 to 3. Is that what you wanted?

Colour thresholding is in general more complicated than greyscale because it deals with colour models that might not lead to a robust batch thresholing unless the images are similar/comparable.

Hi Gabriel,

The HSB filters are correct– the images we’re analysing are basically just dark frames with very small light tracks created by radioactive particles :slight_smile:

For colour thresholding, we’re slightly wary of converting out images to greyscale because it may change the value of the signal (which we’ve calibrated to units of photoelectrons).

In that case, the filters are not really exploiting colour information, only the brightness channel which is thresholded from 4 to 255.
If that is what you want, I would not use the colour thresholder, but just convert the image to hsb and threshold the brightness channel.

Anyway, if you are after radioactive particles, why is the capture done in colour?

Hi Chris,

So we have a folder of images with tiny particles in them. We want to select the area of the particles and measure the raw integrated density of them. This is the macro that we recorded when analysing a single image:

run("Color Threshold...");
// Color Thresholder 2.0.0-rc-69/1.52p
// Autogenerated macro, single images only!
min=newArray(3);
max=newArray(3);
filter=newArray(3);
a=getTitle();
run("HSB Stack");
run("Convert Stack to Images");
selectWindow("Hue");
rename("0");
selectWindow("Saturation");
rename("1");
selectWindow("Brightness");
rename("2");
min[0]=0;
max[0]=255;
filter[0]="pass";
min[1]=0;
max[1]=255;
filter[1]="pass";
min[2]=4;
max[2]=255;
filter[2]="pass";
for (i=0;i<3;i++){
  selectWindow(""+i);
  setThreshold(min[i], max[i]);
  run("Convert to Mask");
  if (filter[i]=="stop")  run("Invert");
}
imageCalculator("AND create", "0","1");
imageCalculator("AND create", "Result of 0","2");
for (i=0;i<3;i++){
  selectWindow(""+i);
  close();
}
selectWindow("Result of 0");
close();
selectWindow("Result of Result of 0");
rename(a);
// Colour Thresholding-------------
run("Close");

run("Set Measurements...", "area mean standard modal min perimeter integrated median redirect=None decimal=3");

run("Measure");
close();

We’ve tried selecting the area of the particle using a colour threshold (which works when we’re analysing this sample image). 83279527_484851875422610_8207351081504604160_n.tiff (23.1 KB)

Ideally, we want to automate this process for an entire folder of similar images, and export the raw integrated density measurements to a csv file

Hope that makes things clearer :smiley:

  • Jacklin & Antri

Ok, thank you. The image that you provided now is a RGB image and can be converted to a HSB stack directly.

The images you provided before are single channel 8-bit greyscale images with 2 slices. Thus cannot be converted into a HSB stack without further conversion. You said you wanted to avoid conversion to greyscale. So I don’t know how to proceed with that.

Seems that your output changed between these two examples.

Hijacking this thread …

I’m experiencing the same macro error as mentioned above … which is odd, since I didn’t have this issue until I updated to 1.52p.

Manual color thresholding works, but the macro stops at run (“HSB Stack”) (as mentioned above ) … this also happens when using a sample image (new-lenna.jpg).

Is there any way around this? I don’t have many images to threshold, but it would be nice to have the macro working again … :sob:

I tested it using the new-lenna.jpg.
When saved as .jpg the run(“HSB Stack”); does not give me an error with an updated Fiji.
Also running Image > Type > HSB Stack works fine on the new-lenna.jpg

The image needs to be a RGB. Any other type does not work.
You can see the type in the image header:
header

However there was another error with the macro in my case.
All the images are closed and it does not find any open images.

Who is the author of this macro?
Maybe you could contact that person?

Hi Schmiedc,

Thanks for the reply, it’s always nice to have extra eyes looking at this.

What I’m working with are RGB color images (image type), so that’s crossed off the list. I’ve just opened the same image using an older build (1.52h) and here I have no errors running the macro.

Any other thoughts?