|
Isis 3.0 Object Programmers' Reference |
Home |
00001 #include "BinaryStretchType.h" 00002 00003 #include <QVBoxLayout> 00004 #include <QLayout> 00005 #include <QLineEdit> 00006 #include <QLabel> 00007 #include <QTableWidget> 00008 00009 #include "CubeViewport.h" 00010 #include "HistogramWidget.h" 00011 #include "Statistics.h" 00012 #include "Stretch.h" 00013 00014 namespace Isis { 00023 BinaryStretchType::BinaryStretchType(const Histogram &hist, 00024 const Stretch &stretch, 00025 const QString &name, const QColor &color) 00026 : StretchType(hist, stretch, name, color) { 00027 p_startSlider = NULL; 00028 p_startEdit = NULL; 00029 p_endSlider = NULL; 00030 p_endEdit = NULL; 00031 p_sliderOverride = false; 00032 p_editOverride = false; 00033 00034 QWidget *sliderWidget = new QWidget(); 00035 QGridLayout *sliderLayout = new QGridLayout(); 00036 sliderLayout->setColumnStretch(1, 10); 00037 00038 QLabel *startLabel = new QLabel("Start"); 00039 p_startSlider = new QSlider(Qt::Horizontal); 00040 p_startSlider->setTickPosition(QSlider::NoTicks); 00041 p_startSlider->setMinimum(0); 00042 p_startSlider->setMaximum(1000); 00043 p_startSlider->setPageStep(50); 00044 connect(p_startSlider, SIGNAL(valueChanged(int)), 00045 this, SLOT(startSliderMoved(int))); 00046 p_startEdit = new QLineEdit(); 00047 p_startEdit->setMaximumWidth(75); 00048 p_startEdit->setText(QString::number(p_cubeHist->Percent(25))); 00049 connect(p_startEdit, SIGNAL(textChanged(const QString &)), 00050 this, SLOT(startEditChanged(const QString &))); 00051 sliderLayout->addWidget(startLabel, 0, 0); 00052 sliderLayout->addWidget(p_startSlider, 0, 1); 00053 sliderLayout->addWidget(p_startEdit, 0, 2); 00054 00055 QLabel *endLabel = new QLabel("End"); 00056 p_endSlider = new QSlider(Qt::Horizontal); 00057 p_endSlider->setTickPosition(QSlider::NoTicks); 00058 p_endSlider->setMinimum(0); 00059 p_endSlider->setMaximum(1000); 00060 p_endSlider->setValue(1000); 00061 p_endSlider->setPageStep(50); 00062 connect(p_endSlider, SIGNAL(valueChanged(int)), 00063 this, SLOT(endSliderMoved(int))); 00064 p_endEdit = new QLineEdit(); 00065 p_endEdit->setMaximumWidth(75); 00066 p_endEdit->setText(QString::number(p_cubeHist->Percent(75))); 00067 connect(p_endEdit, SIGNAL(textChanged(const QString &)), 00068 this, SLOT(endEditChanged(const QString &))); 00069 sliderLayout->addWidget(endLabel, 1, 0); 00070 sliderLayout->addWidget(p_endSlider, 1, 1); 00071 sliderLayout->addWidget(p_endEdit, 1, 2); 00072 00073 sliderWidget->setLayout(sliderLayout); 00074 p_mainLayout->addWidget(sliderWidget, 1, 0); 00075 00076 setLayout(p_mainLayout); 00077 setStretch(calculateNewStretch()); 00078 } 00079 00080 00084 BinaryStretchType::~BinaryStretchType() { 00085 } 00086 00087 00099 void BinaryStretchType::setStretch(Stretch newStretch) { 00100 double epsilon = p_cubeHist->BinSize(); 00101 00102 Stretch interpretted; 00103 00104 double switch1 = 0.0; 00105 double switch2 = 1.0; 00106 00107 if(newStretch.Pairs() == 2) { 00108 // given a flat line? 00109 if(newStretch.Output(0) == newStretch.Output(1)) { 00110 // assume its binary all white 00111 interpretted.AddPair(p_cubeHist->Minimum(), 255); 00112 interpretted.AddPair(p_cubeHist->Maximum(), 255); 00113 } 00114 else { 00115 // probably linear, figure out something reasonable 00116 interpretted.AddPair(p_cubeHist->Minimum(), 0); 00117 00118 switch1 = newStretch.Input(0); 00119 if(switch1 < p_cubeHist->Minimum()) 00120 switch1 = p_cubeHist->Minimum() + epsilon; 00121 00122 interpretted.AddPair(switch1, 0); 00123 interpretted.AddPair(switch1 + epsilon, 255); 00124 00125 switch2 = newStretch.Input(1); 00126 if(switch2 <= switch1 + epsilon) 00127 switch2 = switch1 + epsilon + epsilon; 00128 00129 interpretted.AddPair(switch2, 255); 00130 interpretted.AddPair(switch2 + epsilon, 0); 00131 00132 double end = p_cubeHist->Maximum(); 00133 if(end <= switch2 + epsilon) 00134 end = switch2 + epsilon + epsilon; 00135 00136 interpretted.AddPair(end, 0); 00137 } 00138 } 00139 else if(newStretch.Pairs() == 4) { 00140 if(newStretch.Output(0) > 127) { 00141 interpretted.AddPair(p_cubeHist->Minimum(), 255); 00142 00143 switch1 = newStretch.Input(1); 00144 if(switch1 <= p_cubeHist->Minimum()) 00145 switch1 = p_cubeHist->Minimum() + epsilon; 00146 00147 interpretted.AddPair(switch1, 255); 00148 interpretted.AddPair(switch1 + epsilon, 0); 00149 00150 double end = p_cubeHist->Maximum(); 00151 if(end <= switch1 + epsilon) 00152 end = switch1 + epsilon + epsilon; 00153 00154 switch2 = end; 00155 00156 interpretted.AddPair(end, 0); 00157 } 00158 else { 00159 interpretted.AddPair(p_cubeHist->Minimum(), 0); 00160 00161 switch1 = newStretch.Input(1); 00162 if(switch1 < p_cubeHist->Minimum()) 00163 switch1 = p_cubeHist->Minimum() + epsilon; 00164 00165 interpretted.AddPair(switch1, 0); 00166 interpretted.AddPair(switch1 + epsilon, 255); 00167 00168 double end = p_cubeHist->Maximum(); 00169 if(end <= switch1 + epsilon) 00170 end = switch1 + epsilon + epsilon; 00171 switch2 = end; 00172 00173 interpretted.AddPair(end, 255); 00174 } 00175 } 00176 // 6 pairs means the 255 values are in the middle (typical) 00177 else if(newStretch.Pairs() == 6) { 00178 interpretted.AddPair(p_cubeHist->Minimum(), 0); 00179 00180 switch1 = newStretch.Input(1); 00181 if(switch1 <= p_cubeHist->Minimum()) 00182 switch1 = p_cubeHist->Minimum() + epsilon; 00183 00184 interpretted.AddPair(switch1, 0); 00185 interpretted.AddPair(switch1 + epsilon, 255); 00186 00187 00188 switch2 = newStretch.Input(3); 00189 if(switch2 <= switch1 + epsilon) 00190 switch2 = switch1 + epsilon + epsilon; 00191 00192 interpretted.AddPair(switch2, 255); 00193 interpretted.AddPair(switch2 + epsilon, 0); 00194 00195 double end = p_cubeHist->Maximum(); 00196 if(end <= switch2 + epsilon) 00197 end = switch2 + epsilon + epsilon; 00198 00199 interpretted.AddPair(end, 0); 00200 } 00201 00202 if(!interpretted.Pairs()) { 00203 interpretted.CopyPairs(calculateNewStretch()); 00204 switch1 = p_startEdit->text().toDouble(); 00205 switch2 = p_endEdit->text().toDouble(); 00206 } 00207 00208 bool changed = (interpretted.Text() != p_stretch->Text()); 00209 00210 p_editOverride = true; 00211 if(changed) { 00212 p_stretch->CopyPairs(interpretted); 00213 p_startEdit->setText(QString::number(switch1)); 00214 p_endEdit->setText(QString::number(switch2)); 00215 } 00216 00217 // regardless of it all, slider positions could need changed... 00218 startEditChanged(QString()); 00219 endEditChanged(QString()); 00220 p_editOverride = false; 00221 00222 if(changed) { 00223 emit stretchChanged(); 00224 } 00225 } 00226 00227 00232 void BinaryStretchType::startSliderMoved(int) { 00233 if(p_sliderOverride) 00234 return; 00235 00236 if(p_startSlider->value() >= p_endSlider->value()) { 00237 p_startSlider->setValue(p_endSlider->value() - 1); 00238 return; 00239 } 00240 00241 double value = p_cubeHist->Minimum(); 00242 value += p_startSlider->value() * 00243 (p_cubeHist->Maximum() - p_cubeHist->Minimum()) / 1000.0; 00244 p_startEdit->setText(QString::number(value)); 00245 } 00246 00247 00252 void BinaryStretchType::startEditChanged(const QString &) { 00253 double value = p_startEdit->text().toDouble(); 00254 00255 if(value >= p_endEdit->text().toDouble()) { 00256 return; 00257 } 00258 00259 double percentage = value - p_cubeHist->Minimum(); 00260 percentage /= (p_cubeHist->Maximum() - p_cubeHist->Minimum()); 00261 int valuePos = (int)(percentage * 1000.0); 00262 00263 p_sliderOverride = true; 00264 p_startSlider->setValue(valuePos); 00265 p_sliderOverride = false; 00266 00267 if(p_editOverride) return; 00268 00269 Stretch newStretch = calculateNewStretch(); 00270 00271 if(newStretch.Text() != p_stretch->Text()) { 00272 p_stretch->CopyPairs(newStretch); 00273 emit stretchChanged(); 00274 } 00275 } 00276 00277 00282 void BinaryStretchType::endSliderMoved(int) { 00283 if(p_sliderOverride) 00284 return; 00285 00286 if(p_endSlider->value() <= p_startSlider->value()) { 00287 p_endSlider->setValue(p_startSlider->value() + 1); 00288 return; 00289 } 00290 00291 double value = p_cubeHist->Minimum(); 00292 value += p_endSlider->value() * 00293 (p_cubeHist->Maximum() - p_cubeHist->Minimum()) / 1000.0; 00294 p_endEdit->setText(QString::number(value)); 00295 } 00296 00297 00302 void BinaryStretchType::endEditChanged(const QString &) { 00303 double value = p_endEdit->text().toDouble(); 00304 00305 if(value <= p_startEdit->text().toDouble()) { 00306 return; 00307 } 00308 00309 double percentage = value - p_cubeHist->Minimum(); 00310 percentage /= (p_cubeHist->Maximum() - p_cubeHist->Minimum()); 00311 int valuePos = (int)(percentage * 1000.0); 00312 00313 p_sliderOverride = true; 00314 p_endSlider->setValue(valuePos); 00315 p_sliderOverride = false; 00316 00317 if(p_editOverride) return; 00318 00319 Stretch newStretch = calculateNewStretch(); 00320 00321 if(newStretch.Text() != p_stretch->Text()) { 00322 p_stretch->CopyPairs(newStretch);; 00323 emit stretchChanged(); 00324 } 00325 } 00326 00327 00334 Stretch BinaryStretchType::calculateNewStretch() { 00335 double epsilon = p_cubeHist->BinSize(); 00336 00337 if(epsilon == 0) { 00338 epsilon = (p_cubeHist->Maximum() - p_cubeHist->Minimum()) / 65536; 00339 } 00340 00341 Stretch newStretch; 00342 00343 if(epsilon == 0) { 00344 return newStretch; 00345 } 00346 // Start high? 00347 double startPt = p_startEdit->text().toDouble(); 00348 if(fabs(startPt - p_cubeHist->Minimum()) < epsilon || 00349 startPt <= p_cubeHist->Minimum()) { 00350 newStretch.AddPair(p_cubeHist->Minimum(), 255); 00351 startPt = p_cubeHist->Minimum() - epsilon; 00352 } 00353 else { 00354 newStretch.AddPair(p_cubeHist->Minimum(), 0); 00355 newStretch.AddPair(startPt, 0); 00356 newStretch.AddPair(startPt + epsilon, 255); 00357 } 00358 00359 // End high? 00360 double endPt = p_endEdit->text().toDouble(); 00361 if(endPt <= startPt + epsilon) { 00362 endPt = startPt + 2 * epsilon; 00363 } 00364 00365 if(fabs(endPt + epsilon - p_cubeHist->Maximum()) < epsilon || 00366 endPt + epsilon >= p_cubeHist->Maximum()) { 00367 newStretch.AddPair(p_cubeHist->Maximum(), 255); 00368 } 00369 else { 00370 newStretch.AddPair(endPt, 255); 00371 newStretch.AddPair(endPt + epsilon, 0); 00372 newStretch.AddPair(p_cubeHist->Maximum(), 0); 00373 } 00374 00375 return newStretch; 00376 } 00377 }