USGS

Isis 3.0 Object Programmers' Reference

Home

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 
14 namespace Isis {
24  const Stretch &stretch,
25  const QString &name, const QColor &color)
26  : StretchType(hist, stretch, name, color) {
27  p_startSlider = NULL;
28  p_startEdit = NULL;
29  p_endSlider = NULL;
30  p_endEdit = NULL;
31  p_sliderOverride = false;
32  p_editOverride = false;
33 
34  QWidget *sliderWidget = new QWidget();
35  QGridLayout *sliderLayout = new QGridLayout();
36  sliderLayout->setColumnStretch(1, 10);
37 
38  QLabel *startLabel = new QLabel("Start");
39  p_startSlider = new QSlider(Qt::Horizontal);
40  p_startSlider->setTickPosition(QSlider::NoTicks);
41  p_startSlider->setMinimum(0);
42  p_startSlider->setMaximum(1000);
43  p_startSlider->setPageStep(50);
44  connect(p_startSlider, SIGNAL(valueChanged(int)),
45  this, SLOT(startSliderMoved(int)));
46  p_startEdit = new QLineEdit();
47  p_startEdit->setMaximumWidth(75);
48  p_startEdit->setText(QString::number(p_cubeHist->Percent(25)));
49  connect(p_startEdit, SIGNAL(textChanged(const QString &)),
50  this, SLOT(startEditChanged(const QString &)));
51  sliderLayout->addWidget(startLabel, 0, 0);
52  sliderLayout->addWidget(p_startSlider, 0, 1);
53  sliderLayout->addWidget(p_startEdit, 0, 2);
54 
55  QLabel *endLabel = new QLabel("End");
56  p_endSlider = new QSlider(Qt::Horizontal);
57  p_endSlider->setTickPosition(QSlider::NoTicks);
58  p_endSlider->setMinimum(0);
59  p_endSlider->setMaximum(1000);
60  p_endSlider->setValue(1000);
61  p_endSlider->setPageStep(50);
62  connect(p_endSlider, SIGNAL(valueChanged(int)),
63  this, SLOT(endSliderMoved(int)));
64  p_endEdit = new QLineEdit();
65  p_endEdit->setMaximumWidth(75);
66  p_endEdit->setText(QString::number(p_cubeHist->Percent(75)));
67  connect(p_endEdit, SIGNAL(textChanged(const QString &)),
68  this, SLOT(endEditChanged(const QString &)));
69  sliderLayout->addWidget(endLabel, 1, 0);
70  sliderLayout->addWidget(p_endSlider, 1, 1);
71  sliderLayout->addWidget(p_endEdit, 1, 2);
72 
73  sliderWidget->setLayout(sliderLayout);
74  p_mainLayout->addWidget(sliderWidget, 1, 0);
75 
76  setLayout(p_mainLayout);
78  }
79 
80 
85  }
86 
87 
100  double epsilon = p_cubeHist->BinSize();
101 
102  Stretch interpretted;
103 
104  double switch1 = 0.0;
105  double switch2 = 1.0;
106 
107  if(newStretch.Pairs() == 2) {
108  // given a flat line?
109  if(newStretch.Output(0) == newStretch.Output(1)) {
110  // assume its binary all white
111  interpretted.AddPair(p_cubeHist->Minimum(), 255);
112  interpretted.AddPair(p_cubeHist->Maximum(), 255);
113  }
114  else {
115  // probably linear, figure out something reasonable
116  interpretted.AddPair(p_cubeHist->Minimum(), 0);
117 
118  switch1 = newStretch.Input(0);
119  if(switch1 < p_cubeHist->Minimum())
120  switch1 = p_cubeHist->Minimum() + epsilon;
121 
122  interpretted.AddPair(switch1, 0);
123  interpretted.AddPair(switch1 + epsilon, 255);
124 
125  switch2 = newStretch.Input(1);
126  if(switch2 <= switch1 + epsilon)
127  switch2 = switch1 + epsilon + epsilon;
128 
129  interpretted.AddPair(switch2, 255);
130  interpretted.AddPair(switch2 + epsilon, 0);
131 
132  double end = p_cubeHist->Maximum();
133  if(end <= switch2 + epsilon)
134  end = switch2 + epsilon + epsilon;
135 
136  interpretted.AddPair(end, 0);
137  }
138  }
139  else if(newStretch.Pairs() == 4) {
140  if(newStretch.Output(0) > 127) {
141  interpretted.AddPair(p_cubeHist->Minimum(), 255);
142 
143  switch1 = newStretch.Input(1);
144  if(switch1 <= p_cubeHist->Minimum())
145  switch1 = p_cubeHist->Minimum() + epsilon;
146 
147  interpretted.AddPair(switch1, 255);
148  interpretted.AddPair(switch1 + epsilon, 0);
149 
150  double end = p_cubeHist->Maximum();
151  if(end <= switch1 + epsilon)
152  end = switch1 + epsilon + epsilon;
153 
154  switch2 = end;
155 
156  interpretted.AddPair(end, 0);
157  }
158  else {
159  interpretted.AddPair(p_cubeHist->Minimum(), 0);
160 
161  switch1 = newStretch.Input(1);
162  if(switch1 < p_cubeHist->Minimum())
163  switch1 = p_cubeHist->Minimum() + epsilon;
164 
165  interpretted.AddPair(switch1, 0);
166  interpretted.AddPair(switch1 + epsilon, 255);
167 
168  double end = p_cubeHist->Maximum();
169  if(end <= switch1 + epsilon)
170  end = switch1 + epsilon + epsilon;
171  switch2 = end;
172 
173  interpretted.AddPair(end, 255);
174  }
175  }
176  // 6 pairs means the 255 values are in the middle (typical)
177  else if(newStretch.Pairs() == 6) {
178  interpretted.AddPair(p_cubeHist->Minimum(), 0);
179 
180  switch1 = newStretch.Input(1);
181  if(switch1 <= p_cubeHist->Minimum())
182  switch1 = p_cubeHist->Minimum() + epsilon;
183 
184  interpretted.AddPair(switch1, 0);
185  interpretted.AddPair(switch1 + epsilon, 255);
186 
187 
188  switch2 = newStretch.Input(3);
189  if(switch2 <= switch1 + epsilon)
190  switch2 = switch1 + epsilon + epsilon;
191 
192  interpretted.AddPair(switch2, 255);
193  interpretted.AddPair(switch2 + epsilon, 0);
194 
195  double end = p_cubeHist->Maximum();
196  if(end <= switch2 + epsilon)
197  end = switch2 + epsilon + epsilon;
198 
199  interpretted.AddPair(end, 0);
200  }
201 
202  if(!interpretted.Pairs()) {
203  interpretted.CopyPairs(calculateNewStretch());
204  switch1 = p_startEdit->text().toDouble();
205  switch2 = p_endEdit->text().toDouble();
206  }
207 
208  bool changed = (interpretted.Text() != p_stretch->Text());
209 
210  p_editOverride = true;
211  if(changed) {
212  p_stretch->CopyPairs(interpretted);
213  p_startEdit->setText(QString::number(switch1));
214  p_endEdit->setText(QString::number(switch2));
215  }
216 
217  // regardless of it all, slider positions could need changed...
218  startEditChanged(QString());
219  endEditChanged(QString());
220  p_editOverride = false;
221 
222  if(changed) {
223  emit stretchChanged();
224  }
225  }
226 
227 
233  if(p_sliderOverride)
234  return;
235 
236  if(p_startSlider->value() >= p_endSlider->value()) {
237  p_startSlider->setValue(p_endSlider->value() - 1);
238  return;
239  }
240 
241  double value = p_cubeHist->Minimum();
242  value += p_startSlider->value() *
243  (p_cubeHist->Maximum() - p_cubeHist->Minimum()) / 1000.0;
244  p_startEdit->setText(QString::number(value));
245  }
246 
247 
252  void BinaryStretchType::startEditChanged(const QString &) {
253  double value = p_startEdit->text().toDouble();
254 
255  if(value >= p_endEdit->text().toDouble()) {
256  return;
257  }
258 
259  double percentage = value - p_cubeHist->Minimum();
260  percentage /= (p_cubeHist->Maximum() - p_cubeHist->Minimum());
261  int valuePos = (int)(percentage * 1000.0);
262 
263  p_sliderOverride = true;
264  p_startSlider->setValue(valuePos);
265  p_sliderOverride = false;
266 
267  if(p_editOverride) return;
268 
269  Stretch newStretch = calculateNewStretch();
270 
271  if(newStretch.Text() != p_stretch->Text()) {
272  p_stretch->CopyPairs(newStretch);
273  emit stretchChanged();
274  }
275  }
276 
277 
283  if(p_sliderOverride)
284  return;
285 
286  if(p_endSlider->value() <= p_startSlider->value()) {
287  p_endSlider->setValue(p_startSlider->value() + 1);
288  return;
289  }
290 
291  double value = p_cubeHist->Minimum();
292  value += p_endSlider->value() *
293  (p_cubeHist->Maximum() - p_cubeHist->Minimum()) / 1000.0;
294  p_endEdit->setText(QString::number(value));
295  }
296 
297 
302  void BinaryStretchType::endEditChanged(const QString &) {
303  double value = p_endEdit->text().toDouble();
304 
305  if(value <= p_startEdit->text().toDouble()) {
306  return;
307  }
308 
309  double percentage = value - p_cubeHist->Minimum();
310  percentage /= (p_cubeHist->Maximum() - p_cubeHist->Minimum());
311  int valuePos = (int)(percentage * 1000.0);
312 
313  p_sliderOverride = true;
314  p_endSlider->setValue(valuePos);
315  p_sliderOverride = false;
316 
317  if(p_editOverride) return;
318 
319  Stretch newStretch = calculateNewStretch();
320 
321  if(newStretch.Text() != p_stretch->Text()) {
322  p_stretch->CopyPairs(newStretch);;
323  emit stretchChanged();
324  }
325  }
326 
327 
335  double epsilon = p_cubeHist->BinSize();
336 
337  if(epsilon == 0) {
338  epsilon = (p_cubeHist->Maximum() - p_cubeHist->Minimum()) / 65536;
339  }
340 
341  Stretch newStretch;
342 
343  if(epsilon == 0) {
344  return newStretch;
345  }
346  // Start high?
347  double startPt = p_startEdit->text().toDouble();
348  if(fabs(startPt - p_cubeHist->Minimum()) < epsilon ||
349  startPt <= p_cubeHist->Minimum()) {
350  newStretch.AddPair(p_cubeHist->Minimum(), 255);
351  startPt = p_cubeHist->Minimum() - epsilon;
352  }
353  else {
354  newStretch.AddPair(p_cubeHist->Minimum(), 0);
355  newStretch.AddPair(startPt, 0);
356  newStretch.AddPair(startPt + epsilon, 255);
357  }
358 
359  // End high?
360  double endPt = p_endEdit->text().toDouble();
361  if(endPt <= startPt + epsilon) {
362  endPt = startPt + 2 * epsilon;
363  }
364 
365  if(fabs(endPt + epsilon - p_cubeHist->Maximum()) < epsilon ||
366  endPt + epsilon >= p_cubeHist->Maximum()) {
367  newStretch.AddPair(p_cubeHist->Maximum(), 255);
368  }
369  else {
370  newStretch.AddPair(endPt, 255);
371  newStretch.AddPair(endPt + epsilon, 0);
372  newStretch.AddPair(p_cubeHist->Maximum(), 0);
373  }
374 
375  return newStretch;
376  }
377 }