/*
 * 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.segmentation;

import boofcv.factory.segmentation.ConfigFh04;
import boofcv.factory.segmentation.ConfigSegmentMeanShift;
import boofcv.factory.segmentation.ConfigSlic;
import boofcv.factory.segmentation.ConfigWatershed;
import boofcv.gui.StandardAlgConfigPanel;
import boofcv.struct.ConnectRule;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * Panel which allows the user to configure segmentation algorithms and select the visualization
 *
 * @author Peter Abeles
 */
public class SegmentConfigPanel extends StandardAlgConfigPanel implements ActionListener{

	JComboBox selectVisualize;

	JProgressBar progress = new JProgressBar();

	VisualizeImageSegmentationApp owner;

	JButton recompute = new JButton("Recompute");

	ConfigFh04 configFh = new ConfigFh04();
	ConfigSlic configSlic = new ConfigSlic(800);
	ConfigSegmentMeanShift configMeanShift = new ConfigSegmentMeanShift();
	ConfigWatershed configWatershed = new ConfigWatershed();

	JPanel panelConfig = new JPanel();
	PanelConfigFH panelFh = new PanelConfigFH();
	PanelConfigSlic panelSlic = new PanelConfigSlic();
	PanelConfigMeanShift panelMS = new PanelConfigMeanShift();
	PanelConfigWatershed panelWater = new PanelConfigWatershed();

	public SegmentConfigPanel(VisualizeImageSegmentationApp owner) {
		this.owner = owner;

		selectVisualize = new JComboBox(new String[]{"Color","Border","Regions"});
		selectVisualize.addActionListener(this);
		selectVisualize.setMaximumSize(selectVisualize.getPreferredSize());

		recompute.addActionListener(this);

		panelConfig.setLayout(new BorderLayout());

		addLabeled(selectVisualize, "Visualize", this);
		addSeparator(100);
		addAlignCenter(recompute,this);
		addAlignCenter(progress, this);
		addAlignCenter(panelConfig,this);
	}

	public void setComputing( final boolean isComputing ) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				if( isComputing ) {
					progress.setIndeterminate(true);
					progress.setEnabled(true);
				} else {
					progress.setIndeterminate(false);
					progress.setEnabled(false);
				}
			}});
	}

	protected void configHasChange() {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				recompute.setEnabled(true);
			}});
	}

	public void switchAlgorithm( final int which ) {
		// the GUI freezes if this is invoked in the GUI thread!?!?
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				recompute.setEnabled(false);
				panelConfig.removeAll();
				if( which == 0 ) {
					panelConfig.add(panelFh,BorderLayout.CENTER);
				} else if( which == 1 ) {
					panelConfig.add(panelSlic,BorderLayout.CENTER);
				} else if( which == 2 ) {
					panelConfig.add(panelMS,BorderLayout.CENTER);
				} else if( which == 3 ) {
					panelConfig.add(panelWater,BorderLayout.CENTER);
				}
				panelConfig.revalidate();
				repaint();
			}});
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if( selectVisualize == e.getSource() )
			owner.updateActiveDisplay(selectVisualize.getSelectedIndex());
		else if( recompute == e.getSource() ) {
			recompute.setEnabled(false);
			owner.recompute();
		}
	}

	private class PanelConfigFH extends StandardAlgConfigPanel implements ActionListener, ChangeListener {

		JComboBox selectConnect;
		JSpinner spinnerSize;
		JSpinner spinnerK;

		public PanelConfigFH() {
			selectConnect = new JComboBox(new String[]{"4-Connect","8-Connect"});
			selectConnect.addActionListener(this);
			selectConnect.setMaximumSize(selectConnect.getPreferredSize());

			spinnerSize = new JSpinner(new SpinnerNumberModel(10,5,200,5));
			spinnerSize.addChangeListener(this);
			spinnerSize.setMaximumSize(spinnerSize.getPreferredSize());

			spinnerK = new JSpinner(new SpinnerNumberModel(10,10,4000,100));
			spinnerK.addChangeListener(this);
			spinnerK.setMaximumSize(spinnerK.getPreferredSize());

			configure();

			addAlignCenter(selectConnect,this);
			addLabeled(spinnerSize, "Min Size", this);
			addLabeled(spinnerK, "K", this);
		}

		private void configure() {
			if( configFh.connectRule == ConnectRule.FOUR )
				selectConnect.setSelectedIndex(0);
			else
				selectConnect.setSelectedIndex(1);

			spinnerSize.setValue(configFh.minimumRegionSize);
			spinnerK.setValue(configFh.K);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			configHasChange();
			if( selectConnect == e.getSource() ) {
				int which = selectConnect.getSelectedIndex();
				if( which == 0 )
					configFh.connectRule = ConnectRule.FOUR;
				else
					configFh.connectRule = ConnectRule.EIGHT;
			}
		}

		@Override
		public void stateChanged(ChangeEvent e) {
			configHasChange();
			if( spinnerSize == e.getSource() ) {
				configFh.minimumRegionSize = ((Number) spinnerSize.getValue()).intValue();
			} else if( spinnerK == e.getSource() ) {
				configFh.K = ((Number) spinnerK.getValue()).floatValue();
			}
		}
	}

	private class PanelConfigSlic extends StandardAlgConfigPanel implements ActionListener, ChangeListener {

		JComboBox selectConnect;
		JSpinner spinnerTotal;
		JSpinner spinnerWeight;

		public PanelConfigSlic() {
			selectConnect = new JComboBox(new String[]{"4-Connect","8-Connect"});
			selectConnect.addActionListener(this);
			selectConnect.setMaximumSize(selectConnect.getPreferredSize());

			spinnerTotal = new JSpinner(new SpinnerNumberModel(10,10,2000,10));
			spinnerTotal.addChangeListener(this);
			spinnerTotal.setMaximumSize(spinnerTotal.getPreferredSize());

			spinnerWeight = new JSpinner(new SpinnerNumberModel(10,10,1000,10));
			spinnerWeight.addChangeListener(this);
			spinnerWeight.setMaximumSize(spinnerWeight.getPreferredSize());

			configure();

			addAlignCenter(selectConnect,this);
			addLabeled(spinnerTotal, "Regions", this);
			addLabeled(spinnerWeight, "Weight", this);
		}

		private void configure() {
			if( configSlic.connectRule == ConnectRule.FOUR )
				selectConnect.setSelectedIndex(0);
			else
				selectConnect.setSelectedIndex(1);

			spinnerTotal.setValue(configSlic.numberOfRegions);
			spinnerWeight.setValue(configSlic.spacialWeight);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			configHasChange();
			if( selectConnect == e.getSource() ) {
				int which = selectConnect.getSelectedIndex();
				if( which == 0 )
					configSlic.connectRule = ConnectRule.FOUR;
				else
					configSlic.connectRule = ConnectRule.EIGHT;
			}
		}

		@Override
		public void stateChanged(ChangeEvent e) {
			configHasChange();
			if( spinnerTotal == e.getSource() ) {
				configSlic.numberOfRegions = ((Number) spinnerTotal.getValue()).intValue();
			} else if( spinnerWeight == e.getSource() ) {
				configSlic.spacialWeight = ((Number) spinnerWeight.getValue()).floatValue();
			}
		}
	}

	private class PanelConfigMeanShift extends StandardAlgConfigPanel implements ActionListener, ChangeListener {

		JComboBox selectConnect;
		JSpinner spinnerSize;
		JSpinner spinnerSpacial;
		JSpinner spinnerColor;
		JCheckBox toggleFast;

		public PanelConfigMeanShift() {
			selectConnect = new JComboBox(new String[]{"4-Connect","8-Connect"});
			selectConnect.addActionListener(this);
			selectConnect.setMaximumSize(selectConnect.getPreferredSize());

			spinnerSize = new JSpinner(new SpinnerNumberModel(10,5,200,5));
			spinnerSize.addChangeListener(this);
			spinnerSize.setMaximumSize(spinnerSize.getPreferredSize());

			spinnerSpacial = new JSpinner(new SpinnerNumberModel(10,1,50,1));
			spinnerSpacial.addChangeListener(this);
			spinnerSpacial.setMaximumSize(spinnerSpacial.getPreferredSize());

			spinnerColor = new JSpinner(new SpinnerNumberModel(10,5,255,5));
			spinnerColor.addChangeListener(this);
			spinnerColor.setMaximumSize(spinnerColor.getPreferredSize());

			toggleFast = new JCheckBox("Fast");
			toggleFast.addChangeListener(this);
			toggleFast.setMaximumSize(toggleFast.getPreferredSize());

			configure();

			addAlignCenter(selectConnect,this);
			addLabeled(spinnerSize, "Min Size", this);
			addLabeled(spinnerSpacial, "Spacial Rad", this);
			addLabeled(spinnerColor, "Color Rad", this);
			addAlignCenter(toggleFast, this);
		}

		private void configure() {
			if( configMeanShift.connectRule == ConnectRule.FOUR )
				selectConnect.setSelectedIndex(0);
			else
				selectConnect.setSelectedIndex(1);

			spinnerSize.setValue(configMeanShift.minimumRegionSize);
			spinnerSpacial.setValue(configMeanShift.spacialRadius);
			spinnerColor.setValue(configMeanShift.colorRadius);
			toggleFast.setSelected(configMeanShift.fast);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			configHasChange();
			if( selectConnect == e.getSource() ) {
				int which = selectConnect.getSelectedIndex();
				if( which == 0 )
					configMeanShift.connectRule = ConnectRule.FOUR;
				else
					configMeanShift.connectRule = ConnectRule.EIGHT;
			}
		}

		@Override
		public void stateChanged(ChangeEvent e) {
			configHasChange();
			if( spinnerSize == e.getSource() ) {
				configMeanShift.minimumRegionSize = ((Number) spinnerSize.getValue()).intValue();
			} else if( spinnerSpacial == e.getSource() ) {
				configMeanShift.spacialRadius = ((Number) spinnerSpacial.getValue()).intValue();
			} else if( spinnerColor == e.getSource() ) {
				configMeanShift.colorRadius = ((Number) spinnerColor.getValue()).intValue();
			} else if( toggleFast == e.getSource() ) {
				configMeanShift.fast = toggleFast.isSelected();
			}
		}
	}

	private class PanelConfigWatershed extends StandardAlgConfigPanel implements ActionListener, ChangeListener {

		JComboBox selectConnect;
		JSpinner spinnerSize;

		public PanelConfigWatershed() {
			selectConnect = new JComboBox(new String[]{"4-Connect","8-Connect"});
			selectConnect.addActionListener(this);
			selectConnect.setMaximumSize(selectConnect.getPreferredSize());

			spinnerSize = new JSpinner(new SpinnerNumberModel(10,0,500,5));
			spinnerSize.addChangeListener(this);
			spinnerSize.setMaximumSize(spinnerSize.getPreferredSize());



			configure();

			addAlignCenter(selectConnect, this);
			addLabeled(spinnerSize, "Min Size", this);
		}

		private void configure() {
			if( configWatershed.connectRule == ConnectRule.FOUR )
				selectConnect.setSelectedIndex(0);
			else
				selectConnect.setSelectedIndex(1);

			spinnerSize.setValue(configWatershed.minimumRegionSize);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			configHasChange();
			if( selectConnect == e.getSource() ) {
				int which = selectConnect.getSelectedIndex();
				if( which == 0 )
					configWatershed.connectRule = ConnectRule.FOUR;
				else
					configWatershed.connectRule = ConnectRule.EIGHT;
			}
		}

		@Override
		public void stateChanged(ChangeEvent e) {
			configHasChange();
			if( spinnerSize == e.getSource() ) {
				configWatershed.minimumRegionSize = ((Number) spinnerSize.getValue()).intValue();
			}
		}
	}

	public ConfigFh04 getConfigFh() {
		return configFh;
	}

	public ConfigSlic getConfigSlic() {
		return configSlic;
	}

	public ConfigSegmentMeanShift getConfigMeanShift() {
		return configMeanShift;
	}

	public ConfigWatershed getConfigWatershed() {
		return configWatershed;
	}
}

 

Ads help maintain this website.