/*
* 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.associate;
import boofcv.abst.feature.associate.AssociateDescription;
import boofcv.abst.feature.associate.ScoreAssociation;
import boofcv.abst.feature.detdesc.DetectDescribePoint;
import boofcv.abst.feature.detect.interest.ConfigFastHessian;
import boofcv.core.image.GeneralizedImageOps;
import boofcv.factory.feature.associate.FactoryAssociation;
import boofcv.factory.feature.detdesc.FactoryDetectDescribe;
import boofcv.gui.SelectAlgorithmAndInputPanel;
import boofcv.gui.feature.AssociationPanel;
import boofcv.gui.image.ShowImages;
import boofcv.io.PathLabel;
import boofcv.io.UtilIO;
import boofcv.io.image.ConvertBufferedImage;
import boofcv.struct.feature.TupleDesc_F64;
import boofcv.struct.image.GrayF32;
import boofcv.struct.image.ImageGray;
import georegression.struct.point.Point2D_F64;
import org.ddogleg.struct.FastQueue;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
/**
* Using the same descriptor show how associations changes with different algorithms.
*
* @author Peter Abeles
*/
public class VisualizeAssociationAlgorithmsApp
extends SelectAlgorithmAndInputPanel
{
DetectDescribePoint detector;
AssociateDescription alg;
T image0;
T image1;
Class imageType;
AssociationPanel panel = new AssociationPanel(20);
boolean processedImage = false;
FastQueue features0 = new FastQueue(1,TupleDesc_F64.class,false);
FastQueue points0 = new FastQueue(1,Point2D_F64.class,true);
FastQueue features1 = new FastQueue(1,TupleDesc_F64.class,false);
FastQueue points1 = new FastQueue(1,Point2D_F64.class,true);
public VisualizeAssociationAlgorithmsApp( Class imageType ) {
super(1);
this.imageType = imageType;
detector = (DetectDescribePoint) FactoryDetectDescribe.surfStable(
new ConfigFastHessian(5, 4, 200, 1, 9, 4, 4), null, null, GrayF32.class);
// detector = (DetectDescribePoint) FactoryDetectDescribe.sift(4,1,false,200);
int DOF = detector.createDescription().size();
ScoreAssociation score = FactoryAssociation.scoreEuclidean(TupleDesc_F64.class,true);
addAlgorithm(0, "Greedy", FactoryAssociation.greedy(score, Double.MAX_VALUE, false));
addAlgorithm(0, "Greedy Backwards", FactoryAssociation.greedy(score, Double.MAX_VALUE, true));
addAlgorithm(0, "K-D Tree BBF", FactoryAssociation.kdtree(DOF, 75));
addAlgorithm(0, "Random Forest", FactoryAssociation.kdRandomForest(DOF, 75, 10, 5, 1233445565));
image0 = GeneralizedImageOps.createSingleBand(imageType, 1, 1);
image1 = GeneralizedImageOps.createSingleBand(imageType, 1, 1);
setMainGUI(panel);
}
public void process(final BufferedImage buffLeft, final BufferedImage buffRight) {
image0.reshape(buffLeft.getWidth(), buffLeft.getHeight());
image1.reshape(buffRight.getWidth(), buffRight.getHeight());
ConvertBufferedImage.convertFromSingle(buffLeft, image0, imageType);
ConvertBufferedImage.convertFromSingle(buffRight, image1, imageType);
createSet(image0,features0,points0);
createSet(image1,features1,points1);
System.out.println("Found features: "+features0.size()+" "+features1.size());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
panel.setImages(buffLeft, buffRight);
processedImage = true;
doRefreshAll();
}
});
}
private void createSet( T image , FastQueue descs , FastQueue points ) {
detector.detect(image);
descs.reset();
points.reset();
for( int i = 0; i < detector.getNumberOfFeatures(); i++ ) {
points.grow().set(detector.getLocation(i));
descs.add( detector.getDescription(i).copy() );
}
}
public void processImages() {
long before = System.currentTimeMillis();
alg.setSource(features0);
alg.setDestination(features1);
long before1 = System.currentTimeMillis();
alg.associate();
long after = System.currentTimeMillis();
System.out.println("Elapsed: "+(after-before)+" or "+(after-before1));
SwingUtilities.invokeLater(new Runnable() {
public void run() {
panel.setAssociation(points0.toList(), points1.toList(), alg.getMatches());
repaint();
}
});
}
@Override
public void refreshAll(Object[] cookies) {
alg = (AssociateDescription)cookies[0];
processImages();
}
@Override
public void setActiveAlgorithm(int indexFamily, String name, Object cookie) {
alg = (AssociateDescription)cookie;
processImages();
}
@Override
public void changeInput(String name, int index) {
BufferedImage left = media.openImage(inputRefs.get(index).getPath(0));
BufferedImage right = media.openImage(inputRefs.get(index).getPath(1));
process(left, right);
}
@Override
public void loadConfigurationFile(String fileName) {}
@Override
public boolean getHasProcessedImage() {
return processedImage;
}
public static void main(String args[]) {
Class imageType = GrayF32.class;
VisualizeAssociationAlgorithmsApp app = new VisualizeAssociationAlgorithmsApp(imageType);
List inputs = new ArrayList();
inputs.add(new PathLabel("Cave",
UtilIO.pathExample("stitch/cave_01.jpg"), UtilIO.pathExample("stitch/cave_02.jpg")));
inputs.add(new PathLabel("Kayak",
UtilIO.pathExample("stitch/kayak_02.jpg"), UtilIO.pathExample("stitch/kayak_03.jpg")));
inputs.add(new PathLabel("Forest",
UtilIO.pathExample("scale/rainforest_01.jpg"), UtilIO.pathExample("scale/rainforest_02.jpg")));
inputs.add(new PathLabel("Building",
UtilIO.pathExample("stitch/apartment_building_01.jpg"), UtilIO.pathExample("stitch/apartment_building_02.jpg")));
inputs.add(new PathLabel("Trees Rotate",
UtilIO.pathExample("stitch/trees_rotate_01.jpg"), UtilIO.pathExample("stitch/trees_rotate_03.jpg")));
app.setPreferredSize(new Dimension(1000, 500));
app.setSize(1000, 500);
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, "Associated Features", true);
}
}
Ads help maintain this website.