Batch Processing Several Folder

batch-processing
macro
Tags: #<Tag:0x00007fd5438342b0> #<Tag:0x00007fd5438340d0>

#1

Hello!

I’am new to ImageJ and I am trying to write a macro that makes it possible to analyze several subfolders within a mainfolder. I found a macro which might be suitable, however I cannot modify it so that I can use it for my purpose:

1. Macro for batch processing, which I found:

input = getDirectory("Input directory");
output = getDirectory("Output directory");

suffix = ".tif";  //you only want to apply to tiff images, no need to ask

processFolder(input);

function processFolder(input) {
    list = getFileList(input);
    for (i = 0; i < list.length; i++) {
        if(File.isDirectory(input + list[i]))   //if it's a directory, go to subfolder
            processFolder("" + input + list[i]);
        if(endsWith(list[i], suffix))   //if it's a tiff image, process it
            processFile(input, output, list[i]);
        //if it's neither a tiff nor a directory, do nothing
    }
}

function processFile(input, output, file) {

//here, you put the real processing

2. Code, which I use for a single folder

run("Image Sequence...", "open=[C:\\Users\\c7401320\\Desktop\\B11 Series\\Series006_Crop001\\B11 10ms 0.1% LG 27.lif_Series006_Crop001_t000.tif]");
    selectWindow("Series006_Crop001");
    run("Properties...", "channels=1 slices=1 frames=304 unit=m pixel_width=200 pixel_height=200 voxel_depth=200");

Unfortunately I do not know how to modify the macro so that several subfolders (Series006_Crop001, Series006_Crop002, Series006_Crop003 ….) are analyzed one by one.

Thanks for any help!


Automate tasks using macros in images placed in folders and subfolders
#2

@Levin

No worries! Actually - we have example code that comes with Fiji’s Script Editor… and it needed to be modified recently to work on subfolders (see this old Forum post for the explanation/fix). This code also takes advantage of Script Parameters - which are super helpful!!! So take a look at this code and adapt it as you need:

/*
 * 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

// See also Process_Folder.py for a version of this code
// in the Python scripting language.

processFolder(input);

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

function processFile(input, output, file) {
	// Do the processing here by adding your own code.
	// Leave the print statements until things work, then remove them.
	print("Processing: " + input + File.separator + file);
	print("Saving to: " + output);
}

Hope this helps!

eta :slight_smile:


#3

@etarena

Thanks a lot for your help :slight_smile: ! I still have a problem to modify the macro that way that it analyzes folder by folder. Now it does it only for one folder, probably my problem is quite trivial, but since I am quite new to ImageJ I cannot figure it out.

here is my current code:

    input = getDirectory("Input directory");

    suffix = ".tif";  //you only want to apply to tiff images, no need to ask

    processFolder(input);

    function processFolder(input) {
        list = getFileList(input);
        print(list.length);     
        for (i = 0; i < list.length; i++) {
            if(File.isDirectory(input + list[i]))   //if it's a directory, go to subfolder
                processFolder("" + input + list[i]);
            //if(endsWith(list[i], suffix))   //if it's a tiff image, process it
               //processFile(input, list[i]);
            //if it's neither a tiff nor a directory, do nothing

    	}
    }

    function processFile(input, file) {
    run("Image Sequence...", "open=[input] number=304 starting=1 increment=1");
    dirName = File.getName(input);
    selectWindow(dirName);
    run("Properties...", "channels=1 slices=1 frames=304 unit=nm pixel_width=104 pixel_height=104 voxel_depth=104 frame=[0.06 sec]");

many thx


#4

Hi @etarena

I quickly tested it with slight modifications (add a log statement for control and uncommet the call to processFile()) :

function processFolder(input) {
    IJ.log("processing directory " + input);
    list = getFileList(input);
    
    for (i = 0; i < list.length; i++) {
        if(File.isDirectory(input + list[i]))   //if it's a directory, go to subfolder
            processFolder("" + input + list[i]);
            
        if(endsWith(list[i], suffix))   //if it's a tiff image, process it
           processFile(input, list[i]);
    }
}

and

function processFile(input, file) {
	IJ.log("   processing file " + file);

	run("Image Sequence...", "open=[input] number=304 starting=1 increment=1");
	dirName = File.getName(input);
	selectWindow(dirName);
	run("Properties...", "channels=1 slices=1 frames=304 unit=nm pixel_width=104 pixel_height=104 voxel_depth=104 frame=[0.06 sec]");
}

works for me… runs through the the entire directory tree (it’s recursive :smile:)
(I commented the run statements in the processFile() function out though)


#5

Hi @Felix and @etarena

Thanks a lot for your help again and your fast reponse :slight_smile:! I norticed that I was not precise regarding the description of my problem:

  1. I have a main directory, which contains hundreds of subfolders, each subfolder contains an image sequence (304 images or even more).

  2. The image sequence of each subfolder has to be analyzed (I didnt include the code), for this purpose the image sequence has to be ‘loaded’ (only one time!!) via:

  3. run("Image Sequence...", "open=[input] number=304 starting=1 increment=1"

  4. The input variable has to be the path of the first image of the image sequence.

  5. When the image sequence of subfolder1 was loaded and analyzed, the algorithm should proceed to subfolder2, etc…

The current situation is as follows: for each subfolder the image sequence is loaded 304 times (=the number of images per subfolder) :confused:

unfortunatly I do not know how to change the code!


#6

too much recursive :frowning:

since I had some trouble with the arrays and out of personal preference I switched to python.
The following script runs through all folders it finds and looks of a files with a given extension. Again, I could not test the code manipulating the image sequence.
With the python script instead of run call IJ.run().

# @File(style='directory') directory
# @String extension

import os
from glob import glob
from ij import IJ


def process_sequence(folder, files):
	filename = os.path.basename(files[0])
        dirname = os.path.basename(folder)
	IJ.log('   found %i %s-files, first file name %s' % (len(files), extension, filename))
        IJ.run("Image Sequence...", "open=[" + folder + "] number=304 starting=1 increment=1")
        IJ.selectWindow(dirname)
        IJ.run("Properties...", "channels=1 slices=1 frames=304 unit=nm pixel_width=104 pixel_height=104 voxel_depth=104 frame=[0.06 sec]");

def process_folder(folder, extension):
	IJ.log('processing folder: ' + folder)
	
	for subdir in glob(os.path.join(folder, '*/')):
		process_folder(subdir, extension)
		
	files = glob(os.path.join(folder, '*' + extension))
	if len(files) > 0:
		process_sequence(folder, files)


process_folder(directory.getPath(), extension)

I hope this helps


#7

Thanks a lot for your effort!

Still a small problem: when running the script, I receive the following error message:

Exception in thread "AWT-EventQueue-0" java.lang.Error: Error: could not match input
  
    console: Failed to install '': java.nio.charset.UnsupportedCharsetException: cp0.

I followed a previous posts, where a possible solution was suggested to pass the following JVM argument:

-Dpython.console.encoding=UTF-8

However I did not know how to exactly include this into the code …

thx for help!


#8

Hi @Levin

are you running the latest version of ImageJ?

You don’t. Instead of launching ImageJ normally, you need to open a command line, change directory to the ImageJ or Fiji directory and type the command:

./ImageJ-macosx -Dpython.console.encoding=UTF-8 

there are different executables for Windows and Linux, with corresponding names. Choose the one that fits your OS.


#9

Hi @FelixM

Thanks for your advise! I am running Fiji (latest version), using Windows7. However I was not able to find a suitable executable for Windows. This might be a very basic question but I was searching for it intensely whithout finding a command that finally was working. Do you have any suggestions where to search?

thx!


#10

Hey @Levin

it’s in the Fiji.app folder ImageJ-win64.exe
Then open a command line, navigate to the application folder and run the executable with the arguments.

Best,

Felix