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.pixel.statistics;
31
32 import org.openimaj.feature.FeatureVectorProvider;
33 import org.openimaj.image.MBFImage;
34 import org.openimaj.math.statistics.distribution.MultidimensionalHistogram;
35
36
37
38
39
40
41
42
43
44 public class BlockHistogramModel extends AbstractPixelStatisticsModel implements FeatureVectorProvider<MultidimensionalHistogram> {
45 private static final long serialVersionUID = 1L;
46
47
48
49
50 public MultidimensionalHistogram [][] histograms;
51
52 int blocks_x;
53 int blocks_y;
54 int [] dims;
55
56
57
58
59
60
61
62 public BlockHistogramModel(int blocks_x, int blocks_y, int... nbins) {
63 super(nbins.length);
64 this.dims = nbins;
65 this.blocks_x = blocks_x;
66 this.blocks_y = blocks_y;
67 this.histograms = new MultidimensionalHistogram[blocks_y][blocks_x];
68
69 for (int y=0; y<blocks_y; y++)
70 for (int x=0; x<blocks_x; x++)
71 histograms[y][x] = new MultidimensionalHistogram(dims);
72 }
73
74
75
76
77
78 public MultidimensionalHistogram toSingleHistogram() {
79 int [] newdims = new int[dims.length + 2];
80
81 for (int i=0; i<dims.length; i++)
82 newdims[i] = dims[i];
83 newdims[dims.length] = blocks_x;
84 newdims[dims.length+1] = blocks_y;
85
86 MultidimensionalHistogram h = new MultidimensionalHistogram(newdims);
87
88 for (int y=0; y<blocks_y; y++) {
89 for (int x=0; x<blocks_x; x++) {
90 int blkid = x + y*blocks_x;
91 for (int i=0; i<histograms[y][x].values.length; i++) {
92 h.values[i + blkid*histograms[y][x].values.length] = histograms[y][x].values[i];
93 }
94 }
95 }
96
97 return h;
98 }
99
100 protected void reset(MultidimensionalHistogram histogram) {
101 for (int i=0; i<histogram.values.length; i++)
102 histogram.values[i] = 0;
103 }
104
105 @Override
106 public void estimateModel(MBFImage... images) {
107
108 for (int y=0; y<blocks_y; y++)
109 for (int x=0; x<blocks_x; x++)
110 reset(histograms[y][x]);
111
112
113 for (MBFImage img : images) {
114 for (int y=0; y<blocks_y; y++) {
115 for (int x=0; x<blocks_x; x++) {
116 accum(img, x, y);
117 }
118 }
119 }
120
121
122 for (int y=0; y<blocks_y; y++)
123 for (int x=0; x<blocks_x; x++)
124 histograms[y][x].normalise();
125 }
126
127 protected void accum(MBFImage im, int bx, int by) {
128 assert (im.numBands() == ndims);
129
130 MultidimensionalHistogram histogram = histograms[by][bx];
131 int height = im.getHeight();
132 int width = im.getWidth();
133
134 int cols_per_block = width / blocks_x;
135 int startx = bx*cols_per_block;
136 int stopx = (1+bx)*cols_per_block;
137
138 int rows_per_block = height / blocks_y;
139 int starty = by*rows_per_block;
140 int stopy = (1+by)*rows_per_block;
141
142 if (stopx >= width) stopx = width;
143 if (stopy >= height) stopy = height;
144
145 for (int y=starty; y<stopy; y++) {
146 for (int x=startx; x<stopx; x++) {
147 int [] bins = new int[ndims];
148
149 for (int i=0; i<ndims; i++) {
150 bins[i] = (int)(im.getBand(i).pixels[y][x] * (histogram.nbins[i]));
151 if (bins[i] >= histogram.nbins[i]) bins[i] = histogram.nbins[i] - 1;
152 }
153
154 int bin = 0;
155 for (int i=0; i<ndims; i++) {
156 int f = 1;
157 for (int j=0; j<i; j++)
158 f *= histogram.nbins[j];
159
160 bin += f * bins[i];
161 }
162
163 histogram.values[bin]++;
164 }
165 }
166 }
167
168 @Override
169 public String toString() {
170 String s = "LocalHistogram[\n";
171
172 for (int y=0; y<blocks_y; y++)
173 for (int x=0; x<blocks_x; x++)
174 s += "\t(" + x + ", " + y + ") = " + histograms[y][x].toString() + "\n";
175
176 s += "]\n";
177 return s;
178 }
179
180 @Override
181 public BlockHistogramModel clone() {
182 BlockHistogramModel model = new BlockHistogramModel(blocks_x, blocks_x, dims);
183 model.histograms = new MultidimensionalHistogram[blocks_y][blocks_x];
184
185 for (int y=0; y<blocks_y; y++)
186 for (int x=0; x<blocks_x; x++)
187 model.histograms[y][x] = histograms[y][x].clone();
188
189 return model;
190 }
191
192 @Override
193 public MultidimensionalHistogram getFeatureVector() {
194 return toSingleHistogram();
195 }
196 }