Search code examples
javamacrosimagejfijiimagej-macro

Fiji Macro for .nd2 images batch processing


Can anybody tell me why with this macro I just get as an output for each channel of each image a .png file of the first image slice and not of the stacked image? It seems like the Z-project part of the code is not properly working, thanks in advance!!

`// Function to process each .nd2 file
function processFile(filePath) {
    // Open the .nd2 file
    setBatchMode(true);
    open(filePath);
    // Get the title of the opened image
    title = getTitle();
    
    // Stack different focal planes into one high projection image per channel
    run("Split Channels");
    channelTitles = getList("image.titles");

    // Process each channel
    for (c = 0; c < channelTitles.length; c++) {
        selectWindow(channelTitles[c]);
         // Get the total number of slices
        totalSlices = getSliceNumber();

        // Use all slices for Z Projection
        run("Z Project...", start=1 stop=totalSlices, " projection=[Max Intensity]");
        run("Update");
        projTitle = getTitle();
        close(channelTitles[c]);
        selectWindow(projTitle);
        // Adjust brightness and contrast automatically
        run("Enhance Contrast", "saturated=0.35");
        run("Update")
        run("Apply LUT", "stack");
        
        // Convert to RGB
        run("RGB Color");
        
        // Save the processed channel
        saveAs("Tiff", filePath + "_channel" + (c + 1) + ".tif");
        close();
    }
    
    // Close the original image
    close(title);
}`

I tried to work on the following portion of the code by selecting the project image once generated and closing the original one but it doesn't still work....

// Use all slices for Z Projection
        run("Z Project...", start=1 stop=totalSlices, " projection=[Max Intensity]");
        run("Update");
        projTitle = getTitle();
        close(channelTitles[c]);
        selectWindow(projTitle);

That is an example of how it should look like if I do the same passages listed in the code in Fiji directly on each image

That's what I get after all the attempt and suggestions you gave me


Solution

  • Below please find an ImageJ demo macro that uses a ".nd2"-file I found here. Please download this raw-file and try the macro with this file! The file shows two colour-channels with four images (here: time points).

    //imagej-macro "nd2-processing" (Herbie G., 09. Aug. 2024)
    requires("1.54j");
    path=File.openDialog("Open the sample nd2-file");
    run("Bio-Formats","open=[path] color_mode=Default rois_import=[ROI manager] split_channels view=Hyperstack stack_order=XYCZT use_virtual_stack series_1");
    path=File.getDirectory(path)+File.nameWithoutExtension;
    clr=newArray("Blue","Green","Red");
    n=nImages;
    for (i=0;i<n;i++) {
       run("Z Project...","projection=[Max Intensity]");
       run("Enhance Contrast...","saturated=0.35");
       run(clr[i]);
       saveAs("PNG",path+"_ch-"+(n-i)+".png");
       close(); close();
    }
    exit();
    //imagej-macro "nd2-processing" (Herbie G., 09. Aug. 2024)
    

    Please note that by assigning a LUT to the projection images makes them saved with 8bit depth. Save in TIF-format to keep the 16bit depth. =============================================

    Finally, below please find the code for batch processing all ".nd2"-files in a folder:

    //imagej-macro "batch_nd2-processing" (Herbie G., 09./10. Aug. 2024)
    requires("1.54j");
    close("*");
    inSfx=2;  // preferred source file suffix
    outSfx=0; // preferred result file suffix
    Dialog.create("Batch Process Folder");
       sfxIn=newArray(".tif",".czi",".nd2");
       sfxOut=newArray(".tif",".png",".jpg");
       Dialog.setInsets(0,220,0);
       Dialog.addMessage("Macro does not process nested folders!",12,"blue");
       Dialog.setInsets(6,0,0);
       Dialog.addChoice("Suffix",sfxIn,sfxIn[inSfx]);   
       Dialog.setInsets(-28,182,0);
       Dialog.addMessage("of the source files");   
       Dialog.addDirectory("Source-Folder",getDir("file"));
       Dialog.addChoice("Suffix",sfxOut,sfxOut[outSfx]);   
       Dialog.setInsets(-37,182,0);
       Dialog.addMessage("for the result files");  
       Dialog.addDirectory("Result-Folder",getDir("file"));
    Dialog.show();
    sfx1=Dialog.getChoice();
    srce=Dialog.getString();
    sfx2=Dialog.getChoice();
    dest=Dialog.getString();
    setBatchMode(true);
    count=processFolder(sfx1,srce,sfx2,dest);
    setBatchMode(false);
    exit(""+count+" files processed");
    //
    function processFolder(xtn1,dir1,xtn2,dir2) {
       color=newArray("Blue","Green","Red","Yellow","Magenta","Cyan");
       cnt=0;
       list=getFileList(dir1);
       n=list.length;
       for (i=0;i<n;i++)
          if (endsWith(list[i],xtn1)) {
             path=dir1+list[i];
             run("Bio-Formats","open=[path] color_mode=Default split_channels view=Hyperstack stack_order=XYCZT use_virtual_stack series_1");
             path=dir2+File.nameWithoutExtension;
             Stack.getDimensions(w,h,c,s,f);
             if (s>1||f>1) {
                cnt++;
                processStack(path,xtn2,color);
             } else {
                close("*");
                print("Unsuited image data: "+list[i]);
             }
          }
       return cnt;
    }
    function processStack(pth,xtn,clr) {
       n=nImages;
       for (i=0;i<n;i++) {
          run("Z Project...","projection=[Max Intensity]");
          run("Enhance Contrast...","saturated=0.35");
          if (n<7) run(clr[i]);
          saveAs(pth+"_ch-"+(n-i)+xtn);
          close(); close();
       }
    }
    //imagej-macro "batch_nd2-processing" (Herbie G., 09./10. Aug. 2024)
    

    It is assumed that the source stacks have a maximum of six colour channels!