/*
* 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.feature.detect.edge;
import boofcv.alg.feature.detect.edge.CannyEdge;
import boofcv.alg.feature.detect.edge.EdgeContour;
import boofcv.alg.filter.binary.GThresholdImageOps;
import boofcv.alg.filter.binary.LinearContourLabelChang2004;
import boofcv.alg.misc.GImageStatistics;
import boofcv.demonstrations.binary.SelectHistogramThresholdPanel;
import boofcv.factory.feature.detect.edge.FactoryEdgeDetectors;
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.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
/**
* Displays contours selected using different algorithms.
*
* @author Peter Abeles
*/
public class ShowEdgeContourApp
extends SelectAlgorithmAndInputPanel implements CannyControlBar.Listener , SelectHistogramThresholdPanel.Listener
{
// shows panel for displaying input image
ImagePanel panel = new ImagePanel();
BufferedImage input;
T workImage;
Class imageType;
Class derivType;
boolean processedImage = false;
GrayU8 binary = new GrayU8(1,1);
GrayS32 labeled = new GrayS32(1,1);
CannyControlBar barCanny;
SelectHistogramThresholdPanel barBinary;
JPanel bodyPanel = new JPanel();
int activeAlg;
int previousBlur;
CannyEdge canny;
LinearContourLabelChang2004 contour = new LinearContourLabelChang2004(ConnectRule.EIGHT);
public ShowEdgeContourApp(Class imageType, Class derivType) {
super(1);
this.imageType = imageType;
this.derivType = derivType;
addAlgorithm(0, "Canny", 0);
addAlgorithm(0, "Threshold Contour", 1);
barCanny = new CannyControlBar(1,15);
barCanny.setListener(this);
barBinary = new SelectHistogramThresholdPanel(50,true);
barBinary.setListener(this);
bodyPanel.setLayout(new BorderLayout());
bodyPanel.add(panel,BorderLayout.CENTER);
bodyPanel.add(barCanny,BorderLayout.NORTH);
setMainGUI(bodyPanel);
previousBlur = barCanny.getBlurRadius();
canny = FactoryEdgeDetectors.canny(previousBlur, true, true, imageType, derivType);
}
public void process( BufferedImage input ) {
setInputImage(input);
this.input = input;
workImage = ConvertBufferedImage.convertFromSingle(input, null, imageType);
// update the binary histogram threshold for this image
final double threshold = GImageStatistics.mean(workImage);
binary.reshape(workImage.width,workImage.height);
labeled.reshape(workImage.width,workImage.height);
final int width = input.getWidth();
final int height = input.getHeight();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
barBinary.setThreshold((int)threshold);
barBinary.getHistogramPanel().update(workImage);
panel.setPreferredSize(new Dimension(width,height));
processedImage = true;
doRefreshAll();
}});
}
@Override
public void loadConfigurationFile(String fileName) {}
@Override
public void refreshAll(Object[] cookies) {
setActiveAlgorithm(0,null,cookies[0]);
}
@Override
public void setActiveAlgorithm(int indexFamily, String name, Object cookie) {
activeAlg = ((Integer)cookie).intValue();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// swap control bar on top
if( activeAlg == 0 ){
bodyPanel.remove(barBinary);
bodyPanel.add(barCanny,BorderLayout.NORTH);
barCanny.repaint();
} else {
bodyPanel.remove(barCanny);
bodyPanel.add(barBinary,BorderLayout.NORTH);
barBinary.repaint();
}
validate();
}});
doProcess();
}
private void doProcess() {
if( input == null )
return;
final BufferedImage temp;
if( activeAlg == 0 ) {
if( previousBlur != barCanny.getBlurRadius() ) {
previousBlur = barCanny.getBlurRadius();
canny = FactoryEdgeDetectors.canny(previousBlur,true, true, imageType, derivType);
}
double thresh = barCanny.getThreshold()/100.0;
canny.process(workImage,(float)thresh*0.1f,(float)thresh,null);
List contours = canny.getContours();
temp = VisualizeBinaryData.renderContours(contours,null,workImage.width,workImage.height,null);
} else {
// create a binary image by thresholding
GThresholdImageOps.threshold(workImage, binary, barBinary.getThreshold(), barBinary.isDown());
contour.process(binary,labeled);
temp = VisualizeBinaryData.renderContours(contour.getContours().toList(),null,0xFF1010,
workImage.width,workImage.height,null);
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
panel.setBufferedImage(temp);
panel.repaint();
}});
}
@Override
public void changeInput(String name, int index) {
BufferedImage image = media.openImage(inputRefs.get(index).getPath());
if( image != null ) {
process(image);
}
}
@Override
public boolean getHasProcessedImage() {
return processedImage;
}
@Override
public void changeCanny() {
doProcess();
}
@Override
public void histogramThresholdChange() {
doProcess();
}
public static void main( String args[] ) {
ShowEdgeContourApp app =
new ShowEdgeContourApp(GrayF32.class, GrayF32.class);
// ShowFeatureOrientationApp app =
// new ShowFeatureOrientationApp(input,GrayU8.class, GrayS16.class);
List inputs = new ArrayList();
inputs.add(new PathLabel("shapes", UtilIO.pathExample("shapes/shapes01.png")));
inputs.add(new PathLabel("Room",UtilIO.pathExample("indoors01.jpg")));
inputs.add(new PathLabel("Objects",UtilIO.pathExample("simple_objects.jpg")));
inputs.add(new PathLabel("Indoors",UtilIO.pathExample("lines_indoors.jpg")));
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,"Contours", true);
System.out.println("Done");
}
}
Ads help maintain this website.