//ProcessImage.java // analyszes an image through a give receptive field. //Title: General Classes //Version: 0.1 //Author: John Krantz //Company: Hanover College // package model; import java.awt.*; import javax.swing.*; import java.awt.event.*; // Front end imports import util.*; import image.*; import io.*; import output.*; import gui.*; import model.color.*; /** * Constructs a screen size frame with the defaults already in place * base upon JFrame. This also controls the processing of the * Gabor model of the simple cell and the processing of the image * through the DOG model of the center surround cell. * @author John Krantz * @version 0.2 */ public class ProcessImage extends MainFrame { static final long serialVersionUID = 0; public final static Dimension SCREENSIZE = Toolkit.getDefaultToolkit().getScreenSize(); // container to hold panel private Container c = this.getContentPane(); //Panels JPanel(new BorderLayout()); private JPanel titlePanel = new JPanel(new BorderLayout()); private JPanel toolPanel = new JPanel(new FlowLayout()); private JPanel holdPanel = new JPanel(new BorderLayout()); // title object private JLabel titleLabel = new JLabel("Title"); // Image processing objects private Image source; private ImageGrabber convert = new ImageGrabber(); private double [][][] rawImage; private ColorComputer converter = new ColorComputer(); private double [][][] colorOpponentImage; // model objects // simple cells private SimpleCell sc = new SimpleCell(); private SimpleCell scs[] = new SimpleCell[2]; private boolean adaptPhase = false;// flag // if true the phase with the highest activity is taken (if phase // > 90 & < 270, the sign is reversed. // DOG Cells private DOG_Cell dog = new DOG_Cell(); // current cell being tested private int currentModel = ModelConst.SIMPLE_CELL; // objects and methods to select cell type to model private JComboBox modelCellCBX = new JComboBox(ModelConst.CELL_NAMES); private DialogFrame cells; private ImageProcess model = new ImageProcess(); private int numOrient = Defaults.NUM_ORIENT; private double [][][] processedImage = new double [numOrient][][]; private double stdDev = Defaults.STDEV; // width of bar in stdDev units // or stdev of excitatory circle in pixels private int step = Defaults.STEP; // step size through image private double phase = Defaults.PHASE; // phase of model in deg // dog model unique parameters private double inhib = Defaults.INHIB; // stddev of inhibitory circle in // standard deviation. private double eFactor = 1; // relative balance of // excitation and inhibition in the DOG cell. // objects to set parameter phases JLabel paramLabels [] = new JLabel[3]; JTextField paramFields [] = new JTextField [3]; JPanel [] paramPanel = new JPanel [3]; JCheckBox adaptPhaseCBX = new JCheckBox("Determine Phase Dynamically",false); // set the processing parameters private JButton setAnalysisParameters = new JButton("Set Parameters"); private DialogFrame parameters; // processed data file save objects private JButton saveData = new JButton("Save Model Results"); private String directory = ""; private SaveFile save; // model button private JButton runModel=new JButton("Model"); // modeling the fovea/periphery objects private boolean doFovea = Defaults.DO_FOVEA; // private JCheckBox fovea = new JCheckBox("Model Fovea/Periphery", doFovea); private double foveaRad = model.getFovRadius(); private double acuitySlope = model.getAcuitySlope(); // jitter objects private JCheckBox jitter = new JCheckBox("Model Eye Jitter", false); private boolean doJitter = model.getEyeJitter(); private int jitMax = model.getMaxJitterOffset(); private int numJit = model.getNumJitter(); // control objects Analyze control; Menus menu; // add a title to the same frame as above. public ProcessImage(Analyze ga){ control = ga; setSize(new Dimension(600,500)); titlePanel.add(titleLabel,BorderLayout.NORTH); titlePanel.add(toolPanel,BorderLayout.WEST); holdPanel.add(convert,BorderLayout.CENTER); toolPanel.add(setAnalysisParameters); toolPanel.add(runModel); toolPanel.add(saveData); c.add(titlePanel,BorderLayout.NORTH); c.add(holdPanel,BorderLayout.CENTER); // set up the four phases for the dynamic phase model for (int i = 0; i < scs.length; i ++){ scs[i] = new SimpleCell(); scs[i].setPhase((double)i*90.0/(double)scs.length); } menu = new Menus(this,control,false); setupListeners(); } private void setupListeners(){ setAnalysisParameters.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent E){ setParameters(); } }); // run model button runModel.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ control.runModel(); } }); // save data button saveData.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ save = null; System.gc(); save = new SaveFile(); directory = save.saveAs(getProcessedData(), control.createSummary(), directory,".gbr"); } }); } public void setParameters(){ if (currentModel == ModelConst.SIMPLE_CELL){ setSimpleParam(); } else { setDOGParam(); } } private void setSimpleParam(){ Component [] items = new Component[8]; paramLabels = new JLabel[items.length-2]; paramFields = new JTextField[items.length-2]; paramPanel = new JPanel[items.length-2]; String names [] = {"Standard Deviation of Center", "Step Size Through Image", "Number of Orientations", "Phase of Simple Cell", "Max Jitter Offset", "Number Time Sample in Jitter"}; String defaults [] = new String [names.length]; defaults[0] = ""+stdDev; defaults[1] = ""+step; defaults[2] = ""+numOrient; defaults[3] = ""+phase; defaults[4] = ""+jitMax; defaults[5] = ""+numJit; for (int i = 0; i < paramPanel.length; i ++){ paramLabels[i] = new JLabel(names[i]); paramFields[i] = new JTextField(defaults[i]); paramFields[i].setColumns(5); paramFields[i].setEditable(true); paramPanel[i] = new JPanel(new FlowLayout()); paramPanel[i].add(paramLabels[i]); paramPanel[i].add(paramFields[i]); if (i < 4) { // less that jitter position items[i] = paramPanel[i]; } else { items[i+1] = paramPanel[i]; } } items[4] = jitter; items[items.length-1] = adaptPhaseCBX; // create the window parameters = new DialogFrame("Set Simple Cell Model Parameters", items); parameters.setVisible(true); // read the thresholds setting panel's apply button parameters.applyButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ stdDev = Double.parseDouble(paramFields[0].getText()); step = (int)Double.parseDouble(paramFields[1].getText()); numOrient = (int)Double.parseDouble(paramFields[2].getText()); phase = Double.parseDouble(paramFields[3].getText()); doJitter = jitter.isSelected(); jitMax = (int)Double.parseDouble(paramFields[4].getText()); numJit = (int)Double.parseDouble(paramFields[5].getText()); setAdaptPhase(adaptPhaseCBX.isSelected()); control.resetCurrentModelDone(); control.runModel(); } }); // read the thresholds setting panel's done button parameters.doneButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ stdDev = Double.parseDouble(paramFields[0].getText()); step = (int)Double.parseDouble(paramFields[1].getText()); numOrient = (int)Double.parseDouble(paramFields[2].getText()); phase = Double.parseDouble(paramFields[3].getText()); doJitter = jitter.isSelected(); jitMax = (int)Double.parseDouble(paramFields[4].getText()); numJit = (int)Double.parseDouble(paramFields[5].getText()); setAdaptPhase(adaptPhaseCBX.isSelected()); parameters.setVisible(false); control.resetCurrentModelDone(); control.runModel(); } }); } // end set simple param private void setDOGParam(){ Component [] items = new Component[7]; paramLabels = new JLabel[items.length-1]; paramFields = new JTextField[items.length-1]; paramPanel = new JPanel[items.length-1]; String names [] = {"Excitatory Standard Deviation", "Inhibitory Standard Deviation", "Excitatory Weight (>=1)", "Step Size Through Image", "Max Jitter Offset", "Number Time Sample in Jitter"}; String defaults [] = new String [names.length]; defaults[0] = ""+stdDev; defaults[1] = ""+inhib; defaults[2] = ""+eFactor; defaults[3] = ""+step; defaults[4] = ""+jitMax; defaults[5] = ""+numJit; for (int i = 0; i < names.length; i ++){ paramLabels[i] = new JLabel(names[i]); paramFields[i] = new JTextField(defaults[i]); paramFields[i].setColumns(5); paramFields[i].setEditable(true); paramPanel[i] = new JPanel(new FlowLayout()); paramPanel[i].add(paramLabels[i]); paramPanel[i].add(paramFields[i]); if (i < 4) { items[i] = paramPanel[i]; } else { items[i+1] = paramPanel[i]; } } items[4] = jitter; // create the window parameters = new DialogFrame("Set DOG Cell Parameters", items); parameters.setVisible(true); // read the thresholds setting panel's apply button parameters.applyButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ stdDev = Double.parseDouble(paramFields[0].getText()); inhib = Double.parseDouble(paramFields[1].getText()); eFactor = Double.parseDouble(paramFields[2].getText()); step = (int)Double.parseDouble(paramFields[3].getText()); doJitter = jitter.isSelected(); jitMax = (int)Double.parseDouble(paramFields[4].getText()); numJit = (int)Double.parseDouble(paramFields[5].getText()); control.resetCurrentModelDone(); control.runModel(); } }); // read the thresholds setting panel's done button parameters.doneButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ stdDev = Double.parseDouble(paramFields[0].getText()); inhib = Double.parseDouble(paramFields[1].getText()); eFactor = Double.parseDouble(paramFields[2].getText()); step = (int)Double.parseDouble(paramFields[3].getText()); doJitter = jitter.isSelected(); jitMax = (int)Double.parseDouble(paramFields[4].getText()); numJit = (int)Double.parseDouble(paramFields[5].getText()); parameters.setVisible(false); control.resetCurrentModelDone(); control.runModel(); } }); }// end set dog param public void runModel(){ control.updateModelInfo(); model.setJitter(doJitter,jitMax,numJit); if (adaptPhase & currentModel == ModelConst.SIMPLE_CELL){ runAdaptPhaseModel(); } else { model.setFoveaParam(foveaRad, acuitySlope); model.setImage(colorOpponentImage); switch (currentModel){ case (ModelConst.SIMPLE_CELL) : // now process the image model.setChannel(ColorConst.BL_WH); processedImage = new double [numOrient][][]; setBarWidth(stdDev); setStep(step); setNumOrientations(numOrient); setPhase(phase); sc.setupCell(); for (int i = 0; i < numOrient; i ++){ model.setCell(sc.getCell(i)); if (doFovea){ processedImage[i] = model.processFoveaImage(sc, i); } else { processedImage[i] = model.processImage(); } convert.setAngleDone(i); convert.repaint(); } convert.setAngleDone(ImageGrabber.NONE); convert.repaint(); break; case (ModelConst.DOG_CELL) : // now process the image dog.setCellParameters(stdDev, inhib); dog.setExcitFactor(eFactor); setStep(step); dog.setupCell(); model.setCell(dog.getCell()); // process all three chroma channels at once so you have it. processedImage = new double [ColorConst.NUM_CHAN][][]; for (int i = 0; i < ColorConst.NUM_CHAN; i ++){ model.setChannel(i); if (doFovea){ dog.setCellParameters(stdDev, inhib); dog.setExcitFactor(eFactor); setStep(step); dog.setupCell(); model.setCell(dog.getCell()); processedImage[i] = model.processFoveaImage(dog); } else { processedImage[i] = model.processImage(); } } break; } } } public void runAdaptPhaseModel(){ setStep(step); setBarWidth(stdDev); // model.setImage(rawImage); model.setImage(colorOpponentImage); for (int i = 0; i < scs.length; i ++){ scs[i].setupCell(); } // temporary holding variable double [][][][] possibleActivities = new double [scs.length][18][][]; // now run model for each angle and phase for (int a = 0; a < 18; a ++){ // angle for (int p = 0; p < scs.length; p ++){// phase model.setCell(scs[p].getCell(a)); possibleActivities[p][a]=model.processImage(); } convert.setAngleDone(a); convert.repaint(); } // now find the highest activity double phases [] = new double[scs.length]; for (int i = 0; i < phases.length; i ++){ phases[i]= scs[i].getPhase(); } // determine the final activity level if // phase is > 90 and < 270 deg, then reverse sign // of activity. processedImage = new double[18] [possibleActivities[0][0].length] [possibleActivities[0][0][0].length]; for (int a = 0; a < 18; a ++){// angles for (int x = 0; x < processedImage[0].length; x ++){ // x for (int y = 0; y < processedImage[0][0].length; y ++){ // y int i = 0; // index of phase with greatest activity double max = possibleActivities[0][a][x][y]; // the max activity // find max for (int p = 1; p < scs.length; p ++){ if (max < possibleActivities[p][a][x][y]){ max = possibleActivities[p][a][x][y]; i = p; } } // now put into processed image array if (phases[i] <= 90 | phases[i] >= 270){ // place in positive processedImage[a][x][y] = max; } else{// place in negative processedImage[a][x][y] = -max; } }// end y }// end x }// end angles convert.setAngleDone(ImageGrabber.NONE); convert.repaint(); control.showPlot(); } // set methods public void setCellType(){ Component [] items = new Component[1]; String names [] = {"Cell type to model"}; items[0] = modelCellCBX; JLabel [] cellLabels = new JLabel[1]; cellLabels[0] = new JLabel(names[0]); JPanel [] cellPanel = new JPanel[1]; cellPanel[0] = new JPanel(new FlowLayout()); cellPanel[0].add(cellLabels[0]); cellPanel[0].add(items[0]); // create the window cells = new DialogFrame("Select Cell to Model", cellPanel); cells.setVisible(true); // read the thresholds setting panel's apply button cells.applyButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ currentModel = modelCellCBX.getSelectedIndex(); control.enableAnalysis(); control.updateModelInfo(); runModel(); } }); // read the thresholds setting panel's done button cells.doneButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ currentModel = modelCellCBX.getSelectedIndex(); control.enableAnalysis(); cells.setVisible(false); runModel(); } }); } public void setCellType(int cellType){ currentModel = cellType; } public void setImage(Image src, String filename){ source = src; convert.setPic(source); this.setTitle(filename); titleLabel.setText(filename); this.setVisible(true); rawImage = convert.getPixelArray(); colorOpponentImage = converter.fromRGBtoColorOpponent(rawImage); source = null; System.gc(); }// end set image public void setImage(Image src, String filename, double stDev, int st){ setBarWidth(stDev); setStep(st); setImage(src,filename); } public void setBarWidth(double stDev){ stdDev = (stDev > 0 ? stDev : stdDev); sc.setBarWidth(stDev); // set up multiple cells for (int i = 0; i < scs.length; i ++){ scs[i].setBarWidth(stDev); } } public void setDogParam(double sdExcit, double sdInhib){ stdDev = (sdExcit > 0 ? sdExcit : stdDev); inhib = (sdInhib > 0 ? sdInhib : inhib); dog.setCellParameters(stdDev, inhib); } public void setStep(int st){ step = (st > 0 ? st : step); model.setStep(st); } public void setNumOrientations(int orients){ numOrient = (orients > 1 ? orients : numOrient); sc.setNumOrientations(numOrient); } public void setPhase(double phs){ phase = phs; sc.setPhase(phase); } public void setAdaptPhase(boolean b){ adaptPhase = b; } public void setDirectory(String dir){ directory = dir; } // get methods public double [][][] getProcessedData() { return processedImage; } public String getCurrentModelCell() { return ModelConst.CELL_NAMES[currentModel]; } public int getCurrentCell() { return currentModel; } public int getNumOrientations() { return numOrient; } public int getStep() { return step; } public double [] getSimpleParam(){ double temp [] = {stdDev,phase,numOrient}; if (adaptPhase){ temp[1] = -1; } return temp; } public double [] getDOGParam(){ double temp [] = {stdDev,inhib,model.getChannel()}; return temp; } public boolean getEyeJitter() { return doJitter; } public int getJitterMax() { return jitMax; } public int getNumJit() { return numJit; } }