Sharing the generalization of 'Batch Processing' for multiple folders

I have just started using the macros and scripts in ImageJ. Have been trying to analyze about 100 data sets, each contain several 100 images.
There was a script in the ImageJ to analyze all the images in one folder. But I needed something for 100 folders. I also needed to save the analyzed stacks of images in new folders in a different path, after creating the folders by the script. In other word, the script is generalization of the ‘Batch Processing’. I used the ImageJ script for one folder and attempted to do the generalization. Here I am posting the code. Have written descriptions on the code. But one general point is that a Directory (Dir) contains several Folders; and each Folder contains several images. Hope it is helpful.

//A directory contains several folders; and each folder is a stack of images.
//User chooses the input direcotry path. The code analyzes all the images in the folders of the directory.
//It creates folders with analyzed images in the output direcotry which has been chosen by the user.
//The created folders and images have the same name as the input folders and images, respectively.
//The analysis in this specific case is segmentation of images by SRM and coversion of images to 8bit before saving.
//This part of the script - the two lines starting with ‘run’ in processFile function - can be replaced by any other analysis.

inputDir = getDirectory(“choose the input directory”);
outputDir = getDirectory(“choose the output directory”);

processDir(inputDir, outputDir);

//inputDir (direcotry) is a collection of Folders.
//The function processDir deals with processing every single Folder in the Dir and writes the results to outputDir.
//The inputDir and outputDir paths are given by the user.
//The Folders inside outputDir are created by processDir with the same names for equivalent Folders in inputDir.

function processDir(inputDir, outputDir) {
listdir = getFileList(inputDir);
for (j = 0; j < listdir.length; j++) {
print("Processing: " + listdir[j]);
File.makeDirectory(outputDir + listdir[j]);
outputFolder = outputDir + listdir[j];
inputFolder = inputDir + listdir[j];

//processFolder function manipulates a stack of images in a folder.
//It runs the processFile function for every image in the folder.

function processFolder(inputFolder) {
list = getFileList(inputFolder);
for (i = 0; i < list.length; i++) {
processFile(inputFolder, outputFolder, list[i]);

//processFile function processes single images.
//In this case the images are segmented by SRM and converted to 8bit.
//This part of code - the two lines starting with ‘run’ - can be replaced by other processes.

function processFile(inputFolder, outputFolder, file) {
print("Processing: " + inputFolder + file);
open(inputFolder + file);
run(“Statistical Region Merging”, “q=100 showaverages”);
print("Saving to: " + outputFolder);
saveAs(“TIFF”, outputFolder+file);


Sometimes one has to adapt to whatever is available. In your case, if the 1 folder analysis works, rather than spending time in writing and debugging something that is not trivial as analysing 100 data sets with 100 items each I would use the already working macro in one folder. Copy the 100 datasets to a single folder making sure that you can identify which image belongs to which dataset and you will be saving a lot of time, debugging why the program gives errors here and not there, etc. It is not going to be easy if you are just starting writing macros.

Have a look at this example macro which processes all images in a folder and subfolders:

This is also a good, updated option, using @Parameters to process a folder/subfolders:

 * Macro template to process multiple images in a folder

// @File(label = "Input directory", style = "directory") input
// @File(label = "Output directory", style = "directory") output
// @String(label = "File suffix", value = ".tif") suffix


// function to scan folders/subfolders/files to find files with correct suffix
function processFolder(input) {
	list = getFileList(input);
	for (i = 0; i < list.length; i++) {
		if(File.isDirectory(input + list[i]))
			processFolder("" + input + list[i]);
		if(endsWith(list[i], suffix))
			processFile(input, output, list[i]);

function processFile(input, output, file) {
	// do the processing here by replacing
	// the following two lines by your own code
	// leave them in until things are working... then replace all with your own code
	print("Processing: " + input + file);
	print("Saving to: " + output);
1 Like

I had the same thought of copying all the images to one folder and analyzing the whole images by the primary macro. It doesn’t really take a short time to do this. And what if I have 300 data sets! Didn’t want to compromise as I need this automation so often. It is also about learning. I wanted to learn something new about macros and programming in general.

Thanks for reminding about this one. I have seen this macro. It is good but it just rewrites the files and doesn’t keep the originals. In the one I shared, I attempted to keep the original files and folders and create new folders. The macro does this for me.

I tried to run your macro. I am getting an error “undefined variable in line (processFolder(input));” it seems the macro does not recognize the input. Should I do any changes in macro?

just delete this line from the code. the very first lines must be the @Parameters

1 Like

have tried it and got the same error!

Hi Hamid,
I used your macro for processing subfolders !!! It worked just fine for me !!!
Thanks to have made it available !!!

Hi Eric,
I’m glad it was helpful.

Continuing the discussion from Sharing the generalization of 'Batch Processing' for multiple folders:

This helped to solve a headache I have been having getting ImageJ to carry out the same operations on multiple folders rather than having to manually select the next folder every 20-30 minutes (big data sets). Thank you so much for sharing!