001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.image.feature.local.engine; 031 032import org.openimaj.citation.annotation.Reference; 033import org.openimaj.citation.annotation.ReferenceType; 034import org.openimaj.feature.local.list.LocalFeatureList; 035import org.openimaj.image.FImage; 036import org.openimaj.image.analysis.pyramid.gaussian.GaussianOctave; 037import org.openimaj.image.analysis.pyramid.gaussian.GaussianPyramid; 038import org.openimaj.image.feature.local.descriptor.gradient.SIFTFeatureProvider; 039import org.openimaj.image.feature.local.detector.dog.collector.Collector; 040import org.openimaj.image.feature.local.detector.dog.collector.OctaveKeypointCollector; 041import org.openimaj.image.feature.local.detector.dog.collector.OctaveMinMaxKeypointCollector; 042import org.openimaj.image.feature.local.detector.dog.extractor.DominantOrientationExtractor; 043import org.openimaj.image.feature.local.detector.dog.extractor.GradientFeatureExtractor; 044import org.openimaj.image.feature.local.detector.dog.extractor.OrientationHistogramExtractor; 045import org.openimaj.image.feature.local.detector.dog.pyramid.DoGOctaveExtremaFinder; 046import org.openimaj.image.feature.local.detector.pyramid.BasicOctaveExtremaFinder; 047import org.openimaj.image.feature.local.detector.pyramid.OctaveInterestPointFinder; 048import org.openimaj.image.feature.local.keypoints.MinMaxKeypoint; 049 050/** 051 * A modified implementation of Lowe's difference-of-Gaussian detector and SIFT 052 * feature extraction technique that also records whether features are detected 053 * at local minima or maxima by looking at the sign of the difference of 054 * Gaussian. This information can then be used for enhancing matching or 055 * clustering. 056 * <p> 057 * Internally, this class is identical to {@link DoGSIFTEngine}, but uses a 058 * {@link OctaveMinMaxKeypointCollector} instead of an 059 * {@link OctaveKeypointCollector}. 060 * 061 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 062 */ 063@Reference( 064 type = ReferenceType.Inproceedings, 065 author = { "Jonathon Hare", "Sina Samangooei", "Paul Lewis" }, 066 title = "Efficient clustering and quantisation of SIFT features: Exploiting characteristics of the SIFT descriptor and interest region detectors under image inversion", 067 year = "2011", 068 booktitle = "The ACM International Conference on Multimedia Retrieval (ICMR 2011)", 069 month = "April", 070 publisher = "ACM Press") 071public class MinMaxDoGSIFTEngine implements Engine<MinMaxKeypoint, FImage> { 072 DoGSIFTEngineOptions<FImage> options; 073 074 /** 075 * Construct a {@link MinMaxDoGSIFTEngine} with the default options. 076 */ 077 public MinMaxDoGSIFTEngine() { 078 this(new DoGSIFTEngineOptions<FImage>()); 079 } 080 081 /** 082 * Construct a {@link MinMaxDoGSIFTEngine} with the given options. 083 * 084 * @param options 085 * the options 086 */ 087 public MinMaxDoGSIFTEngine(DoGSIFTEngineOptions<FImage> options) { 088 this.options = options; 089 } 090 091 @Override 092 public LocalFeatureList<MinMaxKeypoint> findFeatures(FImage image) { 093 final OctaveInterestPointFinder<GaussianOctave<FImage>, FImage> finder = 094 new DoGOctaveExtremaFinder(new BasicOctaveExtremaFinder(options.magnitudeThreshold, 095 options.eigenvalueRatio)); 096 097 final Collector<GaussianOctave<FImage>, MinMaxKeypoint, FImage> collector = new OctaveMinMaxKeypointCollector( 098 new GradientFeatureExtractor( 099 new DominantOrientationExtractor(options.peakThreshold, 100 new OrientationHistogramExtractor(options.numOriHistBins, options.scaling, 101 options.smoothingIterations, options.samplingSize)), 102 new SIFTFeatureProvider(options.numOriBins, options.numSpatialBins, options.valueThreshold, 103 options.gaussianSigma), 104 options.magnificationFactor * options.numSpatialBins 105 )); 106 107 finder.setOctaveInterestPointListener(collector); 108 109 options.setOctaveProcessor(finder); 110 111 final GaussianPyramid<FImage> pyr = new GaussianPyramid<FImage>(options); 112 pyr.process(image); 113 114 return collector.getFeatures(); 115 } 116 117 /** 118 * Get the options for this engine. 119 * 120 * @return the options for this engine 121 */ 122 public DoGSIFTEngineOptions<FImage> getOptions() { 123 return options; 124 } 125}