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 gnu.trove.list.array.TFloatArrayList;
33 import gnu.trove.map.hash.TIntIntHashMap;
34 import gnu.trove.procedure.TIntIntProcedure;
35
36 import org.openimaj.image.FImage;
37 import org.openimaj.image.MBFImage;
38
39 import static java.lang.Math.sqrt;
40
41
42
43
44
45
46
47 public class BasicDescriptiveStatisticsModel extends AbstractPixelStatisticsModel {
48 private static final long serialVersionUID = 1L;
49
50
51
52
53 public double [] mean;
54
55
56
57
58 public double [] mode;
59
60
61
62
63 public double [] median;
64
65
66
67
68 public double [] range;
69
70
71
72
73 public double [] variance;
74
75
76
77
78
79
80
81
82
83 public BasicDescriptiveStatisticsModel(int ndims) {
84 super(ndims);
85
86 mean = new double[ndims];
87 mode = new double[ndims];
88 median = new double[ndims];
89 range = new double[ndims];
90 variance = new double[ndims];
91 }
92
93 @Override
94 public void estimateModel(MBFImage... images) {
95 for (int i=0; i<ndims; i++) {
96 mean[i] = 0;
97 TFloatArrayList values = new TFloatArrayList();
98 TIntIntHashMap freqs = new TIntIntHashMap();
99
100 int count = 0;
101 for (MBFImage im : images) {
102 FImage band = im.getBand(i);
103
104 for (int r=0; r<band.height; r++) {
105 for (int c=0; c<band.width; c++) {
106 float val = band.pixels[r][c];
107 mean[i] += val;
108 values.add(val);
109 freqs.adjustOrPutValue(Math.round(val*255F), 1, 1);
110 count++;
111 }
112 }
113 }
114
115
116 mean[i] /= count;
117
118
119 values.sort();
120 int idx = values.size() / 2;
121 if (values.size() % 2 == 0) {
122 median[i] = (values.get(idx) + values.get(idx - 1)) / 2.0;
123 } else {
124 median[i] = values.get(idx);
125 }
126
127
128 HashMax hm = new HashMax();
129 freqs.forEachEntry(hm);
130 mode[i] = hm.idx / 255.0;
131
132
133 range[i] = values.get(values.size() - 1) - values.get(0);
134
135
136 variance[i] = 0;
137 for (int j=0; j<values.size(); j++) {
138 variance[i] += (values.get(j) - mean[i]) * (values.get(j) - mean[i]);
139 }
140 variance[i] = sqrt(variance[i] / values.size());
141 }
142 }
143
144 @Override
145 public String toString() {
146 String desc = "";
147 for (int i=0; i<ndims; i++) desc += String.format("%2.2f, ", mean[i]);
148 for (int i=0; i<ndims; i++) desc += String.format("%2.2f, ", mode[i]);
149 for (int i=0; i<ndims; i++) desc += String.format("%2.2f, ", median[i]);
150 for (int i=0; i<ndims; i++) desc += String.format("%2.2f, ", range[i]);
151 for (int i=0; i<ndims; i++) desc += String.format("%2.2f, ", variance[i]);
152 return desc.substring(0, desc.length()-2);
153 }
154 }
155
156 class HashMax implements TIntIntProcedure {
157 public int max = 0;
158 public int idx = -1;
159
160 @Override
161 public boolean execute(int key, int value) {
162 if (value > max) {
163 max = value;
164 idx = key;
165 }
166 return true;
167 }
168 }