import java.awt.*; import java.awt.image.*; import java.io.*; import java.util.*; import ij.io.*; import ij.*; import ij.gui.*; import ij.util.StringSorter; import ij.plugin.PlugIn; import ij.plugin.*; import ij.process.*; import javax.swing.*; import java.awt.event.*; import javax.swing.event.*; /* Christopher Philip Mauer. Copyright (c) 2003. Permission to use, copy, modify, and distribute this software for any purpose without fee is hereby granted, provided that this entire notice is included in all copies of any software which is or includes a copy or modification of this software and in all copies of the supporting documentation for such software. Any for profit use of this software is expressly forbidden without first obtaining the explicit consent of the author. THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY. IN PARTICULAR, THE AUTHOR DOES NOT MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */ /* This PlugIn implements a recursive prediction/correction algorithm based on the Kalman Filter. The application for which it was designed is cleaning up timelapse image streams. It operates in constant space by opening the image files as needed, and closing them when the computation has been completed. Christopher Philip Mauer cpmauer@northwestern.edu */ public class Kalman_Filter implements PlugIn{ protected static ImagePlus imp; protected static ImagePlus imp2; protected static ImageStack stack; protected static ImageStack stack2; protected static ImageProcessor ip = null; protected static ImageProcessor ip2 = null; private String fileName = null; private String directory = null; private String savedirectory = null; private String savename = null; private String abspath = null; private double numimages = 0; private double firstimage = 0; private String namewith = null; private String prefixname = null; private String fileList[] = null; private String fullDirectory[] = null; private static String filteredDirectory[] = null; private String newfileName = null; protected settingBar sbar = null; private double gain = 0.80; private double percentvar = 0.05;/*spec this at runtime*/ private double fps = 30; private boolean stopit = false; private boolean stop = true; private boolean save = false; private boolean test = true; public void run (String argv){ boolean g = true; boolean f = getFiles(); if(f==true){ sbar = new settingBar(); g = getStartSpecs(); if(g==true){ imp = new ImagePlus(filteredDirectory[0]); imp2 = new ImagePlus(filteredDirectory[0]); } } if(f==true&&g==true) Kalmanizer(); } public boolean getFiles(){ String directory = ""; JFileChooser jfc = new JFileChooser(); jfc.setCurrentDirectory(new File(".")); int jfcval = jfc.showDialog(sbar, "Choose File"); if (jfcval == JFileChooser.APPROVE_OPTION){ File thefile = jfc.getSelectedFile(); fileName = thefile.getName(); directory = thefile.getAbsolutePath(); directory = directory.substring(0,directory.length()-fileName.length()); prefixname = fileName.substring(0,fileName.length()-4); } if(fileName==null) return false; GenericDialog fname = new GenericDialog("Pick the naming convention..", IJ.getInstance()); fname.addStringField("Enter the naming convention which is common to the files you wish to use", fileName, 40); fname.addStringField("Enter the naming convention for the save (will be appended with K######)", prefixname, 40); fname.addCheckbox("Specify save directory (the default is to save to the raw image directory)", false); fname.showDialog(); if(fname.wasCanceled()) return false; namewith = fname.getNextString(); savename = fname.getNextString(); /*spec the save directory*/ if(fname.getNextBoolean()==true){ JFileChooser dirchooser = new JFileChooser(); dirchooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int r = dirchooser.showDialog(sbar, "Choose Directory"); try{ savedirectory = dirchooser.getSelectedFile().getAbsolutePath(); } catch(Exception e){return false;} } else savedirectory = directory; namewith = directory+namewith; /*strcat the absolutepath to the filename and order it*/ fullDirectory = new File(directory).list(); for(int i=0;i filteredDirectory.length){ IJ.showMessage("Error", "Invalid image number. Default employed."); numimages = filteredDirectory.length; } if(percentvar>1.0||gain>1.0||percentvar<=0.0||gain<0.0){ IJ.showMessage(ErrorMessage); percentvar = 0.05; gain = 0.80; } save = finfo.getNextBoolean(); sbar.gainval.setText(String.valueOf(gain)); sbar.fpsval.setText(String.valueOf((int)fps)); sbar.gslider.setValue((int)(gain*100)); sbar.fpslider.setValue((int)fps); return true; } public void Kalmanizer(){ int m = imp.getWidth(); int n = imp.getHeight(); int dimension = m*n; short stackslice[] = new short[dimension]; short filteredslice[] = new short[dimension]; double noisevar[] = new double[dimension]; double average[] = new double[dimension]; double predicted[] = new double[dimension]; double predictedvar[] = new double[dimension]; double observed[] = new double[dimension]; double Kalman[] = new double[dimension]; double corrected[] = new double[dimension]; double correctedvar[] = new double[dimension]; ImagePlus img = null; Opener o = new Opener(); try{ stack = imp.createEmptyStack(); } catch(Exception e){ IJ.showMessage("Improper File Type: "+fileName); return; } stack.addSlice("raw",imp.getProcessor()); stack2 = imp.createEmptyStack(); stack2.addSlice("Kalman Filter",imp.getProcessor()); //stack = new ImageStack(m,n,imp.getProcessor().getColorModel()); imp.setStack("raw", stack); imp.show(); imp.getWindow().setLocation(20,150); imp2.setStack("Kalman Filter", stack2); imp2.show(); imp2.getWindow().setLocation(m+50,150); try{ stackslice = (short[])stack.getPixels(1); } catch(Exception e){ IJ.showMessage("KalmanFilter uses 16bit images"); return; } stack.deleteLastSlice(); stack2.deleteLastSlice(); for (int i=0;i