0

I've written a script in ImageJ Macro in order to batch process a large number of images with color thresholding and particle analysis, modified from this tutorial. Most of the time the thresholding works automatically, but sometimes has to be done manually, so I've created a partly automated "human-in-the-loop" script, which pauses for user input in several places. The most important of these follows an if/else statement in which user input determines whether the automatic color thresholding is acceptable. If yes, then the particles are analyzed, and if no then the color threshold is re-set to be done manually. To make this possible, I duplicate the imagefile at the beginning of the script, and revert to the original in order to process it manually. The majority of the script works, but the .tif files are not saved when the thresholding is done automatically (interestingly, the files are saved when the else portion of the script is run, i.e. when the thresholding is done manually).

In troubleshooting this issue, I've tried saving the .tif file outside the if/else statement, but still inside the processImage function. With this modification, the output file is not saved even when the images are thresholded manually. I've also tried modifying the output directory - I wonder whether the issue results from some issue with which directory the images are being saved to. My other guess is that my process for generating the filenames is failing, but I've gone through a troubleshooting process to print the generated names, and this suggests that the names are being generated correctly.

This is my first time writing a script in ImageJ macro, and I don't know what else to try! Any ImageJ Macro wizards out there who can spot my problem? Gratitude in advance for many tedious hours of repetitive clicking avoided.

// ask user to select a folder (should be parent folder)
home_dir = getDirectory("select home folder");

//// prepare a folder to output the images
output_dir = home_dir + "output" + File.separator;
File.makeDirectory(output_dir);

input_dir = getDirectory("select process folder");

// Get the list of files from that directory
// ****NOTE: if there are non-image files in this directory, it may cause the macro to crash****
fileList = getFileList(input_dir);

for (i = 0; i < fileList.length; i++)
{
    processImage(fileList[i]);
}

updateResults();  // Update the results table so it shows the filenames

// Show a dialog to allow user to save the results file
outputFile = File.openDialog("Save results file");

// Save the results data
saveAs("results",outputFile);

function processImage(imageFile)
{
    // Store the number of results before executing the commands,
    // so we can add the filename just to the new results
    prevNumResults = nResults;
  
  
  //set working directory
    
    open(imageFile);
    // Get the filename from the title of the image that's open for adding to the results table
    // We do this instead of using the imageFile parameter so that the
    // directory path is not included on the table
    filename = getTitle();
    
    //***** my macro script*****
    
    //select line tool, measure, and set scale
    setTool("line");
    waitForUser("Click OK when done");
    run("Set Scale...");
    
    //duplicate image in case automated thresholding needs adjustment
    run("Duplicate...", " ");
    
    // Color Thresholder 1.52a
    // 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]=43;  // lower bound for Hue
    max[0]=132;  //upper bound for Hue
    filter[0]="pass";
    min[1]=25;   //lower bound for Saturation
    max[1]=255;   //upper bound for Saturation
    filter[1]="pass";
    min[2]=45;   //lower bound for Brightness
    max[2]=255;   //upper bound for Brightness 
    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);
    
    ans=getBoolean("good threshold?"); 
    
    if(ans==1){
        run("Analyze Particles...", "size=100000-Infinity pixel show=[Overlay Masks] display include");  //increase "size = 40000"      
        waitForUser("check result");
        filename=getInfo("image.filename");
        image_out = output_dir + filename;
        saveAs("Tiff",image_out);
        print(image_out);
        
    } else{
        close();
        run("Out [-]");
        run("Out [-]");
        run("Out [-]");
        run("Color Threshold...");
        waitForUser("Click OK when done");
        run("Analyze Particles...", "size=70000-Infinity pixel show=[Overlay Masks] display include"); //have to increase it here too
        waitForUser("check result");
        filename=getInfo("image.filename");
        image_out = output_dir + filename;
        saveAs("Tiff",image_out);
        print(image_out);
    }    
    
          
    // Now loop through each of the new results, and add the filename to the "Filename" column
     for (row = prevNumResults; row < nResults; row++)
        {
            setResult("Filename", row, filename);
        }
    
       close("*");  // Closes all images   
    
}
      
mws
  • 1

0 Answers0