1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.openimaj.image.feature.dense.gradient.binning;
31
32 import org.openimaj.image.analysis.algorithm.histogram.GradientOrientationHistogramExtractor;
33 import org.openimaj.image.analysis.algorithm.histogram.WindowedHistogramExtractor;
34 import org.openimaj.image.analysis.algorithm.histogram.binning.SpatialBinningStrategy;
35 import org.openimaj.image.feature.dense.gradient.binning.FixedHOGStrategy.BlockNormalisation;
36 import org.openimaj.math.geometry.shape.Rectangle;
37 import org.openimaj.math.statistics.distribution.Histogram;
38
39
40
41
42
43
44
45
46
47
48 public class FlexibleHOGStrategy implements SpatialBinningStrategy {
49 int numCellsX = 8;
50 int numCellsY = 16;
51 int cellsPerBlockX = 2;
52 int cellsPerBlockY = 2;
53 BlockNormalisation norm = BlockNormalisation.L2;
54
55 private int numBlocksX;
56 private int numBlocksY;
57 private int blockLength;
58 private int blockArea;
59 private int blockStepX;
60 private int blockStepY;
61
62 private transient Histogram[][] blocks;
63 private transient Histogram[][] cells;
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 public FlexibleHOGStrategy(int numCellsX, int numCellsY, int cellsPerBlock) {
79 this(numCellsX, numCellsY, cellsPerBlock, 1, BlockNormalisation.L2);
80 }
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 public FlexibleHOGStrategy(int numCellsX, int numCellsY, int cellsPerBlock, BlockNormalisation norm) {
97 this(numCellsX, numCellsY, cellsPerBlock, 1, norm);
98 }
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 public FlexibleHOGStrategy(int numCellsX, int numCellsY, int cellsPerBlock, int blockStep, BlockNormalisation norm) {
116 this(numCellsX, numCellsY, cellsPerBlock, cellsPerBlock, blockStep, blockStep, norm);
117 }
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 public FlexibleHOGStrategy(int numCellsX, int numCellsY, int cellsPerBlockX, int cellsPerBlockY,
142 int blockStepX, int blockStepY, BlockNormalisation norm)
143 {
144 super();
145 this.numCellsX = numCellsX;
146 this.numCellsY = numCellsY;
147 this.cellsPerBlockX = cellsPerBlockX;
148 this.cellsPerBlockY = cellsPerBlockY;
149 this.norm = norm;
150 this.blockStepX = blockStepX;
151 this.blockStepY = blockStepY;
152
153 numBlocksX = 1 + (numCellsX - cellsPerBlockX) / blockStepX;
154 numBlocksY = 1 + (numCellsY - cellsPerBlockY) / blockStepY;
155 }
156
157 @Override
158 public Histogram extract(WindowedHistogramExtractor binnedData, Rectangle region, Histogram output) {
159 if (cells == null || cells[0][0].values.length != binnedData.getNumBins()) {
160 cells = new Histogram[numCellsY][numCellsX];
161 blocks = new Histogram[numBlocksY][numBlocksX];
162
163 for (int j = 0; j < numCellsY; j++)
164 for (int i = 0; i < numCellsX; i++)
165 cells[j][i] = new Histogram(binnedData.getNumBins());
166
167 for (int j = 0; j < numBlocksY; j++)
168 for (int i = 0; i < numBlocksX; i++)
169 blocks[j][i] = new Histogram(binnedData.getNumBins() * cellsPerBlockX * cellsPerBlockY);
170
171 blockLength = blocks[0][0].values.length;
172 blockArea = cellsPerBlockX * cellsPerBlockY;
173 }
174
175 computeCells(binnedData, region);
176 computeBlocks(cells);
177
178 if (output == null || output.values.length != blocks[0].length * blocks.length * blockLength)
179 output = new Histogram(blocks[0].length * blocks.length * blockLength);
180
181 for (int j = 0, k = 0; j < blocks.length; j++) {
182 for (int i = 0; i < blocks[0].length; i++, k++) {
183 norm.normalise(blocks[j][i], blockArea);
184
185 System.arraycopy(blocks[j][i].values, 0, output.values, k * blockLength, blockLength);
186 }
187 }
188
189 return output;
190 }
191
192 private void computeBlocks(Histogram[][] cells) {
193 for (int y = 0; y < numBlocksY; y++) {
194 for (int x = 0; x < numBlocksX; x++) {
195 final double[] blockData = blocks[y][x].values;
196
197 for (int j = 0, k = 0; j < cellsPerBlockY; j++) {
198 for (int i = 0; i < cellsPerBlockX; i++) {
199 final double[] cellData = cells[y * blockStepY + j][x * blockStepX + i].values;
200
201 System.arraycopy(cellData, 0, blockData, k, cellData.length);
202
203 k += cellData.length;
204 }
205 }
206 }
207 }
208 }
209
210 private void computeCells(WindowedHistogramExtractor binnedData, Rectangle region) {
211 final int cellWidth = (int) (region.width / numCellsX);
212 final int cellHeight = (int) (region.height / numCellsY);
213
214 for (int j = 0, y = (int) region.y; j < numCellsY; j++, y += cellHeight) {
215 for (int i = 0, x = (int) region.x; i < numCellsX; i++, x += cellWidth) {
216 binnedData.computeHistogram(x, y, cellWidth, cellHeight, cells[j][i]);
217 cells[j][i].normaliseL2();
218 }
219 }
220 }
221 }