View Javadoc

1   /**
2    * Copyright (c) 2011, The University of Southampton and the individual contributors.
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without modification,
6    * are permitted provided that the following conditions are met:
7    *
8    *   * 	Redistributions of source code must retain the above copyright notice,
9    * 	this list of conditions and the following disclaimer.
10   *
11   *   *	Redistributions in binary form must reproduce the above copyright notice,
12   * 	this list of conditions and the following disclaimer in the documentation
13   * 	and/or other materials provided with the distribution.
14   *
15   *   *	Neither the name of the University of Southampton nor the names of its
16   * 	contributors may be used to endorse or promote products derived from this
17   * 	software without specific prior written permission.
18   *
19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package org.openimaj.image.analysis.pyramid.gaussian;
31  
32  import org.openimaj.image.FImage;
33  import org.openimaj.image.Image;
34  import org.openimaj.image.analysis.pyramid.PyramidOptions;
35  import org.openimaj.image.processing.convolution.FGaussianConvolve;
36  import org.openimaj.image.processor.SinglebandImageProcessor;
37  
38  /**
39   * Options for constructing a Gaussian pyramid in the style of Lowe's SIFT
40   * paper.
41   * 
42   * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
43   * 
44   * @param <IMAGE>
45   *            type of underlying image.
46   */
47  public class GaussianPyramidOptions<IMAGE extends Image<?, IMAGE> & SinglebandImageProcessor.Processable<Float, FImage, IMAGE>>
48  		extends
49  		PyramidOptions<GaussianOctave<IMAGE>, IMAGE>
50  {
51  	/**
52  	 * Number of pixels of border for processors to ignore. Also used in
53  	 * calculating the minimum image size for the last octave.
54  	 */
55  	protected int borderPixels = 5;
56  
57  	/**
58  	 * Should the starting image of the pyramid be stretched to twice its size?
59  	 */
60  	protected boolean doubleInitialImage = true;
61  
62  	/**
63  	 * The number of extra scale steps taken beyond scales.
64  	 */
65  	protected int extraScaleSteps = 2; // number of extra steps to take beyond
66  										// doubling sigma
67  
68  	/**
69  	 * Assumed initial scale of the first image in each octave. For SIFT, Lowe
70  	 * suggested 1.6 (for optimal repeatability; see Lowe's IJCV paper, P.10).
71  	 */
72  	protected float initialSigma = 1.6f;
73  
74  	/**
75  	 * The number of scales in this octave minus extraScaleSteps. Levels are
76  	 * constructed so that level[scales] has twice the sigma of level[0].
77  	 */
78  	protected int scales = 3;
79  
80  	/**
81  	 * Default constructor.
82  	 */
83  	public GaussianPyramidOptions() {
84  
85  	}
86  
87  	/**
88  	 * Construct the pyramid options by copying the non-processor options from
89  	 * the given options object.
90  	 * 
91  	 * @param options
92  	 *            options to copy from
93  	 */
94  	public GaussianPyramidOptions(GaussianPyramidOptions<?> options) {
95  		this.borderPixels = options.borderPixels;
96  		this.doubleInitialImage = options.doubleInitialImage;
97  		this.extraScaleSteps = options.extraScaleSteps;
98  		this.initialSigma = options.initialSigma;
99  		this.keepOctaves = options.keepOctaves;
100 		this.scales = options.scales;
101 	}
102 
103 	/**
104 	 * Get the number of pixels used for a border that processors shouldn't
105 	 * touch.
106 	 * 
107 	 * @return number of border pixels.
108 	 */
109 	public int getBorderPixels() {
110 		return borderPixels;
111 	}
112 
113 	/**
114 	 * Get the number of extra scale steps taken beyond scales.
115 	 * 
116 	 * @see #getScales()
117 	 * 
118 	 * @return the extraScaleSteps
119 	 */
120 	public int getExtraScaleSteps() {
121 		return extraScaleSteps;
122 	}
123 
124 	/**
125 	 * Get the assumed initial scale of the first image in each octave.
126 	 * 
127 	 * @return the initialSigma
128 	 */
129 	public float getInitialSigma() {
130 		return initialSigma;
131 	}
132 
133 	/**
134 	 * Get the number of scales in this octave minus extraScaleSteps. Levels of
135 	 * each octave are constructed so that level[scales] has twice the sigma of
136 	 * level[0].
137 	 * 
138 	 * @return the scales
139 	 */
140 	public int getScales() {
141 		return scales;
142 	}
143 
144 	/**
145 	 * Should the starting image of the pyramid be stretched to twice its size?
146 	 * 
147 	 * @return the doubleInitialImage
148 	 */
149 	public boolean isDoubleInitialImage() {
150 		return doubleInitialImage;
151 	}
152 
153 	/**
154 	 * Set the number of pixels used for a border that processors shouldn't
155 	 * touch. Also affects the minimum image size for the last octave, which
156 	 * must be at least 2 + 2*borderPixels.
157 	 * 
158 	 * @param borderPixels
159 	 *            number of pixels to leave as border
160 	 */
161 	public void setBorderPixels(int borderPixels) {
162 		if (borderPixels < 2)
163 			throw new IllegalArgumentException("BorderDistance must be >= 2");
164 		this.borderPixels = borderPixels;
165 	}
166 
167 	/**
168 	 * Set whether starting image of the pyramid be stretched to twice its size?
169 	 * 
170 	 * @param doubleInitialImage
171 	 *            the doubleInitialImage to set
172 	 */
173 	public void setDoubleInitialImage(boolean doubleInitialImage) {
174 		this.doubleInitialImage = doubleInitialImage;
175 	}
176 
177 	/**
178 	 * Set the number of extra scale steps taken beyond scales.
179 	 * 
180 	 * @see #setScales(int)
181 	 * 
182 	 * @param extraScaleSteps
183 	 *            the extraScaleSteps to set
184 	 */
185 	public void setExtraScaleSteps(int extraScaleSteps) {
186 		this.extraScaleSteps = extraScaleSteps;
187 	}
188 
189 	/**
190 	 * Set the assumed initial scale of the first image in each octave. For
191 	 * SIFT, Lowe suggested 1.6 (for optimal repeatability; see Lowe's IJCV
192 	 * paper, P.10).
193 	 * 
194 	 * @param initialSigma
195 	 *            the initialSigma to set
196 	 */
197 	public void setInitialSigma(float initialSigma) {
198 		this.initialSigma = initialSigma;
199 	}
200 
201 	/**
202 	 * Set the number of scales in this octave minus extraScaleSteps. Levels of
203 	 * each octave are constructed so that level[scales] has twice the sigma of
204 	 * level[0].
205 	 * 
206 	 * @param scales
207 	 *            the scales to set
208 	 */
209 	public void setScales(int scales) {
210 		this.scales = scales;
211 	}
212 
213 	/**
214 	 * Create a {@link SinglebandImageProcessor} that performs a Gaussian
215 	 * blurring with a standard deviation given by sigma. This method is used by
216 	 * the {@link GaussianOctave} and {@link GaussianPyramid} to create filters
217 	 * for performing the blurring. By overriding in subclasses, you can control
218 	 * the exact filter implementation (i.e. for speed).
219 	 * 
220 	 * @param sigma
221 	 *            the gaussian standard deviation
222 	 * @return the image processor to apply the blur
223 	 */
224 	public SinglebandImageProcessor<Float, FImage> createGaussianBlur(float sigma) {
225 		return new FGaussianConvolve(sigma);
226 	}
227 }