File failed to load: https://isis.astrogeology.usgs.gov/9.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
BinaryStretchType.cpp
1#include "BinaryStretchType.h"
2
3#include <QVBoxLayout>
4#include <QLayout>
5#include <QLineEdit>
6#include <QLabel>
7#include <QTableWidget>
8
9#include "CubeViewport.h"
10#include "HistogramWidget.h"
11#include "Statistics.h"
12#include "Stretch.h"
13#include "CubeStretch.h"
14
15namespace Isis {
25 const Stretch &stretch,
26 const QString &name, const QColor &color)
27 : StretchType(hist, stretch, name, color) {
28 p_startSlider = NULL;
29 p_startEdit = NULL;
30 p_endSlider = NULL;
31 p_endEdit = NULL;
32 p_sliderOverride = false;
33 p_editOverride = false;
34
35 QWidget *sliderWidget = new QWidget();
36 QGridLayout *sliderLayout = new QGridLayout();
37 sliderLayout->setColumnStretch(1, 10);
38
39 QLabel *startLabel = new QLabel("Start");
40 p_startSlider = new QSlider(Qt::Horizontal);
41 p_startSlider->setTickPosition(QSlider::NoTicks);
42 p_startSlider->setMinimum(0);
43 p_startSlider->setMaximum(1000);
44 p_startSlider->setPageStep(50);
45 connect(p_startSlider, SIGNAL(valueChanged(int)),
46 this, SLOT(startSliderMoved(int)));
47 p_startEdit = new QLineEdit();
48 p_startEdit->setMaximumWidth(75);
49 p_startEdit->setText(QString::number(p_cubeHist->Percent(25)));
50 connect(p_startEdit, SIGNAL(textChanged(const QString &)),
51 this, SLOT(startEditChanged(const QString &)));
52 sliderLayout->addWidget(startLabel, 0, 0);
53 sliderLayout->addWidget(p_startSlider, 0, 1);
54 sliderLayout->addWidget(p_startEdit, 0, 2);
55
56 QLabel *endLabel = new QLabel("End");
57 p_endSlider = new QSlider(Qt::Horizontal);
58 p_endSlider->setTickPosition(QSlider::NoTicks);
59 p_endSlider->setMinimum(0);
60 p_endSlider->setMaximum(1000);
61 p_endSlider->setValue(1000);
62 p_endSlider->setPageStep(50);
63 connect(p_endSlider, SIGNAL(valueChanged(int)),
64 this, SLOT(endSliderMoved(int)));
65 p_endEdit = new QLineEdit();
66 p_endEdit->setMaximumWidth(75);
67 p_endEdit->setText(QString::number(p_cubeHist->Percent(75)));
68 connect(p_endEdit, SIGNAL(textChanged(const QString &)),
69 this, SLOT(endEditChanged(const QString &)));
70 sliderLayout->addWidget(endLabel, 1, 0);
71 sliderLayout->addWidget(p_endSlider, 1, 1);
72 sliderLayout->addWidget(p_endEdit, 1, 2);
73
74 sliderWidget->setLayout(sliderLayout);
75 p_mainLayout->addWidget(sliderWidget, 1, 0);
76
77 setLayout(p_mainLayout);
79 }
80
81
87
88
101 double epsilon = p_cubeHist->BinSize();
102
103 Stretch interpretted;
104
105 double switch1 = 0.0;
106 double switch2 = 1.0;
107
108 if(newStretch.Pairs() == 2) {
109 // given a flat line?
110 if(newStretch.Output(0) == newStretch.Output(1)) {
111 // assume its binary all white
112 interpretted.AddPair(p_cubeHist->Minimum(), 255);
113 interpretted.AddPair(p_cubeHist->Maximum(), 255);
114 }
115 else {
116 // probably linear, figure out something reasonable
117 interpretted.AddPair(p_cubeHist->Minimum(), 0);
118
119 switch1 = newStretch.Input(0);
120 if(switch1 < p_cubeHist->Minimum())
121 switch1 = p_cubeHist->Minimum() + epsilon;
122
123 interpretted.AddPair(switch1, 0);
124 interpretted.AddPair(switch1 + epsilon, 255);
125
126 switch2 = newStretch.Input(1);
127 if(switch2 <= switch1 + epsilon)
128 switch2 = switch1 + epsilon + epsilon;
129
130 interpretted.AddPair(switch2, 255);
131 interpretted.AddPair(switch2 + epsilon, 0);
132
133 double end = p_cubeHist->Maximum();
134 if(end <= switch2 + epsilon)
135 end = switch2 + epsilon + epsilon;
136
137 interpretted.AddPair(end, 0);
138 }
139 }
140 else if(newStretch.Pairs() == 4) {
141 if(newStretch.Output(0) > 127) {
142 interpretted.AddPair(p_cubeHist->Minimum(), 255);
143
144 switch1 = newStretch.Input(1);
145 if(switch1 <= p_cubeHist->Minimum())
146 switch1 = p_cubeHist->Minimum() + epsilon;
147
148 interpretted.AddPair(switch1, 255);
149 interpretted.AddPair(switch1 + epsilon, 0);
150
151 double end = p_cubeHist->Maximum();
152 if(end <= switch1 + epsilon)
153 end = switch1 + epsilon + epsilon;
154
155 switch2 = end;
156
157 interpretted.AddPair(end, 0);
158 }
159 else {
160 interpretted.AddPair(p_cubeHist->Minimum(), 0);
161
162 switch1 = newStretch.Input(1);
163 if(switch1 < p_cubeHist->Minimum())
164 switch1 = p_cubeHist->Minimum() + epsilon;
165
166 interpretted.AddPair(switch1, 0);
167 interpretted.AddPair(switch1 + epsilon, 255);
168
169 double end = p_cubeHist->Maximum();
170 if(end <= switch1 + epsilon)
171 end = switch1 + epsilon + epsilon;
172 switch2 = end;
173
174 interpretted.AddPair(end, 255);
175 }
176 }
177 // 6 pairs means the 255 values are in the middle (typical)
178 else if(newStretch.Pairs() == 6) {
179 interpretted.AddPair(p_cubeHist->Minimum(), 0);
180
181 switch1 = newStretch.Input(1);
182 if(switch1 <= p_cubeHist->Minimum())
183 switch1 = p_cubeHist->Minimum() + epsilon;
184
185 interpretted.AddPair(switch1, 0);
186 interpretted.AddPair(switch1 + epsilon, 255);
187
188
189 switch2 = newStretch.Input(3);
190 if(switch2 <= switch1 + epsilon)
191 switch2 = switch1 + epsilon + epsilon;
192
193 interpretted.AddPair(switch2, 255);
194 interpretted.AddPair(switch2 + epsilon, 0);
195
196 double end = p_cubeHist->Maximum();
197 if(end <= switch2 + epsilon)
198 end = switch2 + epsilon + epsilon;
199
200 interpretted.AddPair(end, 0);
201 }
202
203 if(!interpretted.Pairs()) {
204 interpretted.CopyPairs(calculateNewStretch());
205 switch1 = p_startEdit->text().toDouble();
206 switch2 = p_endEdit->text().toDouble();
207 }
208
209 bool changed = (interpretted.Text() != p_stretch->Text());
210
211 p_editOverride = true;
212 if(changed) {
213 p_stretch->CopyPairs(interpretted);
214 p_startEdit->setText(QString::number(switch1));
215 p_endEdit->setText(QString::number(switch2));
216 }
217
218 // regardless of it all, slider positions could need changed...
219 startEditChanged(QString());
220 endEditChanged(QString());
221 p_editOverride = false;
222
223 if(changed) {
224 emit stretchChanged();
225 }
226 }
227
228
235 return;
236
237 if(p_startSlider->value() >= p_endSlider->value()) {
238 p_startSlider->setValue(p_endSlider->value() - 1);
239 return;
240 }
241
242 double value = p_cubeHist->Minimum();
243 value += p_startSlider->value() *
244 (p_cubeHist->Maximum() - p_cubeHist->Minimum()) / 1000.0;
245 p_startEdit->setText(QString::number(value));
246 }
247
248
254 double value = p_startEdit->text().toDouble();
255
256 if(value >= p_endEdit->text().toDouble()) {
257 return;
258 }
259
260 double percentage = value - p_cubeHist->Minimum();
261 percentage /= (p_cubeHist->Maximum() - p_cubeHist->Minimum());
262 int valuePos = (int)(percentage * 1000.0);
263
264 p_sliderOverride = true;
265 p_startSlider->setValue(valuePos);
266 p_sliderOverride = false;
267
268 if(p_editOverride) return;
269
270 Stretch newStretch = calculateNewStretch();
271
272 if(newStretch.Text() != p_stretch->Text()) {
273 p_stretch->CopyPairs(newStretch);
274 emit stretchChanged();
275 }
276 }
277
278
285 return;
286
287 if(p_endSlider->value() <= p_startSlider->value()) {
288 p_endSlider->setValue(p_startSlider->value() + 1);
289 return;
290 }
291
292 double value = p_cubeHist->Minimum();
293 value += p_endSlider->value() *
294 (p_cubeHist->Maximum() - p_cubeHist->Minimum()) / 1000.0;
295 p_endEdit->setText(QString::number(value));
296 }
297
298
303 void BinaryStretchType::endEditChanged(const QString &) {
304 double value = p_endEdit->text().toDouble();
305
306 if(value <= p_startEdit->text().toDouble()) {
307 return;
308 }
309
310 double percentage = value - p_cubeHist->Minimum();
311 percentage /= (p_cubeHist->Maximum() - p_cubeHist->Minimum());
312 int valuePos = (int)(percentage * 1000.0);
313
314 p_sliderOverride = true;
315 p_endSlider->setValue(valuePos);
316 p_sliderOverride = false;
317
318 if(p_editOverride) return;
319
320 Stretch newStretch = calculateNewStretch();
321
322 if(newStretch.Text() != p_stretch->Text()) {
323 p_stretch->CopyPairs(newStretch);;
324 emit stretchChanged();
325 }
326 }
327
328
336 double epsilon = p_cubeHist->BinSize();
337
338 if(epsilon == 0) {
339 epsilon = (p_cubeHist->Maximum() - p_cubeHist->Minimum()) / 65536;
340 }
341
342 Stretch newStretch;
343
344 if(epsilon == 0) {
345 return newStretch;
346 }
347 // Start high?
348 double startPt = p_startEdit->text().toDouble();
349 if(fabs(startPt - p_cubeHist->Minimum()) < epsilon ||
350 startPt <= p_cubeHist->Minimum()) {
351 newStretch.AddPair(p_cubeHist->Minimum(), 255);
352 startPt = p_cubeHist->Minimum() - epsilon;
353 }
354 else {
355 newStretch.AddPair(p_cubeHist->Minimum(), 0);
356 newStretch.AddPair(startPt, 0);
357 newStretch.AddPair(startPt + epsilon, 255);
358 }
359
360 // End high?
361 double endPt = p_endEdit->text().toDouble();
362 if(endPt <= startPt + epsilon) {
363 endPt = startPt + 2 * epsilon;
364 }
365
366 if(fabs(endPt + epsilon - p_cubeHist->Maximum()) < epsilon ||
367 endPt + epsilon >= p_cubeHist->Maximum()) {
368 newStretch.AddPair(p_cubeHist->Maximum(), 255);
369 }
370 else {
371 newStretch.AddPair(endPt, 255);
372 newStretch.AddPair(endPt + epsilon, 0);
373 newStretch.AddPair(p_cubeHist->Maximum(), 0);
374 }
375
376 return newStretch;
377 }
378
379
386 CubeStretch cubeStretch(*p_stretch, "Binary");
387 return cubeStretch;
388 }
389}
BinaryStretchType(const Histogram &, const Stretch &, const QString &name, const QColor &color)
This constructs a binary stretch type.
virtual CubeStretch getStretch()
Gets the CubeStretch for this Binary Stretch.
QSlider * p_endSlider
End point slider.
bool p_sliderOverride
This is used to let the edits be changed to where sliders cant go.
void startEditChanged(const QString &)
A new start point was typed in.
void startSliderMoved(int)
This is called when the start point slider moves.
QLineEdit * p_endEdit
End point edit.
virtual void setStretch(Stretch)
Given an arbitrary stretch, this will re-interpret it, as best as possible, into a binary stretch.
void endSliderMoved(int)
This is called when the end point slider moves.
~BinaryStretchType()
Destroys the binary stretch.
Stretch calculateNewStretch()
This uses the GUI elements to calculate the current binary stretch.
void endEditChanged(const QString &)
A new end point was typed in.
QSlider * p_startSlider
Start point slider.
bool p_editOverride
This is used to let the edits be changed without updating the stretch.
QLineEdit * p_startEdit
Start point edit.
Stores stretch information for a cube.
Definition CubeStretch.h:27
Container of a cube histogram.
Definition Histogram.h:74
Pixel value mapper.
Definition Stretch.h:58
void CopyPairs(const Stretch &other)
Copies the stretch pairs from another Stretch object, but maintains special pixel values.
Definition Stretch.cpp:392
void AddPair(const double input, const double output)
Adds a stretch pair to the list of pairs.
Definition Stretch.cpp:48
double Output(const int index) const
Returns the value of the output side of the stretch pair at the specified index.
Definition Stretch.cpp:302
double Input(const int index) const
Returns the value of the input side of the stretch pair at the specified index.
Definition Stretch.cpp:287
int Pairs() const
Returns the number of stretch pairs.
Definition Stretch.h:162
QString Text() const
Converts stretch pair to a string.
Definition Stretch.cpp:268
Stretch * p_stretch
Current stretch pairs stored here.
Definition StretchType.h:71
Histogram * p_cubeHist
Visible area histogram.
Definition StretchType.h:68
StretchType(const Histogram &hist, const Stretch &stretch, const QString &name, const QColor &color)
This constructs a stretch type.
QGridLayout * p_mainLayout
Main layout.
Definition StretchType.h:67
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition IString.cpp:149