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.algorithm.histogram;
31
32 import org.openimaj.image.FImage;
33 import org.openimaj.image.analyser.ImageAnalyser;
34 import org.openimaj.image.analysis.algorithm.histogram.binning.SpatialBinningStrategy;
35 import org.openimaj.image.processing.convolution.FImageGradients;
36
37 /**
38 * Implementation of the {@link WindowedHistogramExtractor} for efficiently
39 * extracting gradient orientation histograms. This implementation is built on
40 * top of a {@link SATWindowedExtractor}. The {@link #analyseImage(FImage)}
41 * method can be used to precompute the underlying data required for efficient
42 * histogram extraction using any of the <code>computeHistogram</code> methods.
43 * <p>
44 * Computed histograms are simply the sum of magnitudes for each orientation bin
45 * over the given window. If you need to generate more complex features (for
46 * example, aggregated spatially binned histograms) then use this class in
47 * combination with a {@link SpatialBinningStrategy}.
48 * <p>
49 * The {@link #analyseImage(FImage, FImage)} method can be used to construct
50 * histograms with moderated magnitudes (for example, suppressing all magnitudes
51 * except those at edges).
52 *
53 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
54 */
55 public class GradientOrientationHistogramExtractor
56 extends SATWindowedExtractor
57 implements ImageAnalyser<FImage>
58 {
59 private FImageGradients.Mode orientationMode;
60 private boolean histogramInterpolation;
61
62 /**
63 * Construct a new {@link GradientOrientationHistogramExtractor} with the
64 * given number of bins. Optionally perform linear interpolation across
65 * orientation bins. Histograms can also use either signed or unsigned
66 * gradients.
67 *
68 * @param nbins
69 * number of bins
70 * @param histogramInterpolation
71 * if true cyclic linear interpolation is used to share the
72 * magnitude across the two closest bins; if false only the
73 * closest bin will be filled.
74 * @param orientationMode
75 * the range of orientations to extract
76 */
77 public GradientOrientationHistogramExtractor(int nbins, boolean histogramInterpolation,
78 FImageGradients.Mode orientationMode)
79 {
80 super(nbins);
81
82 this.histogramInterpolation = histogramInterpolation;
83 this.orientationMode = orientationMode;
84 }
85
86 @Override
87 public void analyseImage(FImage image) {
88 final FImage[] magnitudes = new FImage[nbins];
89
90 for (int i = 0; i < nbins; i++)
91 magnitudes[i] = new FImage(image.width, image.height);
92
93 FImageGradients.gradientMagnitudesAndQuantisedOrientations(image, magnitudes, histogramInterpolation,
94 orientationMode);
95
96 computeSATs(magnitudes);
97 }
98
99 /**
100 * Analyse the given image, but construct the internal data such that the
101 * gradient magnitudes are multiplied by the given edge map before being
102 * accumulated. This could be used to suppress all magnitudes except those
103 * at edges; the resultant extracted histograms would only contain
104 * information about edge gradients.
105 *
106 * @param image
107 * the image to analyse
108 * @param edges
109 * the edge image
110 */
111 public void analyseImage(FImage image, FImage edges) {
112 final FImage[] magnitudes = new FImage[nbins];
113
114 for (int i = 0; i < nbins; i++)
115 magnitudes[i] = new FImage(image.width, image.height);
116
117 FImageGradients.gradientMagnitudesAndQuantisedOrientations(image, magnitudes, histogramInterpolation,
118 orientationMode);
119
120 for (int i = 0; i < nbins; i++)
121 magnitudes[i].multiplyInplace(edges);
122
123 computeSATs(magnitudes);
124 }
125 }