/*
* 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.intensity;
import boofcv.abst.distort.FDistort;
import boofcv.abst.feature.detect.intensity.*;
import boofcv.abst.filter.derivative.AnyImageDerivative;
import boofcv.alg.feature.detect.intensity.HessianBlobIntensity;
import boofcv.alg.filter.derivative.GImageDerivativeOps;
import boofcv.alg.misc.ImageStatistics;
import boofcv.factory.feature.detect.intensity.FactoryIntensityPointAlg;
import boofcv.factory.filter.blur.FactoryBlurFilter;
import boofcv.factory.transform.pyramid.FactoryPyramid;
import boofcv.gui.ListDisplayPanel;
import boofcv.gui.SelectAlgorithmAndInputPanel;
import boofcv.gui.image.ShowImages;
import boofcv.gui.image.VisualizeImageData;
import boofcv.io.PathLabel;
import boofcv.io.UtilIO;
import boofcv.io.image.ConvertBufferedImage;
import boofcv.struct.image.GrayF32;
import boofcv.struct.image.ImageGray;
import boofcv.struct.pyramid.PyramidFloat;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
/**
* Displays the feature intensity for each layer in a scale-space. The scale-space can be represented as a
* pyramid of set of blurred images.
*
* @author Peter Abeles
*/
public class IntensityFeaturePyramidApp
extends SelectAlgorithmAndInputPanel
{
ListDisplayPanel gui = new ListDisplayPanel();
PyramidFloat pyramid;
BufferedImage input;
T workImage;
GrayF32 scaledIntensity;
Class imageType;
AnyImageDerivative anyDerivative;
boolean processedImage = false;
GeneralFeatureIntensity intensity;
public IntensityFeaturePyramidApp(Class imageType, Class derivType ) {
super(2);
this.imageType = imageType;
addAlgorithm(0, "Hessian Det", new WrapperHessianBlobIntensity(HessianBlobIntensity.Type.DETERMINANT,derivType));
addAlgorithm(0, "Laplacian", new WrapperHessianBlobIntensity(HessianBlobIntensity.Type.TRACE,derivType));
addAlgorithm(0, "Harris",new WrapperGradientCornerIntensity(FactoryIntensityPointAlg.harris(2, 0.4f, false, derivType)));
addAlgorithm(0, "Shi Tomasi",new WrapperGradientCornerIntensity( FactoryIntensityPointAlg.shiTomasi(2, false, derivType)));
addAlgorithm(0, "FAST",new WrapperFastCornerIntensity(FactoryIntensityPointAlg.fast(5, 11, imageType)));
addAlgorithm(0, "KitRos",new WrapperKitRosCornerIntensity(derivType));
addAlgorithm(0, "Median",new WrapperMedianCornerIntensity(FactoryBlurFilter.median(imageType,2),imageType));
addAlgorithm(1 , "Pyramid", 0);
addAlgorithm(1 , "Scale-Space", 1);
setMainGUI(gui);
anyDerivative = GImageDerivativeOps.derivativeForScaleSpace(imageType,derivType);
}
@Override
public void setActiveAlgorithm(int indexFamily, String name, Object cookie) {
if( input == null ) {
return;
}
if( indexFamily == 0 ) {
intensity = (GeneralFeatureIntensity)cookie;
if( pyramid == null )
return;
} else if( indexFamily == 1 ) {
// setup the pyramid
double scales[] = new double[25];
for( int i = 0; i < scales.length ; i++ ) {
scales[i] = Math.exp(i*0.15);
}
if( ((Number)cookie).intValue() == 0 ) {
pyramid = FactoryPyramid.scaleSpacePyramid(scales, imageType);
} else {
pyramid = FactoryPyramid.scaleSpace(scales, imageType);
}
if( workImage != null )
pyramid.process(workImage);
if( intensity == null )
return;
}
// setup the feature intensity
gui.reset();
BufferedImage b = VisualizeImageData.grayMagnitude(workImage,null, 255);
gui.addImage(b,"Gray Image");
final ProgressMonitor progressMonitor = new ProgressMonitor(this,
"Computing Scale Space Pyramid Response",
"", 0, pyramid.getNumLayers());
for( int i = 0; i < pyramid.getNumLayers() && !progressMonitor.isCanceled(); i++ ) {
double scale = pyramid.getSigma(i);
T scaledImage = pyramid.getLayer(i);
anyDerivative.setInput(scaledImage);
D derivX = anyDerivative.getDerivative(true);
D derivY = anyDerivative.getDerivative(false);
D derivXX = anyDerivative.getDerivative(true,true);
D derivYY = anyDerivative.getDerivative(false,false);
D derivXY = anyDerivative.getDerivative(true,false);
intensity.process(scaledImage,derivX,derivY,derivXX,derivYY,derivXY);
GrayF32 featureImg = intensity.getIntensity();
// scale it up to full resolution
new FDistort(featureImg,scaledIntensity).interpNN().scaleExt().apply();
// visualize the rescaled intensity
b = VisualizeImageData.colorizeSign(scaledIntensity,null, ImageStatistics.maxAbs(scaledIntensity));
gui.addImage(b,String.format("Scale %6.2f",scale));
final int progressStatus = i+1;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
progressMonitor.setProgress(progressStatus);
}
});
}
gui.requestFocusInWindow();
}
public void process( final BufferedImage input ) {
setInputImage(input);
this.input = input;
workImage = ConvertBufferedImage.convertFromSingle(input, null, imageType);
scaledIntensity = new GrayF32(workImage.width,workImage.height);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setPreferredSize(new Dimension(input.getWidth(),input.getHeight()));
processedImage = true;
}});
doRefreshAll();
}
@Override
public void loadConfigurationFile(String fileName) {}
@Override
public void refreshAll(Object[] cookies) {
intensity = null;
pyramid = null;
setActiveAlgorithm(0,null,cookies[0]);
setActiveAlgorithm(1,null,cookies[1]);
}
@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;
}
public static void main( String args[] ) {
IntensityFeaturePyramidApp app =
new IntensityFeaturePyramidApp(GrayF32.class,GrayF32.class);
// IntensityFeaturePyramidApp app =
// new IntensityFeaturePyramidApp(GrayU8.class,GrayS16.class);
java.util.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,"Feature Scale Space Pyramid Intensity",true);
}
}
Ads help maintain this website.