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 import org.openimaj.util.pair.Pair;
36
37
38
39
40
41
42
43
44 public class HistogramModel extends AbstractPixelStatisticsModel
45 implements
46 FeatureVectorProvider<MultidimensionalHistogram>
47 {
48 private static final long serialVersionUID = 1L;
49
50
51
52
53 public MultidimensionalHistogram histogram;
54
55
56
57
58
59
60
61 public HistogramModel(int... nbins) {
62 super(nbins.length);
63
64 assert (nbins.length > 0);
65
66 histogram = new MultidimensionalHistogram(nbins);
67 }
68
69 @Override
70 public void estimateModel(MBFImage... images) {
71 reset();
72 for (final MBFImage im : images) {
73 accum(im);
74 }
75 histogram.normalise();
76 }
77
78 protected void reset() {
79 for (int i = 0; i < histogram.values.length; i++)
80 histogram.values[i] = 0;
81 }
82
83
84
85
86
87
88
89 public Pair<float[]> colourRange(int index) {
90 final int[] coord = this.histogram.getCoordinates(index);
91 final float[] start = new float[coord.length];
92 final float[] end = new float[coord.length];
93 final int[] nbins = histogram.nbins;
94 for (int i = 0; i < coord.length; i++) {
95 start[i] = (float) coord[i] / (float) nbins[i];
96 end[i] = ((float) coord[i] + 1) / nbins[i];
97 }
98 return new Pair<float[]>(start, end);
99 }
100
101
102
103
104
105
106
107 public float[] colourAverage(int index) {
108 final int[] coord = this.histogram.getCoordinates(index);
109 final float[] average = new float[coord.length];
110 final int[] nbins = histogram.nbins;
111 for (int i = 0; i < coord.length; i++) {
112 final float start = (float) coord[i] / (float) nbins[i];
113 final float end = ((float) coord[i] + 1) / nbins[i];
114 average[i] = (start + end) / 2f;
115 }
116
117 return average;
118 }
119
120 protected void accum(MBFImage im) {
121 final int height = im.getHeight();
122 final int width = im.getWidth();
123 final int[] bins = new int[ndims];
124
125 final float[][][] bands = new float[im.numBands()][][];
126 for (int i = 0; i < bands.length; i++)
127 bands[i] = im.getBand(i).pixels;
128
129 final int[] nbins = histogram.nbins;
130 final double[] values = histogram.values;
131
132 for (int y = 0; y < height; y++) {
133 for (int x = 0; x < width; x++) {
134 for (int i = 0; i < ndims; i++) {
135 bins[i] = (int) (bands[i][y][x] * (nbins[i]));
136 if (bins[i] >= nbins[i])
137 bins[i] = nbins[i] - 1;
138 }
139
140 int bin = 0;
141 for (int i = 0; i < ndims; i++) {
142 int f = 1;
143 for (int j = 0; j < i; j++)
144 f *= nbins[j];
145
146 bin += f * bins[i];
147 }
148
149 values[bin]++;
150 }
151 }
152 }
153
154 @Override
155 public String toString() {
156 return histogram.toString();
157 }
158
159 @Override
160 public HistogramModel clone() {
161 final HistogramModel model = new HistogramModel();
162 model.histogram = histogram.clone();
163 model.ndims = ndims;
164 return model;
165 }
166
167 @Override
168 public MultidimensionalHistogram getFeatureVector() {
169 return histogram;
170 }
171 }