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}