/*
 * Copyright (c) 2011-2016, 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.binary;

import boofcv.abst.filter.FilterImageInterface;
import boofcv.alg.filter.binary.BinaryImageOps;
import boofcv.alg.filter.binary.Contour;
import boofcv.alg.filter.binary.GThresholdImageOps;
import boofcv.core.image.GeneralizedImageOps;
import boofcv.factory.filter.binary.FactoryBinaryImageOps;
import boofcv.gui.SelectAlgorithmAndInputPanel;
import boofcv.gui.binary.VisualizeBinaryData;
import boofcv.gui.image.ImagePanel;
import boofcv.gui.image.ShowImages;
import boofcv.io.PathLabel;
import boofcv.io.UtilIO;
import boofcv.io.image.ConvertBufferedImage;
import boofcv.struct.ConnectRule;
import boofcv.struct.image.GrayF32;
import boofcv.struct.image.GrayS32;
import boofcv.struct.image.GrayU8;
import boofcv.struct.image.ImageGray;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Demonstrates the affects of different binary operations on an image.
 */
public class DemoBinaryImageLabelOpsApp extends SelectAlgorithmAndInputPanel
		implements SelectHistogramThresholdPanel.Listener {

	Random rand = new Random(234234);

	Class imageType;
	T imageInput;
	GrayU8 imageBinary;
	GrayU8 imageOutput1;
	GrayU8 imageOutput2;
	GrayS32 imageLabeled;
	ImageGray selectedVisualize;

	FilterImageInterface filter1;
	FilterImageInterface filter2;
	ConnectRule connectRule;
	BufferedImage work;
	int colors[];

	boolean processedImage = false;

	JComboBox imagesCombo;
	SelectHistogramThresholdPanel selectThresh;
	ImagePanel gui = new ImagePanel();

	public DemoBinaryImageLabelOpsApp(Class imageType) {
		super(3);

		this.imageType = imageType;

		addAlgorithm(0,"Erode-4", FactoryBinaryImageOps.erode4());
		addAlgorithm(0,"Erode-8", FactoryBinaryImageOps.erode8());
		addAlgorithm(0,"Dilate-4", FactoryBinaryImageOps.dilate4());
		addAlgorithm(0,"Dilate-8", FactoryBinaryImageOps.dilate8());
		addAlgorithm(0,"Remove Noise", FactoryBinaryImageOps.removePointNoise());

		addAlgorithm(1,"Erode-4", FactoryBinaryImageOps.erode4());
		addAlgorithm(1,"Erode-8", FactoryBinaryImageOps.erode8());
		addAlgorithm(1,"Dilate-4", FactoryBinaryImageOps.dilate4());
		addAlgorithm(1,"Dilate-8", FactoryBinaryImageOps.dilate8());
		addAlgorithm(1,"Remove Noise", FactoryBinaryImageOps.removePointNoise());

		addAlgorithm(2, "Label-4", 4);
		addAlgorithm(2, "Label-8", 8);

		JPanel body = new JPanel();
		body.setLayout(new BorderLayout());

		body.add(createControlPanel(),BorderLayout.NORTH);
		body.add(gui,BorderLayout.CENTER);

		imageInput = GeneralizedImageOps.createSingleBand(imageType, 1, 1);
		imageBinary = new GrayU8(1,1);
		imageOutput1 = new GrayU8(1,1);
		imageOutput2 = new GrayU8(1,1);
		imageLabeled = new GrayS32(1,1);

		selectedVisualize = imageLabeled;

		setMainGUI(body);
	}

	private JPanel createControlPanel() {
		JPanel left = new JPanel();
		left.setLayout(new BoxLayout(left, BoxLayout.X_AXIS));

		imagesCombo = new JComboBox();
		imagesCombo.addItem("Thresholded");
		imagesCombo.addItem("Filtered 1");
		imagesCombo.addItem("Filtered 2");
		imagesCombo.addItem("Labeled");
		imagesCombo.addActionListener(this);
		imagesCombo.setSelectedIndex(3);
		imagesCombo.setMaximumSize(imagesCombo.getPreferredSize());

		selectThresh = new SelectHistogramThresholdPanel(20,true);
		selectThresh.setListener(this);

		left.add(imagesCombo);
		left.add(selectThresh);
		left.add(Box.createHorizontalGlue());

		return left;
	}

	public void process( final BufferedImage image ) {
		imageInput.reshape(image.getWidth(),image.getHeight());
		imageBinary.reshape(image.getWidth(),image.getHeight());
		imageOutput1.reshape(image.getWidth(),image.getHeight());
		imageOutput2.reshape(image.getWidth(),image.getHeight());
		imageLabeled.reshape(image.getWidth(),image.getHeight());

		ConvertBufferedImage.convertFromSingle(image, imageInput, imageType);

		final double threshold = GThresholdImageOps.computeOtsu(imageInput,0,255);
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				selectThresh.setThreshold((int) threshold);
				setInputImage(image);
				selectThresh.getHistogramPanel().update(imageInput);
				selectThresh.repaint();
			}});
		doRefreshAll();
	}

	@Override
	public void loadConfigurationFile(String fileName) {}

	@Override
	public boolean getHasProcessedImage() {
		return processedImage;
	}

	@Override
	public void refreshAll(Object[] cookies) {
		filter1 = (FilterImageInterface)cookies[0];
		filter2 = (FilterImageInterface)cookies[1];
		connectRule = (Integer)cookies[2] == 4 ? ConnectRule.FOUR : ConnectRule.EIGHT;
		performWork();
	}

	@Override
	public void setActiveAlgorithm(int indexFamily, String name, Object cookie) {
		switch( indexFamily ) {
			case 0:
				filter1 = (FilterImageInterface)cookie;
				break;
			case 1:
				filter2 = (FilterImageInterface)cookie;
				break;
			case 2:
				connectRule = (Integer)cookie == 4 ? ConnectRule.FOUR : ConnectRule.EIGHT;
				break;
		}

		performWork();
	}

	private synchronized void performWork() {
		if( filter1 == null || filter2 == null )
			return;
		GThresholdImageOps.threshold(imageInput, imageBinary, selectThresh.getThreshold(), selectThresh.isDown());
		filter1.process(imageBinary,imageOutput1);
		filter2.process(imageOutput1,imageOutput2);
		List found = BinaryImageOps.contour(imageOutput2, connectRule, imageLabeled);
		if( colors == null || colors.length <= found.size() )
			colors = BinaryImageOps.selectRandomColors(found.size(),rand);

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				if (work == null || work.getWidth() != imageInput.width || work.getHeight() != imageInput.height) {
					work = new BufferedImage(imageInput.width, imageInput.height, BufferedImage.TYPE_INT_BGR);
				}
				renderVisualizeImage();
				gui.setBufferedImage(work);
				gui.setPreferredSize(new Dimension(imageInput.width, imageInput.height));
				processedImage = true;
				gui.repaint();
			}
		});
	}

	private synchronized void renderVisualizeImage() {
		if( selectedVisualize instanceof GrayU8)
			VisualizeBinaryData.renderBinary((GrayU8) selectedVisualize, false, work);
		else {
			VisualizeBinaryData.renderLabeled((GrayS32) selectedVisualize, colors, work);
		}
	}

	@Override
	public void changeInput(String name, int index) {
		BufferedImage image = media.openImage(inputRefs.get(index).getPath());

		if( image != null ) {
			process(image);
		}
	}


	@Override
	public void actionPerformed(ActionEvent e) {
		if( e.getSource() == imagesCombo ) {
			int index = imagesCombo.getSelectedIndex();
			if( index == 0 ) {
				selectedVisualize = imageBinary;
			} else if( index == 1 ) {
				selectedVisualize = imageOutput1;
			} else if( index == 2 ) {
				selectedVisualize = imageOutput2;
			} else if( index == 3 ) {
				selectedVisualize = imageLabeled;
			}
			if( work != null ) {
				renderVisualizeImage();
				gui.repaint();
			}
		} else {
			super.actionPerformed(e);
		}
	}

	@Override
	public void histogramThresholdChange() {
		performWork();
	}

	public static void main( String args[] ) {
		DemoBinaryImageLabelOpsApp app = new DemoBinaryImageLabelOpsApp(GrayF32.class);

		List inputs = new ArrayList();
		inputs.add(new PathLabel("particles", UtilIO.pathExample("particles01.jpg")));
		inputs.add(new PathLabel("shapes",UtilIO.pathExample("shapes/shapes01.png")));

		app.setInputList(inputs);

		// wait for it to process one image so that the size isn't all screwed up
		while( !app.getHasProcessedImage() ) {
			Thread.yield();
		}

		ShowImages.showWindow(app, "Label Binary Blobs", true);

		System.out.println("Done");
	}
}

 

Ads help maintain this website.