Batch_Folder.java |
package vnt; /** * Batch_Folder.java - v1.0 * Began: April 23, 2006 * Last Updated: April 23, 2006 * * Copyright (C) 2005-2006 - Michael D. Miller - mdm162@truman.edu * Truman State University * 100 E. Normal * Kirksville, MO - 63501 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ import ij.*; import ij.gui.*; import java.awt.*; import java.awt.Color.*; import ij.plugin.PlugIn; import ij.process.*; import java.io.*; import ij.io.*; import java.lang.String.*; import java.lang.Math.*; /** * <p>Batch processes an entire folder of images. * Batch_Folder will do the following:</p> * <ol> * <li>grayscale</li> * <li>lighting correction</li> * <li>segmentation</li> * <li>skeletonization</li> * <li>endpoint pruning and outline generation</li> * <li>perform graph theoretic analysis on the skeleton</li> * </ol> * * <p>After it is complete, Batch_Folder closes all images. * An alternative is Batch_Filde, which will perform this process on only one * specific image, but it will leave all the images generated by the process * open for user inspection.</p> * * @author Michael Miller - Truman State University * @version 1.0 * @since 1.0 * @see Batch_File */ public class Batch_Folder extends VascularNetworkToolkit implements PlugIn { /** * This is called at the beginning of the PlugIn. * * <p>Pre: ImageJ is open and the plugin was called. * <br />Post: A batch process is performed on a selected folder. * @param arg Required by the interface. The argument, if any (may be blank). */ public void run(String arg){ // check the ImageJ version // if (!IJ.versionLessThan("1.35l")) { if (IJ.versionLessThan("1.32")) { // ImageJ needs to be updated. IJ.showMessage("ImageJ Version Update Needed", "ImageJ needs to be updated to run this plugin."); return; } // create an Open dialogue for the user String directoryName = IJ.getDirectory(""); if (directoryName.length() == 0) { // user closed the dialogue return; } // process the folder recursiveProcessFolder(directoryName, true); return; } private void recursiveProcessFolder(String directoryName, boolean goDeeper) { File directory = new File(directoryName); FilenameFilter filter = new FilenameFilter() { public boolean accept(File directory, String name) { if (name.startsWith(".")) return false; if (name.endsWith(".txt")) return false; return true; } }; String[] contents = directory.list(filter); if (contents == null) { // Either dir does not exist or is not a directory. return; } String filename; for (int i=0; i<contents.length; i++) { // Get filename of file or directory filename = directoryName+contents[i]; // check if the content is a file or a folder if ((new File(filename)).isDirectory()) { // if content is a folder, should we recursively explore it? if (goDeeper) recursiveProcessFolder(filename+"/", goDeeper); } else { // content is a file, is it an image? // if (getFileInformation(IJ.openImage(filename))) { IJ.open(filename); if (getFileInformation(IJ.getImage())) { // we now have an open image and we extracted its settings, analyze it! mainProcess(); cleanUpAfterProcess(); } } } // all done with this folder! } /** * This is called when a particular image is open and it needs to be processed. * * <p>Pre: An image is open and ready to be processed by the VNT. * <br />Post: A batch process is performed on a currently active image. */ private void mainProcess() { //////////////////// // 0) Grayscaling // (and TIFF conversion) //////////////////// String extlessName = name.substring(0,name.lastIndexOf('.')); if (!name.equalsIgnoreCase(extlessName+".tif")) { IJ.run("RGB Color"); IJ.saveAs("tiff", directory+name); } IJ.run("8-bit"); IJ.saveAs("tiff", directory+"gray_"+name); //////////////////////// // 1) Light Correction// //////////////////////// if (performPolynomialLightingCorrection) IJ.run("Lighting Correction"); // Note: This plugin saves a new image as "lightcorrected_"+filename //////////////////// // 2) Segmentation// //////////////////// if (useHighLowSegmentation) IJ.run("Basic Segment"); else IJ.run("FindEdges Segment"); // Note: This plugin saves a new image as "segmented_"+filename /////////////////////// // 3) Skeletonization// /////////////////////// IJ.run("DistanceMap Skeleton"); // Note: This plugin saves a new image as "skeleton_"+filename /////////////// // 4) Pruning// /////////////// IJ.run("Endpoint Prune"); // Note: This plugin saves a new image as "pruned_"+filename //////////////////////////// // 4.5) Outline Generation// //////////////////////////// IJ.run("DistanceMap Outline"); // Note: This plugin saves a new image as "outline_"+filename IJ.run("Close"); //////////////// // 5) Analysis// //////////////// IJ.run("Node Analysis"); // Note: This plugin saves a new image as "nodes_"+filename // Note: This plugin saves a new image as "graph_"+filename ///////////////////////////// // 6) Additional Operations// ///////////////////////////// if (performEyeCandy) IJ.run("Eye Candy"); } /** * This is called after a particular image has been processed by the VNT. * * <p>Pre: An image has been opened and processed by the VNT. * <br />Post: All open files are closed, and [temp files may be deleted]. */ private void cleanUpAfterProcess() { //////////////////// // 0) Grayscaling // (and TIF conversion) //////////////////// IJ.runMacro("close();"); //////////////////////// // 1) Light Correction// //////////////////////// if (performPolynomialLightingCorrection) { IJ.runMacro("close();"); IJ.runMacro("close();"); } //////////////////// // 2) Segmentation// //////////////////// if (useHighLowSegmentation) { IJ.runMacro("close();"); IJ.runMacro("close();"); IJ.runMacro("close();"); } else { IJ.runMacro("close();"); IJ.runMacro("close();"); } /////////////////////// // 3) Skeletonization// /////////////////////// IJ.runMacro("close();"); IJ.runMacro("close();"); IJ.runMacro("close();"); /////////////// // 4) Pruning// /////////////// IJ.runMacro("close();"); //////////////////////////// // 4.5) Outline Generation// //////////////////////////// //////////////// // 5) Analysis// //////////////// IJ.runMacro("close();"); IJ.runMacro("close();"); IJ.runMacro("close();"); ///////////////////////////// // 6) Additional Operations// ///////////////////////////// if (performEyeCandy) { IJ.runMacro("close();"); } // compute an extensionless filename String extlessName = name.substring(0,name.lastIndexOf('.')); // delete all temporary image files if (keepTemporaryImageFiles == false) { if (!name.equalsIgnoreCase(extlessName+".tif")) (new File(directory+extlessName+".tif")).delete(); (new File(directory+"gray_"+extlessName+".tif")).delete(); (new File(directory+"lightcorrected_"+extlessName+".tif")).delete(); if (generateLightingCorrectionSurfaceEyeCandy) (new File(directory+"surface_"+extlessName+".tif")).delete(); (new File(directory+"segmented_"+extlessName+".tif")).delete(); (new File(directory+"skeleton_"+extlessName+".tif")).delete(); (new File(directory+"pruned_"+extlessName+".tif")).delete(); (new File(directory+"outline_"+extlessName+".tif")).delete(); (new File(directory+"nodes_"+extlessName+".tif")).delete(); (new File(directory+"graph_"+extlessName+".tif")).delete(); (new File(directory+"merged_"+extlessName+".tif")).delete(); } // delete all graph text files if (keepGraphTextFiles == false) { (new File(directory+"coord"+extlessName+".txt")).delete(); (new File(directory+"skel"+extlessName+".txt")).delete(); } // all done cleaning! } }