boofcv.factory.feature.detdesc.FactoryDetectDescribe Maven / Gradle / Ivy
Show all versions of boofcv-feature Show documentation
/*
* Copyright (c) 2011-2020, 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.factory.feature.detdesc;
import boofcv.abst.feature.describe.ConfigSiftDescribe;
import boofcv.abst.feature.describe.ConfigSiftScaleSpace;
import boofcv.abst.feature.describe.ConfigSurfDescribe;
import boofcv.abst.feature.describe.DescribeRegionPoint;
import boofcv.abst.feature.detdesc.*;
import boofcv.abst.feature.detect.extract.NonMaxLimiter;
import boofcv.abst.feature.detect.extract.NonMaxSuppression;
import boofcv.abst.feature.detect.interest.ConfigFastHessian;
import boofcv.abst.feature.detect.interest.ConfigSiftDetector;
import boofcv.abst.feature.detect.interest.InterestPointDetector;
import boofcv.abst.feature.orientation.*;
import boofcv.alg.feature.describe.DescribePointSift;
import boofcv.alg.feature.describe.DescribePointSurf;
import boofcv.alg.feature.describe.DescribePointSurfMod;
import boofcv.alg.feature.describe.DescribePointSurfPlanar;
import boofcv.alg.feature.detdesc.CompleteSift;
import boofcv.alg.feature.detdesc.DetectDescribeSurfPlanar;
import boofcv.alg.feature.detdesc.DetectDescribeSurfPlanar_MT;
import boofcv.alg.feature.detect.interest.FastHessianFeatureDetector;
import boofcv.alg.feature.detect.interest.GeneralFeatureDetector;
import boofcv.alg.feature.detect.interest.SiftScaleSpace;
import boofcv.alg.feature.orientation.OrientationHistogramSift;
import boofcv.alg.transform.ii.GIntegralImageOps;
import boofcv.concurrency.BoofConcurrency;
import boofcv.factory.feature.describe.ConfigDescribeRegionPoint;
import boofcv.factory.feature.describe.FactoryDescribePointAlgs;
import boofcv.factory.feature.describe.FactoryDescribeRegionPoint;
import boofcv.factory.feature.detect.extract.FactoryFeatureExtractor;
import boofcv.factory.feature.detect.interest.ConfigDetectInterestPoint;
import boofcv.factory.feature.detect.interest.FactoryDetectPoint;
import boofcv.factory.feature.detect.interest.FactoryInterestPoint;
import boofcv.factory.feature.detect.interest.FactoryInterestPointAlgs;
import boofcv.factory.feature.orientation.FactoryOrientation;
import boofcv.factory.feature.orientation.FactoryOrientationAlgs;
import boofcv.struct.feature.BrightFeature;
import boofcv.struct.feature.TupleDesc;
import boofcv.struct.image.GrayF32;
import boofcv.struct.image.ImageGray;
import boofcv.struct.image.ImageMultiBand;
import boofcv.struct.image.ImageType;
import javax.annotation.Nullable;
/**
* Creates instances of {@link DetectDescribePoint} for different feature detectors/describers.
*
* @author Peter Abeles
*/
public class FactoryDetectDescribe {
/**
* Generic factory for all detector / descriptors
*/
public static >
DetectDescribePoint generic( ConfigDetectDescribe config , Class imageType )
{
DetectDescribePoint detDesc = null;
if( config.typeDetector == ConfigDetectInterestPoint.DetectorType.FAST_HESSIAN ) {
switch (config.typeDescribe) {
case SURF_FAST:detDesc = FactoryDetectDescribe.surfFast(
config.detectFastHessian, config.describeSurfFast,null,imageType);
break;
case SURF_STABLE:detDesc = FactoryDetectDescribe.surfStable(
config.detectFastHessian, config.describeSurfStability,null,imageType);
break;
}
} else if( config.typeDescribe == ConfigDescribeRegionPoint.DescriptorType.SIFT ) {
var configSift = new ConfigCompleteSift();
configSift.scaleSpace = config.scaleSpaceSift;
configSift.detector = config.detectSift;
configSift.describe = config.describeSift;
detDesc = FactoryDetectDescribe.sift(configSift, imageType);
}
if( detDesc != null )
return detDesc;
InterestPointDetector detector;
switch(config.typeDetector) {
case FAST_HESSIAN: detector = FactoryInterestPoint.fastHessian(config.detectFastHessian,imageType); break;
case SIFT: detector =
FactoryInterestPoint.sift(config.scaleSpaceSift,config.detectSift,imageType); break;
case POINT: {
GeneralFeatureDetector alg = FactoryDetectPoint.create(config.detectPoint,imageType,null);
detector = FactoryInterestPoint.wrapPoint(
alg, config.detectPoint.scaleRadius, imageType, alg.getDerivType());
} break;
default: throw new IllegalArgumentException("Unknown detector");
}
DescribeRegionPoint descriptor;
switch(config.typeDescribe) {
case SURF_FAST:
descriptor = FactoryDescribeRegionPoint.surfFast(config.describeSurfFast, imageType); break;
case SURF_STABLE:
descriptor = FactoryDescribeRegionPoint.surfStable(config.describeSurfStability, imageType); break;
case SIFT: descriptor =
FactoryDescribeRegionPoint.sift(config.scaleSpaceSift,config.describeSift, imageType); break;
case BRIEF: descriptor = FactoryDescribeRegionPoint.brief(config.describeBrief, imageType); break;
case TEMPLATE: descriptor =
FactoryDescribeRegionPoint.template(config.describeTemplate, imageType); break;
default: throw new IllegalArgumentException("Unknown descriptor");
}
OrientationImage orientation = null;
// only compute orientation if the descriptor will use it
if( descriptor.isOriented() ) {
Class integralType = GIntegralImageOps.getIntegralType(imageType);
OrientationIntegral orientationII = FactoryOrientationAlgs.sliding_ii(null, integralType);
orientation = FactoryOrientation.convertImage(orientationII, imageType);
}
return FactoryDetectDescribe.fuseTogether(detector,orientation,descriptor);
}
/**
* Creates a new SIFT feature detector and describer.
*
* @see CompleteSift
*
* @param config Configuration for the SIFT detector and descriptor.
* @return SIFT
*/
public static >
DetectDescribePoint sift( @Nullable ConfigCompleteSift config, Class imageType)
{
if( config == null )
config = new ConfigCompleteSift();
ConfigSiftScaleSpace configSS = config.scaleSpace;
ConfigSiftDetector configDetector = config.detector;
ConfigSiftOrientation configOri = config.orientation;
ConfigSiftDescribe configDesc = config.describe;
SiftScaleSpace scaleSpace = new SiftScaleSpace(
configSS.firstOctave,configSS.lastOctave,configSS.numScales,configSS.sigma0);
OrientationHistogramSift orientation = new OrientationHistogramSift<>(
configOri.histogramSize,configOri.sigmaEnlarge,GrayF32.class);
DescribePointSift describe = new DescribePointSift<>(
configDesc.widthSubregion,configDesc.widthGrid, configDesc.numHistogramBins,
configDesc.sigmaToPixels, configDesc.weightingSigmaFraction,
configDesc.maxDescriptorElementValue,GrayF32.class);
NonMaxSuppression nns = FactoryFeatureExtractor.nonmax(configDetector.extract);
NonMaxLimiter nonMax = new NonMaxLimiter(nns,configDetector.maxFeaturesPerScale);
CompleteSift dds = new CompleteSift(scaleSpace,configDetector.edgeR,nonMax,orientation,describe);
return new DetectDescribe_CompleteSift<>(dds,imageType);
}
/**
*
* Creates a SURF descriptor. SURF descriptors are invariant to illumination, orientation, and scale.
* BoofCV provides two variants. Creates a variant which is designed for speed at the cost of some stability.
* Different descriptors are created for color and gray-scale images.
*
*
*
* [1] Add tech report when its finished. See SURF performance web page for now.
*
*
* @see FastHessianFeatureDetector
* @see DescribePointSurf
* @see DescribePointSurfPlanar
*
* @param configDetector Configuration for SURF detector
* @param configDesc Configuration for SURF descriptor
* @param configOrientation Configuration for orientation
* @return SURF detector and descriptor
*/
public static , II extends ImageGray>
DetectDescribePoint surfFast( @Nullable ConfigFastHessian configDetector ,
@Nullable ConfigSurfDescribe.Fast configDesc,
@Nullable ConfigAverageIntegral configOrientation,
Class imageType) {
Class integralType = GIntegralImageOps.getIntegralType(imageType);
FastHessianFeatureDetector detector = FactoryInterestPointAlgs.fastHessian(configDetector);
DescribePointSurf describe = FactoryDescribePointAlgs.surfSpeed(configDesc, integralType);
OrientationIntegral orientation = FactoryOrientationAlgs.average_ii(configOrientation, integralType);
if(BoofConcurrency.USE_CONCURRENT) {
return new WrapDetectDescribeSurf_MT<>(detector, orientation, describe, imageType);
} else {
return new WrapDetectDescribeSurf<>(detector, orientation, describe, imageType);
}
}
/**
*
* Color version of SURF stable. Features are detected in a gray scale image, but the descriptors are
* computed using a color image. Each band in the page adds to the descriptor length. See
* {@link DetectDescribeSurfPlanar} for details.
*
*
* @see FastHessianFeatureDetector
* @see DescribePointSurf
* @see DescribePointSurfPlanar
*
* @param configDetector Configuration for SURF detector
* @param configDesc Configuration for SURF descriptor
* @param configOrientation Configuration for orientation
* @return SURF detector and descriptor
*/
public static , II extends ImageGray>
DetectDescribePoint surfColorFast( @Nullable ConfigFastHessian configDetector ,
@Nullable ConfigSurfDescribe.Fast configDesc,
@Nullable ConfigAverageIntegral configOrientation,
ImageType imageType) {
Class bandType = imageType.getImageClass();
Class integralType = GIntegralImageOps.getIntegralType(bandType);
FastHessianFeatureDetector detector = FactoryInterestPointAlgs.fastHessian(configDetector);
DescribePointSurf describe = FactoryDescribePointAlgs.surfSpeed(configDesc, integralType);
OrientationIntegral orientation = FactoryOrientationAlgs.average_ii(configOrientation, integralType);
if( imageType.getFamily() == ImageType.Family.PLANAR) {
DescribePointSurfPlanar describeMulti =
new DescribePointSurfPlanar<>(describe, imageType.getNumBands());
DetectDescribeSurfPlanar detectDesc = createDescribeSurfPlanar(detector, orientation, describeMulti);
return new SurfPlanar_to_DetectDescribePoint( detectDesc,bandType,integralType );
} else {
throw new IllegalArgumentException("Image type not supported");
}
}
protected static > DetectDescribeSurfPlanar createDescribeSurfPlanar(FastHessianFeatureDetector detector, OrientationIntegral orientation, DescribePointSurfPlanar describeMulti) {
DetectDescribeSurfPlanar detectDesc;
if( BoofConcurrency.USE_CONCURRENT ) {
detectDesc = new DetectDescribeSurfPlanar_MT<>(detector, orientation, describeMulti);
} else {
detectDesc = new DetectDescribeSurfPlanar<>(detector, orientation, describeMulti);
}
return detectDesc;
}
/**
*
* Creates a SURF descriptor. SURF descriptors are invariant to illumination, orientation, and scale.
* BoofCV provides two variants. Creates a variant which is designed for stability. Different descriptors are
* created for color and gray-scale images.
*
*
*
* [1] Add tech report when its finished. See SURF performance web page for now.
*
*
* @see DescribePointSurfPlanar
* @see FastHessianFeatureDetector
* @see boofcv.alg.feature.describe.DescribePointSurfMod
*
* @param configDetector Configuration for SURF detector. Null for default.
* @param configDescribe Configuration for SURF descriptor. Null for default.
* @param configOrientation Configuration for region orientation. Null for default.
* @param imageType Specify type of input image.
* @return SURF detector and descriptor
*/
public static , II extends ImageGray>
DetectDescribePoint surfStable( @Nullable ConfigFastHessian configDetector,
@Nullable ConfigSurfDescribe.Stability configDescribe,
@Nullable ConfigSlidingIntegral configOrientation,
Class imageType ) {
Class integralType = GIntegralImageOps.getIntegralType(imageType);
FastHessianFeatureDetector detector = FactoryInterestPointAlgs.fastHessian(configDetector);
DescribePointSurfMod describe = FactoryDescribePointAlgs.surfStability(configDescribe, integralType);
OrientationIntegral orientation = FactoryOrientationAlgs.sliding_ii(configOrientation, integralType);
if(BoofConcurrency.USE_CONCURRENT) {
return new WrapDetectDescribeSurf_MT<>(detector, orientation, describe, imageType);
} else {
return new WrapDetectDescribeSurf<>(detector, orientation, describe, imageType);
}
}
/**
*
* Color version of SURF stable feature. Features are detected in a gray scale image, but the descriptors are
* computed using a color image. Each band in the page adds to the descriptor length. See
* {@link DetectDescribeSurfPlanar} for details.
*
*
* @see DescribePointSurfPlanar
* @see FastHessianFeatureDetector
* @see boofcv.alg.feature.describe.DescribePointSurfMod
*
* @param configDetector Configuration for SURF detector. Null for default.
* @param configDescribe Configuration for SURF descriptor. Null for default.
* @param configOrientation Configuration for region orientation. Null for default.
* @param imageType Specify type of color input image.
* @return SURF detector and descriptor
*/
public static , II extends ImageGray>
DetectDescribePoint surfColorStable( @Nullable ConfigFastHessian configDetector,
@Nullable ConfigSurfDescribe.Stability configDescribe,
@Nullable ConfigSlidingIntegral configOrientation,
ImageType imageType ) {
Class bandType = imageType.getImageClass();
Class integralType = GIntegralImageOps.getIntegralType(bandType);
FastHessianFeatureDetector detector = FactoryInterestPointAlgs.fastHessian(configDetector);
DescribePointSurfMod describe = FactoryDescribePointAlgs.surfStability(configDescribe, integralType);
OrientationIntegral orientation = FactoryOrientationAlgs.sliding_ii(configOrientation, integralType);
if( imageType.getFamily() == ImageType.Family.PLANAR) {
DescribePointSurfPlanar describeMulti =
new DescribePointSurfPlanar<>(describe, imageType.getNumBands());
DetectDescribeSurfPlanar detectDesc = createDescribeSurfPlanar(detector, orientation, describeMulti);
return new SurfPlanar_to_DetectDescribePoint( detectDesc,bandType,integralType );
} else {
throw new IllegalArgumentException("Image type not supported");
}
}
/**
* Given independent algorithms for feature detection, orientation, and describing, create a new
* {@link DetectDescribePoint}.
*
* @param detector Feature detector
* @param orientation Orientation estimation. Optionally, can be null.
* @param describe Feature descriptor
* @return {@link DetectDescribePoint}.
*/
public static , D extends TupleDesc>
DetectDescribePoint fuseTogether( InterestPointDetector detector,
@Nullable OrientationImage orientation,
DescribeRegionPoint describe) {
return new DetectDescribeFusion<>(detector, orientation, describe);
}
}