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.dense.gradient.dsift;
031
032import org.openimaj.feature.local.list.LocalFeatureList;
033import org.openimaj.image.Image;
034import org.openimaj.image.analyser.ImageAnalyser;
035import org.openimaj.math.geometry.shape.Rectangle;
036
037/**
038 * Base class for implementations of a dense SIFT feature extractors.
039 * 
040 * @see "http://www.vlfeat.org/api/dsift.html#dsift-usage"
041 * 
042 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
043 * 
044 * @param <IMAGE>
045 *            Type of image being processed
046 */
047public abstract class AbstractDenseSIFT<IMAGE extends Image<?, IMAGE>> implements ImageAnalyser<IMAGE>, Cloneable {
048
049        /**
050         * Compute the dense sift descriptors inside the bounds rectangle of the
051         * given image.
052         * 
053         * @param image
054         *            the image
055         * @param bounds
056         *            the bounds rectangle
057         */
058        public abstract void analyseImage(IMAGE image, Rectangle bounds);
059
060        /**
061         * Compute the dense sift descriptors of the given image. The entire image
062         * will be sampled.
063         * 
064         * @param image
065         *            the image
066         */
067        @Override
068        public final void analyseImage(IMAGE image) {
069                analyseImage(image, image.getBounds());
070        }
071
072        /**
073         * Get the SIFT descriptors from the previous call to
074         * {@link #analyseImage(Image)} or {@link #analyseImage(Image, Rectangle)}
075         * in the form of a list of local features with float vectors.
076         * 
077         * @return a list of {@link FloatDSIFTKeypoint}s.
078         */
079        public abstract LocalFeatureList<FloatDSIFTKeypoint> getFloatKeypoints();
080
081        /**
082         * Get the SIFT descriptors from the previous call to
083         * {@link #analyseImage(Image)} or {@link #analyseImage(Image, Rectangle)}
084         * in the form of a list of local features with byte vectors.
085         * 
086         * @return a list of {@link ByteDSIFTKeypoint}s.
087         */
088        public abstract LocalFeatureList<ByteDSIFTKeypoint> getByteKeypoints();
089
090        /**
091         * Get the SIFT descriptors from the previous call to
092         * {@link #analyseImage(Image)} or {@link #analyseImage(Image, Rectangle)}
093         * in the form of a list of local features with float vectors. Only the
094         * features with an energy above the given threshold will be returned.
095         * 
096         * @param energyThreshold
097         *            the threshold on the feature energy
098         * 
099         * @return a list of {@link FloatDSIFTKeypoint}s.
100         */
101        public abstract LocalFeatureList<FloatDSIFTKeypoint> getFloatKeypoints(float energyThreshold);
102
103        /**
104         * Get the SIFT descriptors from the previous call to
105         * {@link #analyseImage(Image)} or {@link #analyseImage(Image, Rectangle)}
106         * in the form of a list of local features with byte vectors. Only the
107         * features with an energy above the given threshold will be returned.
108         * 
109         * @param energyThreshold
110         *            the threshold on the feature energy
111         * 
112         * @return a list of {@link ByteDSIFTKeypoint}s.
113         */
114        public abstract LocalFeatureList<ByteDSIFTKeypoint> getByteKeypoints(float energyThreshold);
115
116        @SuppressWarnings("unchecked")
117        @Override
118        public AbstractDenseSIFT<IMAGE> clone() {
119                try {
120                        return (AbstractDenseSIFT<IMAGE>) super.clone();
121                } catch (final CloneNotSupportedException e) {
122                        throw new AssertionError(e);
123                }
124        }
125
126        /**
127         * (Optional operation) Set the width of a single bin of the sampling window
128         * (in pixels). Sampling window width is this multiplied by
129         * {@link #getNumBinsX()}.
130         * 
131         * @param size
132         *            size to set
133         */
134        public abstract void setBinWidth(int size);
135
136        /**
137         * (Optional operation) Set the height of a single bin of the sampling
138         * window (in pixels). Sampling window height is this multiplied by
139         * {@link #getNumBinsY()}.
140         * 
141         * @param size
142         *            size to set
143         */
144        public abstract void setBinHeight(int size);
145
146        /**
147         * (Optional operation) Get the width of a single bin of the sampling window
148         * (in pixels). Sampling window width is this multiplied by
149         * {@link #getNumBinsX()}.
150         * 
151         * @return the bin width
152         */
153        public abstract int getBinWidth();
154
155        /**
156         * (Optional operation) Get the height of a single bin of the sampling
157         * window (in pixels). Sampling window height is this multiplied by
158         * {@link #getNumBinsY()}.
159         * 
160         * @return the bin height
161         */
162        public abstract int getBinHeight();
163
164        /**
165         * Get the number of spatial bins in the X direction
166         * 
167         * @return the number of bins in the x direction
168         */
169        public abstract int getNumBinsX();
170
171        /**
172         * Get the number of spatial bins in the Y direction
173         * 
174         * @return the number of bins in the y direction
175         */
176        public abstract int getNumBinsY();
177
178        /**
179         * Get the number of orientation bins
180         * 
181         * @return the number of orientation bins
182         */
183        public abstract int getNumOriBins();
184
185        /**
186         * Get the computed raw dense SIFT descriptors from the previous call to
187         * {@link #analyseImage(Image)} or {@link #analyseImage(Image, Rectangle)} .
188         * 
189         * @return the descriptors.
190         */
191        public abstract float[][] getDescriptors();
192}