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;
31
32 import org.openimaj.image.FImage;
33 import org.openimaj.image.analyser.ImageAnalyser;
34 import org.openimaj.math.geometry.shape.Rectangle;
35
36 /**
37 * Implementation of an Integral Image or Summed Area Table. This Implementation
38 * calculates both the sum and squared sum values.
39 * <p>
40 * See http://en.wikipedia.org/wiki/Summed_area_table and
41 * http://research.microsoft
42 * .com/en-us/um/people/viola/Pubs/Detect/violaJones_IJCV.pdf
43 * <p>
44 * Basically, this provides an efficient way to find the sum of all pixels in a
45 * rectangular area of an image.
46 *
47 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
48 */
49 public class SummedSqAreaTable implements ImageAnalyser<FImage> {
50 /**
51 * The sum data
52 */
53 public FImage sum;
54
55 /**
56 * The squared sum data
57 */
58 public FImage sqSum;
59
60 /**
61 * Construct an empty SAT
62 */
63 public SummedSqAreaTable() {
64 }
65
66 /**
67 * Construct a SAT from the provided image
68 *
69 * @param image
70 * the image
71 */
72 public SummedSqAreaTable(FImage image) {
73 computeTable(image);
74 }
75
76 protected void computeTable(FImage image) {
77 sum = new FImage(image.getWidth() + 1, image.getHeight() + 1);
78 sqSum = new FImage(image.getWidth() + 1, image.getHeight() + 1);
79
80 for (int y = 0; y < image.height; y++) {
81 for (int x = 0; x < image.width; x++) {
82 final float p = image.pixels[y][x];
83
84 sum.pixels[y + 1][x + 1] = p +
85 sum.pixels[y + 1][x] +
86 sum.pixels[y][x + 1] -
87 sum.pixels[y][x];
88
89 sqSum.pixels[y + 1][x + 1] = p * p +
90 sqSum.pixels[y + 1][x] +
91 sqSum.pixels[y][x + 1] -
92 sqSum.pixels[y][x];
93 }
94 }
95 }
96
97 /**
98 * Calculate the sum of pixels in the image used for constructing this SAT
99 * within the rectangle defined by (x1,y1) [top-left coordinate] and (x2,y2)
100 * [bottom- right coordinate]
101 *
102 * @param x1
103 * x1
104 * @param y1
105 * y1
106 * @param x2
107 * x2
108 * @param y2
109 * y2
110 * @return sum of pixels in given rectangle
111 */
112 public float calculateSumArea(int x1, int y1, int x2, int y2) {
113 final float A = sum.pixels[y1][x1];
114 final float B = sum.pixels[y1][x2];
115 final float C = sum.pixels[y2][x2];
116 final float D = sum.pixels[y2][x1];
117
118 return A + C - B - D;
119 }
120
121 /**
122 * Calculate the sum of pixels in the image used for constructing this SAT
123 * within the given rectangle
124 *
125 * @param r
126 * rectangle
127 * @return sum of pixels in given rectangle
128 */
129 public float calculateSumArea(Rectangle r) {
130 return calculateSumArea(Math.round(r.x), Math.round(r.y), Math.round(r.x + r.width), Math.round(r.y + r.height));
131 }
132
133 /**
134 * Calculate the sum of squared pixels in the image used for constructing
135 * this SAT within the rectangle defined by (x1,y1) [top-left coordinate]
136 * and (x2,y2) [bottom- right coordinate]
137 *
138 * @param x1
139 * x1
140 * @param y1
141 * y1
142 * @param x2
143 * x2
144 * @param y2
145 * y2
146 * @return sum of pixels in given rectangle
147 */
148 public float calculateSqSumArea(int x1, int y1, int x2, int y2) {
149 final float A = sqSum.pixels[y1][x1];
150 final float B = sqSum.pixels[y1][x2];
151 final float C = sqSum.pixels[y2][x2];
152 final float D = sqSum.pixels[y2][x1];
153
154 return A + C - B - D;
155 }
156
157 /**
158 * Calculate the sum of squared pixels in the image used for constructing
159 * this SAT within the given rectangle
160 *
161 * @param r
162 * rectangle
163 * @return sum of pixels in given rectangle
164 */
165 public float calculateSqSumArea(Rectangle r) {
166 return calculateSqSumArea(Math.round(r.x), Math.round(r.y), Math.round(r.x + r.width), Math.round(r.y + r.height));
167 }
168
169 /*
170 * (non-Javadoc)
171 *
172 * @see
173 * org.openimaj.image.analyser.ImageAnalyser#analyseImage(org.openimaj.image
174 * .Image)
175 */
176 @Override
177 public void analyseImage(FImage image) {
178 computeTable(image);
179 }
180 }