GteHistogram.cpp
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #include <GTEnginePCH.h>
9 #include <Imagics/GteHistogram.h>
10 #include <Imagics/GteImage2.h>
11 #include <algorithm>
12 using namespace gte;
13 
14 Histogram::Histogram(int numBuckets, int numSamples, int const* samples, bool noRescaling)
15  :
16  mBuckets(numBuckets),
17  mExcessLess(0),
18  mExcessGreater(0)
19 {
20  if (numBuckets <= 0 || numSamples <= 0 || !samples)
21  {
22  LogError("Invalid inputs.");
23  return;
24  }
25 
26  std::fill(mBuckets.begin(), mBuckets.end(), 0);
27 
28  int i, value;
29 
30  if (noRescaling)
31  {
32  // Map to the buckets, also counting out-of-range pixels.
33  for (i = 0; i < numSamples; ++i)
34  {
35  value = samples[i];
36  if (0 <= value)
37  {
38  if (value < numBuckets)
39  {
40  ++mBuckets[value];
41  }
42  else
43  {
45  }
46  }
47  else
48  {
49  ++mExcessLess;
50  }
51  }
52  }
53  else
54  {
55  // Compute the extremes.
56  int minValue = samples[0], maxValue = minValue;
57  for (i = 1; i < numSamples; ++i)
58  {
59  value = samples[i];
60  if (value < minValue)
61  {
62  minValue = value;
63  }
64  else if (value > maxValue)
65  {
66  maxValue = value;
67  }
68  }
69 
70  // Map to the buckets.
71  if (minValue < maxValue)
72  {
73  // The image is not constant.
74  double numer = static_cast<double>(numBuckets - 1);
75  double denom = static_cast<double>(maxValue - minValue);
76  double mult = numer / denom;
77  for (i = 0; i < numSamples; ++i)
78  {
79  int index = static_cast<int>(mult * static_cast<double>(samples[i] - minValue));
80  ++mBuckets[index];
81  }
82  }
83  else
84  {
85  // The image is constant.
86  mBuckets[0] = numSamples;
87  }
88  }
89 }
90 
91 Histogram::Histogram(int numBuckets, int numSamples, float const* samples)
92  :
93  mBuckets(numBuckets),
94  mExcessLess(0),
96 {
97  if (numBuckets <= 0 || numSamples <= 0 || !samples)
98  {
99  LogError("Invalid inputs.");
100  return;
101  }
102 
103  std::fill(mBuckets.begin(), mBuckets.end(), 0);
104 
105  // Compute the extremes.
106  float minValue = samples[0], maxValue = minValue;
107  for (int i = 1; i < numSamples; ++i)
108  {
109  float value = samples[i];
110  if (value < minValue)
111  {
112  minValue = value;
113  }
114  else if (value > maxValue)
115  {
116  maxValue = value;
117  }
118  }
119 
120  // Map to the buckets.
121  if (minValue < maxValue)
122  {
123  // The image is not constant.
124  double numer = static_cast<double>(numBuckets - 1);
125  double denom = static_cast<double>(maxValue - minValue);
126  double mult = numer / denom;
127  for (int i = 0; i < numSamples; ++i)
128  {
129  int index = static_cast<int>(mult * static_cast<double>(samples[i] - minValue));
130  ++mBuckets[index];
131  }
132  }
133  else
134  {
135  // The image is constant.
136  mBuckets[0] = numSamples;
137  }
138 }
139 
140 Histogram::Histogram(int numBuckets, int numSamples, double const* samples)
141  :
142  mBuckets(numBuckets),
143  mExcessLess(0),
144  mExcessGreater(0)
145 {
146  if (numBuckets <= 0 || numSamples <= 0 || !samples)
147  {
148  LogError("Invalid inputs.");
149  return;
150  }
151 
152  std::fill(mBuckets.begin(), mBuckets.end(), 0);
153 
154  // Compute the extremes.
155  double minValue = samples[0], maxValue = minValue;
156  for (int i = 1; i < numSamples; ++i)
157  {
158  double value = samples[i];
159  if (value < minValue)
160  {
161  minValue = value;
162  }
163  else if (value > maxValue)
164  {
165  maxValue = value;
166  }
167  }
168 
169  // Map to the buckets.
170  if (minValue < maxValue)
171  {
172  // The image is not constant.
173  double numer = static_cast<double>(numBuckets - 1);
174  double denom = maxValue - minValue;
175  double mult = numer/denom;
176  for (int i = 0; i < numSamples; ++i)
177  {
178  int index = static_cast<int>(mult * (samples[i] - minValue));
179  ++mBuckets[index];
180  }
181  }
182  else
183  {
184  // The image is constant.
185  mBuckets[0] = numSamples;
186  }
187 }
188 
189 Histogram::Histogram(int numBuckets)
190  :
191  mBuckets(numBuckets),
192  mExcessLess(0),
193  mExcessGreater(0)
194 {
195  if (numBuckets <= 0)
196  {
197  LogError("Invalid inputs.");
198  return;
199  }
200 
201  std::fill(mBuckets.begin(), mBuckets.end(), 0);
202 }
203 
205 {
206  if (0 <= value)
207  {
208  if (value < static_cast<int>(mBuckets.size()))
209  {
210  ++mBuckets[value];
211  }
212  else
213  {
214  ++mExcessGreater;
215  }
216  }
217  else
218  {
219  ++mExcessLess;
220  }
221 }
222 
223 int Histogram::GetLowerTail(double tailAmount)
224 {
225  int const numBuckets = static_cast<int>(mBuckets.size());
226  int hSum = 0;
227  for (int i = 0; i < numBuckets; ++i)
228  {
229  hSum += mBuckets[i];
230  }
231 
232  int hTailSum = static_cast<int>(tailAmount * hSum);
233  int hLowerSum = 0;
234  int lower;
235  for (lower = 0; lower < numBuckets; ++lower)
236  {
237  hLowerSum += mBuckets[lower];
238  if (hLowerSum >= hTailSum)
239  {
240  break;
241  }
242  }
243  return lower;
244 }
245 
246 int Histogram::GetUpperTail(double tailAmount)
247 {
248  int const numBuckets = static_cast<int>(mBuckets.size());
249  int hSum = 0;
250  for (int i = 0; i < numBuckets; ++i)
251  {
252  hSum += mBuckets[i];
253  }
254 
255  int hTailSum = static_cast<int>(tailAmount * hSum);
256  int hUpperSum = 0;
257  int upper;
258  for (upper = numBuckets - 1; upper >= 0; --upper)
259  {
260  hUpperSum += mBuckets[upper];
261  if (hUpperSum >= hTailSum)
262  {
263  break;
264  }
265  }
266  return upper;
267 }
268 
269 void Histogram::GetTails(double tailAmount, int& lower, int& upper)
270 {
271  int const numBuckets = static_cast<int>(mBuckets.size());
272  int hSum = 0;
273  for (int i = 0; i < numBuckets; ++i)
274  {
275  hSum += mBuckets[i];
276  }
277 
278  int hTailSum = static_cast<int>(0.5 * tailAmount * hSum);
279  int hLowerSum = 0;
280  for (lower = 0; lower < numBuckets; ++lower)
281  {
282  hLowerSum += mBuckets[lower];
283  if (hLowerSum >= hTailSum)
284  {
285  break;
286  }
287  }
288 
289  int hUpperSum = 0;
290  for (upper = numBuckets - 1; upper >= 0; --upper)
291  {
292  hUpperSum += mBuckets[upper];
293  if (hUpperSum >= hTailSum)
294  {
295  break;
296  }
297  }
298 }
GLsizei const GLfloat * value
Definition: glcorearb.h:819
GLsizei samples
Definition: glcorearb.h:1293
int GetUpperTail(double tailAmount)
int GetLowerTail(double tailAmount)
#define LogError(message)
Definition: GteLogger.h:92
void InsertCheck(int value)
GLuint index
Definition: glcorearb.h:781
void GetTails(double tailAmount, int &lower, int &upper)
Histogram(int numBuckets, int numSamples, int const *samples, bool noRescaling)
std::vector< int > mBuckets
Definition: GteHistogram.h:67


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:00