/*
* 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.interest;
import boofcv.abst.feature.detect.interest.ConfigFastHessian;
import boofcv.abst.feature.detect.interest.ConfigSiftDetector;
import boofcv.abst.feature.detect.interest.InterestPointDetector;
import boofcv.alg.feature.detect.interest.FeatureLaplacePyramid;
import boofcv.demonstrations.feature.detect.ImageCorruptPanel;
import boofcv.factory.feature.detect.interest.FactoryInterestPoint;
import boofcv.factory.feature.detect.interest.FactoryInterestPointAlgs;
import boofcv.gui.SelectAlgorithmAndInputPanel;
import boofcv.gui.feature.FancyInterestPointRender;
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.image.GrayF32;
import boofcv.struct.image.ImageGray;
import georegression.struct.point.Point2D_F64;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
/**
* Displays a window point features with scale and orientation information
*
* @author Peter Abeles
*/
public class DetectFeaturePointSOApp
extends SelectAlgorithmAndInputPanel implements ImageCorruptPanel.Listener {
static int maxFeatures = 400;
static int maxScaleFeatures = maxFeatures / 3;
public double[] scales = new double[]{1, 1.5, 2, 3, 4, 6, 8, 10,12,14,16,18};
int radius = 2;
float thresh = 1;
T grayImage;
T corruptImage;
Class imageType;
boolean processImage = false;
BufferedImage input;
BufferedImage workImage;
FancyInterestPointRender render = new FancyInterestPointRender();
ImagePanel panel;
ImageCorruptPanel corruptPanel;
public DetectFeaturePointSOApp(Class imageType, Class derivType) {
super(1);
this.imageType = imageType;
FeatureLaplacePyramid flss = FactoryInterestPointAlgs.hessianLaplace(radius, thresh, maxScaleFeatures, imageType, derivType);
addAlgorithm(0, "Hess Lap SS", FactoryInterestPoint.wrapDetector(flss, scales, false, imageType));
FeatureLaplacePyramid flp = FactoryInterestPointAlgs.hessianLaplace(radius, thresh, maxScaleFeatures, imageType, derivType);
addAlgorithm(0, "Hess Lap P", FactoryInterestPoint.wrapDetector(flp, scales, true,imageType));
addAlgorithm(0, "FastHessian", FactoryInterestPoint.fastHessian(
new ConfigFastHessian(thresh, 2, maxScaleFeatures, 2, 9, 4, 4)));
addAlgorithm(0, "SIFT", FactoryInterestPoint.sift(null,new ConfigSiftDetector(2*maxScaleFeatures),imageType));
JPanel viewArea = new JPanel(new BorderLayout());
corruptPanel = new ImageCorruptPanel();
corruptPanel.setListener(this);
panel = new ImagePanel();
viewArea.add(corruptPanel, BorderLayout.WEST);
viewArea.add(panel, BorderLayout.CENTER);
setMainGUI(viewArea);
}
public void process(BufferedImage input) {
setInputImage(input);
this.input = input;
grayImage = ConvertBufferedImage.convertFromSingle(input, null, imageType);
corruptImage = (T) grayImage._createNew(grayImage.width, grayImage.height);
workImage = new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_INT_BGR);
panel.setBufferedImage(workImage);
panel.setPreferredSize(new Dimension(workImage.getWidth(), workImage.getHeight()));
doRefreshAll();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
revalidate();
processImage = true;
}
});
}
@Override
public void loadConfigurationFile(String fileName) {
}
@Override
public void refreshAll(Object[] cookies) {
setActiveAlgorithm(0, null, cookies[0]);
}
@Override
public synchronized void setActiveAlgorithm(int indexFamily, String name, Object cookie) {
if (input == null)
return;
// corrupt the input image
corruptPanel.corruptImage(grayImage, corruptImage);
final InterestPointDetector det = (InterestPointDetector) cookie;
det.detect(corruptImage);
render.reset();
for (int i = 0; i < det.getNumberOfFeatures(); i++) {
Point2D_F64 p = det.getLocation(i);
int radius = (int) Math.ceil(det.getRadius(i));
render.addCircle((int) p.x, (int) p.y, radius);
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ConvertBufferedImage.convertTo(corruptImage, workImage, true);
Graphics2D g2 = workImage.createGraphics();
g2.setStroke(new BasicStroke(3));
render.draw(g2);
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 processImage;
}
@Override
public synchronized void corruptImageChange() {
doRefreshAll();
}
public static void main(String args[]) {
DetectFeaturePointSOApp app = new DetectFeaturePointSOApp(GrayF32.class, GrayF32.class);
// DetectFeaturePointApp app = new DetectFeaturePointApp(GrayU8.class,GrayS16.class);
List inputs = new ArrayList();
inputs.add(new PathLabel("shapes", UtilIO.pathExample("shapes/shapes01.png")));
inputs.add(new PathLabel("amoeba",UtilIO.pathExample("amoeba_shapes.jpg")));
inputs.add(new PathLabel("sunflowers", UtilIO.pathExample("sunflowers.jpg")));
inputs.add(new PathLabel("beach", UtilIO.pathExample("scale/beach02.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, "Point Feature", true);
}
}
Ads help maintain this website.