Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
ImageHistogram.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "ImageHistogram.h"
8
9#include "Brick.h"
10#include "ControlNet.h"
11#include "ControlMeasure.h"
12
13#include <iostream>
14#include <math.h>
15#include <stdio.h>
16#include <string>
17
18using namespace std;
19
20namespace Isis {
21
30 ImageHistogram::ImageHistogram(double minimum, double maximum, int nbins) :
31 Histogram(minimum, maximum, nbins) {
32 }
33
34
56 ImageHistogram::ImageHistogram(Cube &cube, int statsBand, Progress *progress,
57 double startSample, double startLine,
58 double endSample, double endLine,
59 int bins, bool addCubeData) {
60 InitializeFromCube(cube, statsBand, progress, bins, startSample, startLine,
61 endSample, endLine);
62
63 if (addCubeData) {
64 Brick cubeDataBrick((int)(endSample - startSample + 1),
65 1, 1, cube.pixelType());
66
67 // if band == 0, then we're gathering data for all bands.
68 int startBand = statsBand;
69 int endBand = statsBand;
70
71 if (statsBand == 0) {
72 startBand = 1;
73 endBand = cube.bandCount();
74 }
75
76 if (progress != NULL) {
77 progress->SetText("Gathering histogram");
78 progress->SetMaximumSteps(
79 (int)(endLine - startLine + 1) * (int)(endBand - startBand + 1));
80 progress->CheckStatus();
81 }
82
83 for (int band = startBand; band <= endBand; band++) {
84 for (int line = (int)startLine; line <= endLine; line++) {
85 cubeDataBrick.SetBasePosition(qRound(startSample), line, band);
86 cube.read(cubeDataBrick);
87 AddData(cubeDataBrick.DoubleBuffer(), cubeDataBrick.size());
88 if (progress != NULL) {
89 progress->CheckStatus();
90 }
91 }
92 }
93 }
94 }
95
96 void ImageHistogram::InitializeFromCube(Cube &cube, int statsBand,
97 Progress *progress, int nbins, double startSample, double startLine,
98 double endSample, double endLine) {
99 // Make sure band is valid, 0 is valid (means all bands)
100 if ( (statsBand < 0) || (statsBand > cube.bandCount() ) ) {
101 string msg = "Cannot gather histogram for band [" + IString(statsBand) +
102 "]";
103 throw IException(IException::Programmer, msg, _FILEINFO_);
104 }
105
106 // We need to find the min/max DN value for our histogram bins to be the
107 // correct size.
108 double minDnValue = Null;
109 double maxDnValue = Null;
110
111 if (cube.pixelType() == UnsignedByte) {
112 // If we can discretely store every data point, then we can use the
113 // possible extent of the data range as our min/max dn values.
114 if (nbins == 0) {
115 minDnValue = 0.0 * cube.multiplier() + cube.base();
116 maxDnValue = 255.0 * cube.multiplier() + cube.base();
117 nbins = 256;
118 }
119 }
120 else if (cube.pixelType() == UnsignedWord) {
121 if (nbins == 0) {
122 minDnValue = 0.0 * cube.multiplier() + cube.base();
123 maxDnValue = 65535.0 * cube.multiplier() + cube.base();
124 nbins = 65536;
125 }
126 }
127 else if (cube.pixelType() == SignedWord) {
128 if (nbins == 0) {
129 minDnValue = -32768.0 * cube.multiplier() + cube.base();
130 maxDnValue = 32767.0 * cube.multiplier() + cube.base();
131 nbins = 65536;
132 }
133 }
134 // 32-bit data covers too big of a range of values to use
135 // the min and max possible values to set our value range.
136 // So, just set the number of bins and then later we will
137 // compute the min and max value in the actual cube.
138 else if (cube.pixelType() == UnsignedInteger ||
139 cube.pixelType() == SignedInteger ||
140 cube.pixelType() == Real) {
141 if (nbins == 0) {
142 nbins = 65536;
143 }
144 }
145 else {
146 IString msg = "Unsupported pixel type";
147 throw IException(IException::Programmer, msg, _FILEINFO_);
148 }
149
150 if (startSample == Null)
151 startSample = 1.0;
152
153 if (endSample == Null)
154 endSample = cube.sampleCount();
155
156 if (startLine == Null)
157 startLine = 1.0;
158
159 if (endLine == Null)
160 endLine = cube.lineCount();
161
162 // If we still need our min/max DN values, find them.
163 if (minDnValue == Null || maxDnValue == Null) {
164
165 Brick cubeDataBrick((int)(endSample - startSample + 1),
166 1, 1, cube.pixelType() );
167 Statistics stats;
168
169 // if band == 0, then we're gathering stats for all bands. I'm really
170 // not sure that this is correct, a good idea or called from anywhere...
171 // but I don't have time to track down the use case.
172 int startBand = statsBand;
173 int endBand = statsBand;
174
175 if (statsBand == 0) {
176 startBand = 1;
177 endBand = cube.bandCount();
178 }
179
180 if (progress != NULL) {
181
182 progress->SetText("Computing min/max for histogram");
183 progress->SetMaximumSteps(
184 (int)(endLine - startLine + 1) * (int)(endBand - startBand + 1) );
185 progress->CheckStatus();
186 }
187
188 for (int band = startBand; band <= endBand; band++) {
189 for (int line = (int)startLine; line <= endLine; line++) {
190
191 cubeDataBrick.SetBasePosition(qRound(startSample), line, band);
192 cube.read(cubeDataBrick);
193 stats.AddData(cubeDataBrick.DoubleBuffer(), cubeDataBrick.size());
194
195 if (progress != NULL) {
196 progress->CheckStatus();
197 }
198 }
199 }
200
201 if (stats.ValidPixels() == 0) {
202 minDnValue = 0.0;
203 maxDnValue = 1.0;
204 }
205 else {
206 minDnValue = stats.Minimum();
207 maxDnValue = stats.Maximum();
208 }
209 }
210
211 // Set the bins and range
212 SetValidRange(minDnValue, maxDnValue);
213 SetBins(nbins);
214 }
215
219
228 void ImageHistogram::AddData(const double *data,
229 const unsigned int count) {
230 Statistics::AddData(data, count);
231
232 int nbins = p_bins.size();
233 int index;
234 for (unsigned int i = 0; i < count; i++) {
235 if (IsValidPixel(data[i]) && InRange(data[i]) ) {
236 if (BinRangeStart() == BinRangeEnd() ) {
237 index = 0;
238 }
239 else {
240 index = (int) floor((double)(nbins - 1) / (BinRangeEnd() - BinRangeStart()) *
241 (data[i] - BinRangeStart() ) + 0.5);
242 }
243 if (index < 0) index = 0;
244 if (index >= nbins) index = nbins - 1;
245 p_bins[index] += 1;
246 }
247 }
248 }
249
256 void ImageHistogram::AddData(const double data) {
258
259 int nbins = p_bins.size();
260 int index;
261 if (IsValidPixel(data) && InRange(data) ) {
262 if (BinRangeStart() == BinRangeEnd() ) {
263 index = 0;
264 }
265 else {
266 index = (int) floor((double)(nbins - 1) / (BinRangeEnd() - BinRangeStart() ) *
267 (data - BinRangeStart() ) + 0.5);
268 }
269 if (index < 0) index = 0;
270 if (index >= nbins) index = nbins - 1;
271 p_bins[index] += 1;
272 }
273 }
274
284 void ImageHistogram::RemoveData(const double *data,
285 const unsigned int count) {
286 Statistics::RemoveData(data, count);
287
288 int nbins = p_bins.size();
289 int index;
290 for (unsigned int i = 0; i < count; i++) {
291 if (IsValidPixel(data[i]) ) {
292
293 if (BinRangeStart() == BinRangeEnd() ) {
294 index = 0;
295 }
296 else {
297 index = (int) floor((double)(nbins - 1) / (BinRangeEnd() - BinRangeStart()) *
298 (data[i] - BinRangeStart()) + 0.5);
299 }
300 if (index < 0) index = 0;
301 if (index >= nbins) index = nbins - 1;
302 p_bins[index] -= 1;
303 }
304 }
305 }
306
318 void ImageHistogram::BinRange(const int index,
319 double &low, double &high) const {
320 if ( (index < 0) || (index >= (int)p_bins.size() ) ) {
321
322 QString message = Message::ArraySubscriptNotInRange(index);
323 throw IException(IException::Programmer, message, _FILEINFO_);
324 }
325
326 double binSize = (BinRangeEnd() - BinRangeStart()) / (double)(p_bins.size() - 1);
327 low = BinRangeStart() - binSize / 2.0 + binSize * (double) index;
328 high = low + binSize;
329 }
330}
Buffer for containing a three dimensional section of an image.
Definition Brick.h:45
void SetBasePosition(const int start_sample, const int start_line, const int start_band)
This method is used to set the base position of the shape buffer.
Definition Brick.h:120
int size() const
Returns the total number of pixels in the shape buffer.
Definition Buffer.h:97
double * DoubleBuffer() const
Returns the value of the shape buffer.
Definition Buffer.h:138
IO Handler for Isis Cubes.
Definition Cube.h:168
int lineCount() const
Definition Cube.cpp:2008
double multiplier() const
Returns the multiplier value for converting 8-bit/16-bit pixels to 32-bit.
Definition Cube.cpp:2022
int sampleCount() const
Definition Cube.cpp:2081
double base() const
Returns the base value for converting 8-bit/16-bit pixels to 32-bit.
Definition Cube.cpp:1663
PixelType pixelType() const
Definition Cube.cpp:2032
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
Definition Cube.cpp:1043
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Definition Cube.cpp:1646
void SetBins(const int bins)
Change the number of bins in the histogram and reset counters.
std::vector< BigInt > p_bins
The array of counts.
Definition Histogram.h:121
void SetValidRange(const double minimum=Isis::ValidMinimum, const double maximum=Isis::ValidMaximum)
Changes the range of the bins.
ImageHistogram(double minimum, double maximum, int bins=1024)
Constructs a histogram object.
virtual void AddData(const double *data, const unsigned int count)
Add an array of doubles to the histogram counters.
virtual void RemoveData(const double *data, const unsigned int count)
Remove an array of doubles from the histogram counters.
~ImageHistogram()
Destructs a histogram object.
virtual void BinRange(const int index, double &low, double &high) const
Returns the left edge and right edge values of a bin.
Program progress reporter.
Definition Progress.h:42
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition Progress.cpp:85
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition Progress.cpp:61
void CheckStatus()
Checks and updates the status.
Definition Progress.cpp:105
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
void RemoveData(const double *data, const unsigned int count)
Remove an array of doubles from the accumulators and counters.
Statistics(QObject *parent=0)
Constructs an IsisStats object with accumulators and counters set to zero.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
Namespace for the standard library.