/*
* Copyright (c) 2011-2015, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.demonstrations.denoise;
import boofcv.gui.StandardAlgConfigPanel;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Configures denoising algorithm and controls the GUI.
*
* @author Peter Abeles
*/
public class DenoiseInfoPanel extends StandardAlgConfigPanel implements ChangeListener , ActionListener {
// selects which image to view
JComboBox images;
// specifies amount of noise to add to the image
JSpinner noiseLevel;
// A panel that just holds the config's position
JPanel configHolder = new JPanel();
// wavelet config
JPanel waveletConfig;
JComboBox waveletBox;
JSpinner waveletLevel;
// blur config
JPanel blurConfig;
JSpinner blurRadius;
// Shows statistic info in error level
JTextArea algError;
JTextArea algErrorEdge;
JTextArea noiseError;
JTextArea noiseErrorEdge;
// passes change events
Listener listener;
public DenoiseInfoPanel() {
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
images = new JComboBox();
images.addItem("Denoised");
images.addItem("Noisy");
images.addItem("Original");
images.addActionListener(this);
images.setMaximumSize(images.getPreferredSize());
waveletBox = new JComboBox();
waveletBox.addActionListener(this);
double h = waveletBox.getPreferredSize().getHeight();
waveletBox.setMaximumSize(new Dimension(175,(int)h));
noiseLevel = new JSpinner(new SpinnerNumberModel(20,0,100,5));
noiseLevel.addChangeListener(this);
noiseLevel.setMaximumSize(noiseLevel.getPreferredSize());
waveletLevel = new JSpinner(new SpinnerNumberModel(4,1,5,1));
waveletLevel.addChangeListener(this);
waveletLevel.setMaximumSize(new Dimension(75,(int)h));
blurRadius = new JSpinner(new SpinnerNumberModel(1,1,12,1));
blurRadius.addChangeListener(this);
blurRadius.setMaximumSize(new Dimension(75,(int)h));
algError = createErrorComponent();
algErrorEdge = createErrorComponent();
noiseError = createErrorComponent();
noiseErrorEdge = createErrorComponent();
configHolder.add(createWaveletConfig());
createBlurConfig();
addLabeled(images,"View",this);
addLabeled(noiseLevel,"Noise",this);
addSeparator(200);
addCenterLabel("Denoised",this);
addLabeled(algError,"Error",this);
addLabeled(algErrorEdge,"Edge Error",this);
addSeparator(200);
addCenterLabel("Noise Image",this);
addLabeled(noiseError,"Error",this);
addLabeled(noiseErrorEdge,"Edge Error",this);
addSeparator(200);
add(configHolder);
add(Box.createVerticalGlue());
}
private JPanel createWaveletConfig() {
waveletConfig = new JPanel();
waveletConfig.setLayout(new BoxLayout(waveletConfig,BoxLayout.Y_AXIS));
addCenterLabel("Wavelet Config",waveletConfig);
addLabeled(waveletBox,"Wavelet",waveletConfig);
addLabeled(waveletLevel,"Level",waveletConfig);
return waveletConfig;
}
private JPanel createBlurConfig() {
blurConfig = new JPanel();
blurConfig.setLayout(new BoxLayout(blurConfig,BoxLayout.Y_AXIS));
addCenterLabel("Blur Config",blurConfig);
addLabeled(blurRadius,"Radius",blurConfig);
return blurConfig;
}
public void setWaveletActive( boolean active ) {
if( active ){
configHolder.remove(blurConfig);
configHolder.add(waveletConfig);
} else {
configHolder.remove(waveletConfig);
configHolder.add(blurConfig);
}
validate();
}
public void addWaveletName( String name ) {
waveletBox.addItem(name);
waveletBox.validate();
}
private JTextArea createErrorComponent() {
JTextArea comp = new JTextArea(1,6);
comp.setMaximumSize(comp.getPreferredSize());
comp.setEditable(false);
return comp;
}
public void reset() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
images.setSelectedIndex(0);
noiseLevel.setValue(20);
}});
}
public void setListener(Listener listener) {
this.listener = listener;
}
@Override
public void stateChanged(ChangeEvent e) {
if( listener == null )
return;
if( e.getSource() == noiseLevel ) {
listener.noiseChange(getNoiseSigma());
} else if( e.getSource() == blurRadius ) {
listener.noiseChange(getBlurRadius());
} else if( e.getSource() == waveletLevel ) {
listener.waveletChange(waveletBox.getSelectedIndex(),getWaveletLevel());
}
}
@Override
public void actionPerformed(ActionEvent e) {
if( listener == null )
return;
if( e.getSource() == images ) {
listener.imageChange(images.getSelectedIndex());
} else {
listener.waveletChange(waveletBox.getSelectedIndex(),getWaveletLevel());
}
}
public void setError(double algError, double algErrorEdge, double noiseError , double noiseErrorEdge) {
this.algError.setText(String.format("%5.1f",algError));
this.algErrorEdge.setText(String.format("%5.1f",algErrorEdge));
this.noiseError.setText(String.format("%5.1f",noiseError));
this.noiseErrorEdge.setText(String.format("%5.1f",noiseErrorEdge));
}
/**
* Returns the number of levels in the wavelet transform.
*/
public int getWaveletLevel() {
return((Number)waveletLevel.getValue()).intValue();
}
/**
* Radius of the blur kernel
*/
public int getBlurRadius() {
return ((Number)blurRadius.getValue()).intValue();
}
public float getNoiseSigma() {
return ((Number)noiseLevel.getValue()).floatValue();
}
public static interface Listener
{
public void noiseChange( int radius );
public void waveletChange( int which , int level );
public void noiseChange( float sigma );
public void imageChange( int which );
}
}