]> Creatis software - clitk.git/blob - vv/vvToolResample.cxx
531a03b879098dcd7566f68008ed2ea135b98c89
[clitk.git] / vv / vvToolResample.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to: 
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ======================================================================-====*/
18
19 #include "vvToolResample.h"
20 #include "vvSlicer.h"
21 #include "vvToolCreator.h"
22
23 #include <QFileInfo>
24 #include <QMessageBox>
25
26 #define COLUMN_IMAGE_NAME 7
27
28 ADD_TOOL(vvToolResample);
29
30 //------------------------------------------------------------------------------
31 vvToolResample::vvToolResample(vvMainWindowBase * parent, Qt::WindowFlags f):
32   vvToolWidgetBase(parent,f),
33   vvToolBase<vvToolResample>(parent),
34   Ui::vvToolResample() {
35   Ui_vvToolResample::setupUi(mToolWidget);
36
37   mFilter = clitk::ImageResampleGenericFilter::New();
38   mLastError ="";
39
40   mInputFileFormat = "";
41   ComponentType = "";
42   mPixelType = "";
43   mCurrentSlicerManager=NULL;
44
45   mInputSize.resize(0);
46   mInputSpacing.resize(0);
47   mInputOrigin.resize(0);
48   mOutputSize.resize(0);
49   mOutputSpacing.resize(0);
50
51   xSizeLineEdit->setText("");
52   ySizeLineEdit->setText("");
53   zSizeLineEdit->setText("");
54   xSpacingLineEdit->setText("");
55   ySpacingLineEdit->setText("");
56   zSpacingLineEdit->setText("");
57   scaleSizeLineEdit->setText("");
58   scaleSpacingLineEdit->setText("");
59
60   sizeRadioButton->setChecked(0);
61   scaleSizeRadioButton->setChecked(0);
62   isoSizeRadioButton->setChecked(0);
63   spacingRadioButton->setChecked(0);
64   scaleSpacingRadioButton->setChecked(0);
65   isoSpacingRadioButton->setChecked(0);
66
67   gaussianFilterCheckBox->setCheckState(Qt::Unchecked);
68
69   xGaussianLineEdit->hide();
70   yGaussianLineEdit->hide();
71   zGaussianLineEdit->hide();
72   gaussianFilterLabel->hide();
73
74   bSplineLabel->hide();
75   bSplineOrderSpinBox->hide();
76   bLUTFactorLabel->hide();
77   bLUTSpinBox->hide();
78   mDimension = -1;
79
80   QPalette qPalette;
81   qPalette.setColor(QPalette::Foreground, QColor(Qt::blue));
82   mInputFormatLabel->setPalette(qPalette);
83   mInputDimLabel->setPalette(qPalette);
84   mInputPixelTypeLabel->setPalette(qPalette);
85   mInputSizeLabel->setPalette(qPalette);
86   mInputSpacingLabel->setPalette(qPalette);
87
88   // Set how many inputs are needed for this tool
89   AddInputSelector("Select an image to resample", mFilter);
90
91   // Connect signals & slots
92
93   connect(sizeRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
94   connect(scaleSizeRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
95   connect(isoSizeRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
96   connect(spacingRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
97   connect(scaleSpacingRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
98   connect(isoSpacingRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
99
100   connect(xSizeLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSpacingFromSize()));
101   connect(ySizeLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSpacingFromSize()));
102   connect(zSizeLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSpacingFromSize()));
103   connect(xSpacingLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSizeFromSpacing()));
104   connect(ySpacingLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSizeFromSpacing()));
105   connect(zSpacingLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSizeFromSpacing()));
106   connect(scaleSizeLineEdit,SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSizeFromScale()));
107   connect(scaleSpacingLineEdit,SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSpacingFromScale()));
108   connect(isoSizeLineEdit,SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSizeFromIso()));
109   connect(isoSpacingLineEdit,SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSpacingFromIso()));
110
111   connect(gaussianFilterCheckBox,SIGNAL(stateChanged(int)),this,SLOT(UpdateGaussianFilter()));
112   connect(interpolationComboBox,SIGNAL(currentIndexChanged(QString)),this,SLOT(UpdateInterpolation()));
113 }
114 //------------------------------------------------------------------------------
115
116
117 //------------------------------------------------------------------------------
118 void vvToolResample::Initialize() {
119   SetToolName("Resample Image");
120   SetToolMenuName("Resample");
121   SetToolIconFilename(":/common/icons/resample.png");
122   SetToolTip("Resample image with various interpolation methods.");
123 }
124 //------------------------------------------------------------------------------
125
126
127 //------------------------------------------------------------------------------
128 void vvToolResample::InputIsSelected(vvSlicerManager* m) {
129
130   mCurrentSlicerManager = m;
131   mCurrentImage = mCurrentSlicerManager->GetSlicer(0)->GetImage();
132   if (mCurrentImage.IsNull()) return;
133   mInputFileName = mCurrentSlicerManager->GetFileName().c_str();
134
135   // Set current information
136   mPixelType = mCurrentImage->GetScalarTypeAsString().c_str();
137   //ds      ComponentType = mCurrentImageGetNumberOfScalarComponents();
138   mDimension = mCurrentImage->GetNumberOfDimensions();
139
140   // Copy size, spacing ...
141   mInputOrigin.resize(mDimension);
142   mInputSpacing.resize(mDimension);
143   mInputSize.resize(mDimension);
144   for (int i = 0; i < mDimension;i++) {
145     mInputOrigin[i] = mCurrentImage->GetOrigin()[i];
146     mInputSpacing[i] = mCurrentImage->GetSpacing()[i];
147     mInputSize[i] = mCurrentImage->GetSize()[i];
148   }
149
150   // Get file format
151   mInputFileFormat = itksys::SystemTools::GetFilenameLastExtension(mInputFileName.toStdString()).c_str();
152
153   // Display infos
154   mInputFormatLabel->setText(mInputFileFormat);
155   mInputSizeLabel->setText(GetVectorIntAsString(mInputSize));
156   mInputDimLabel->setText(QString::number(mDimension)+"D");
157   mInputSpacingLabel->setText(GetVectorDoubleAsString(mInputSpacing));
158   mInputPixelTypeLabel->setText(mPixelType);
159   mInputMemoryLabel->setText(GetSizeInBytes(mInputSize));
160
161   // Set current size
162   scaleSizeRadioButton->setChecked(true);
163   UpdateControlSizeAndSpacing();
164   scaleSizeLineEdit->setText("100");
165   ComputeNewSizeFromScale();
166
167   // Update output
168   UpdateOutputInfo();
169 }
170 //------------------------------------------------------------------------------
171
172
173 //------------------------------------------------------------------------------
174 void vvToolResample::UpdateOutputInfo() {
175   mOutputSizeLabel->setText(GetVectorIntAsString(mOutputSize));
176   mOutputSpacingLabel->setText(GetVectorDoubleAsString(mOutputSpacing));
177   mOutputMemoryLabel->setText(GetSizeInBytes(mOutputSize));
178 }
179 //------------------------------------------------------------------------------
180
181
182 //------------------------------------------------------------------------------
183 QString vvToolResample::GetSizeInBytes(std::vector<int> & size) {
184   int t = 1;
185   for (unsigned int i=0; i<size.size(); i++) t *= size[i];
186   t *= mCurrentImage->GetScalarSize()*mCurrentImage->GetNumberOfScalarComponents();
187   QString result = QString::number(t);
188   result += " bytes (";
189   if (t > 1000000000) {
190     t /= 1000000000;
191     result += QString::number(t);
192     result += " GB)";
193   }
194   else if (t > 1000000) {
195     t /= 1000000;
196     result += QString::number(t);
197     result += " MB)";
198   }
199   else if (t > 1000) {
200     t /= 1000;
201     result += QString::number(t);
202     result += " KB)";
203   }
204   else result += ")";
205   return result;
206 }
207 //------------------------------------------------------------------------------
208
209
210 //------------------------------------------------------------------------------
211 QString vvToolResample::GetVectorDoubleAsString(std::vector<double> vectorDouble) {
212   QString result;
213   for (unsigned int i= 0; i<vectorDouble.size(); i++) {
214     if (i != 0)
215       result += " x ";
216     result += QString::number(vectorDouble[i]);
217   }
218   return result;
219 }
220 //------------------------------------------------------------------------------
221
222
223 //------------------------------------------------------------------------------
224 QString vvToolResample::GetVectorIntAsString(std::vector<int> vectorInt) {
225   QString result;
226   for (unsigned int i= 0; i<vectorInt.size(); i++) {
227     if (i != 0)
228       result += " x ";
229     result += QString::number(vectorInt[i]);
230   }
231   return result;
232 }
233 //------------------------------------------------------------------------------
234
235
236 //------------------------------------------------------------------------------
237 void vvToolResample::FillSizeEdit(std::vector<int> size) {
238   xSizeLineEdit->setText(QString::number(size[0]));
239   ySizeLineEdit->setText(QString::number(size[1]));
240   if (size.size() > 2)
241     zSizeLineEdit->setText(QString::number(size[2]));
242 }
243 //------------------------------------------------------------------------------
244
245
246 //------------------------------------------------------------------------------
247 void vvToolResample::FillSpacingEdit(std::vector<double> spacing) {
248   xSpacingLineEdit->setText(QString::number(spacing[0]));
249   ySpacingLineEdit->setText(QString::number(spacing[1]));
250   if (spacing.size() > 2)
251     zSpacingLineEdit->setText(QString::number(spacing[2]));
252 }
253 //------------------------------------------------------------------------------
254
255
256 //------------------------------------------------------------------------------
257 void vvToolResample::UpdateOutputSizeAndSpacing() {
258   mOutputSize.resize(mDimension);
259   mOutputSize = mInputSize;
260   mOutputSpacing.resize(mDimension);
261   mOutputSpacing = mInputSpacing;
262   mOutputSize[0] = (int)xSizeLineEdit->text().toDouble();
263   mOutputSize[1] = (int)ySizeLineEdit->text().toDouble();
264   if (mDimension > 2)
265     mOutputSize[2] = (int)zSizeLineEdit->text().toDouble();
266
267   mOutputSpacing[0] = xSpacingLineEdit->text().toDouble();
268   mOutputSpacing[1] = ySpacingLineEdit->text().toDouble();
269   if (mDimension > 2)
270     mOutputSpacing[2] = zSpacingLineEdit->text().toDouble();
271
272   UpdateOutputInfo();
273 }
274 //------------------------------------------------------------------------------
275
276
277 //------------------------------------------------------------------------------
278 void vvToolResample::UpdateControlSizeAndSpacing() {
279   scaleSizeLineEdit->setText("");
280   scaleSpacingLineEdit->setText("");
281   isoSizeLineEdit->setText("");
282   isoSpacingLineEdit->setText("");
283
284   xSizeLineEdit->setReadOnly(1);
285   ySizeLineEdit->setReadOnly(1);
286   zSizeLineEdit->setReadOnly(1);
287   scaleSizeLineEdit->setReadOnly(1);
288   isoSizeLineEdit->setReadOnly(1);
289
290   xSpacingLineEdit->setReadOnly(1);
291   ySpacingLineEdit->setReadOnly(1);
292   zSpacingLineEdit->setReadOnly(1);
293   scaleSpacingLineEdit->setReadOnly(1);
294   isoSpacingLineEdit->setReadOnly(1);
295
296   if (sizeRadioButton->isChecked()) {
297     xSizeLineEdit->setReadOnly(0);
298     ySizeLineEdit->setReadOnly(0);
299     if (mDimension > 2)
300       zSizeLineEdit->setReadOnly(0);
301   }
302   else {
303     if (spacingRadioButton->isChecked()) {
304       xSpacingLineEdit->setReadOnly(0);
305       ySpacingLineEdit->setReadOnly(0);
306       if (mDimension > 2)
307         zSpacingLineEdit->setReadOnly(0);
308     }
309     else if (scaleSizeRadioButton->isChecked())
310       scaleSizeLineEdit->setReadOnly(0);
311     else if (scaleSpacingRadioButton->isChecked())
312       scaleSpacingLineEdit->setReadOnly(0);
313     else if (isoSizeRadioButton->isChecked())
314       isoSizeLineEdit->setReadOnly(0);
315     else if (isoSpacingRadioButton->isChecked())
316       isoSpacingLineEdit->setReadOnly(0);
317   }
318 }
319 //------------------------------------------------------------------------------
320
321
322 //------------------------------------------------------------------------------
323 void vvToolResample::ComputeNewSpacingFromSize() {
324   double newSpacing = mInputSpacing[0]*mInputSize[0];
325   xSpacingLineEdit->setText(QString::number(newSpacing/xSizeLineEdit->text().toDouble()));
326   newSpacing = mInputSpacing[1]*mInputSize[1];
327   ySpacingLineEdit->setText(QString::number(newSpacing/ySizeLineEdit->text().toDouble()));
328   if (mDimension > 2)
329     {
330       newSpacing = mInputSpacing[2]*mInputSize[2];
331       zSpacingLineEdit->setText(QString::number(newSpacing/zSizeLineEdit->text().toDouble()));
332     }
333   UpdateOutputSizeAndSpacing();
334 }
335 //------------------------------------------------------------------------------
336
337
338 //------------------------------------------------------------------------------
339 void vvToolResample::ComputeNewSizeFromSpacing() {
340   double newSize = mInputSpacing[0]*mInputSize[0];
341   xSizeLineEdit->setText(QString::number(newSize/xSpacingLineEdit->text().toDouble()));
342   newSize = mInputSpacing[1]*mInputSize[1];
343   ySizeLineEdit->setText(QString::number(newSize/ySpacingLineEdit->text().toDouble()));
344   if (mDimension > 2)
345     {
346       newSize = mInputSpacing[2]*mInputSize[2];
347       zSizeLineEdit->setText(QString::number(newSize/zSpacingLineEdit->text().toDouble()));
348     }
349   UpdateOutputSizeAndSpacing();
350 }
351 //------------------------------------------------------------------------------
352
353
354 //------------------------------------------------------------------------------
355 void vvToolResample::ComputeNewSpacingFromScale() {
356   xSpacingLineEdit->setText(QString::number(mInputSpacing[0]*scaleSpacingLineEdit->text().toDouble()/100));
357   ySpacingLineEdit->setText(QString::number(mInputSpacing[1]*scaleSpacingLineEdit->text().toDouble()/100));
358   if (mDimension > 2)
359     zSpacingLineEdit->setText(QString::number(mInputSpacing[2]*scaleSpacingLineEdit->text().toDouble()/100));
360   ComputeNewSizeFromSpacing();
361 }
362 //------------------------------------------------------------------------------
363
364
365 //------------------------------------------------------------------------------
366 void vvToolResample::ComputeNewSizeFromScale() {
367   xSizeLineEdit->setText(QString::number(mInputSize[0]*scaleSizeLineEdit->text().toDouble()/100));
368   ySizeLineEdit->setText(QString::number(mInputSize[1]*scaleSizeLineEdit->text().toDouble()/100));
369   if (mDimension > 2)
370     zSizeLineEdit->setText(QString::number(mInputSize[2]*scaleSizeLineEdit->text().toDouble()/100));
371   ComputeNewSpacingFromSize();
372 }
373 //------------------------------------------------------------------------------
374
375
376 //------------------------------------------------------------------------------
377 void vvToolResample::ComputeNewSpacingFromIso() {
378   xSpacingLineEdit->setText(QString::number(isoSpacingLineEdit->text().toDouble()));
379   ySpacingLineEdit->setText(QString::number(isoSpacingLineEdit->text().toDouble()));
380   if (mDimension > 2)
381     zSpacingLineEdit->setText(QString::number(isoSpacingLineEdit->text().toDouble()));
382   ComputeNewSizeFromSpacing();
383 }
384 //------------------------------------------------------------------------------
385
386
387 //------------------------------------------------------------------------------
388 void vvToolResample::ComputeNewSizeFromIso() {
389   xSizeLineEdit->setText(QString::number(isoSizeLineEdit->text().toDouble()));
390   ySizeLineEdit->setText(QString::number(isoSizeLineEdit->text().toDouble()));
391   if (mDimension > 2)
392     zSizeLineEdit->setText(QString::number(isoSizeLineEdit->text().toDouble()));
393   ComputeNewSpacingFromSize();
394 }
395 //------------------------------------------------------------------------------
396
397
398 //------------------------------------------------------------------------------
399 void vvToolResample::UpdateInterpolation() {
400   if (interpolationComboBox->currentText() == "BSpline") {
401     bSplineLabel->show();
402     bSplineOrderSpinBox->show();
403     bLUTFactorLabel->hide();
404     bLUTSpinBox->hide();
405   }
406   else if (interpolationComboBox->currentText() == "B-LUT (faster BSpline)")   {
407     bSplineLabel->show();
408     bSplineOrderSpinBox->show();
409     bLUTFactorLabel->show();
410     bLUTSpinBox->show();
411   }
412   else {
413     bSplineLabel->hide();
414     bSplineOrderSpinBox->hide();
415     bLUTFactorLabel->hide();
416     bLUTSpinBox->hide();
417   }
418 }
419 //------------------------------------------------------------------------------
420
421
422 //------------------------------------------------------------------------------
423 void vvToolResample::UpdateGaussianFilter() {
424   if (gaussianFilterCheckBox->isChecked()) {
425     gaussianFilterLabel->show();
426     xGaussianLineEdit->show();
427     yGaussianLineEdit->show();
428     if (mDimension > 2)
429       zGaussianLineEdit->show();
430   }
431   else {
432     gaussianFilterLabel->hide();
433     xGaussianLineEdit->hide();
434     yGaussianLineEdit->hide();
435     zGaussianLineEdit->hide();
436   }
437 }
438 //------------------------------------------------------------------------------
439
440
441 //------------------------------------------------------------------------------
442 void vvToolResample::apply() {
443
444   // Get resampler options
445   std::vector<double> sigma;
446   sigma.push_back(xGaussianLineEdit->text().toDouble());
447   sigma.push_back(yGaussianLineEdit->text().toDouble());
448   if (mDimension > 2) sigma.push_back(zGaussianLineEdit->text().toDouble());
449   if (mDimension == 4) sigma.push_back(0.01); //FIXME Don't filter along the temporal direction
450
451   mFilter->SetOutputSize(mOutputSize);
452   mFilter->SetOutputSpacing(mOutputSpacing);
453   mFilter->SetInterpolationName(interpolationComboBox->currentText().toLower().toStdString());
454
455   if (interpolationComboBox->currentText() == "BSpline")
456     mFilter->SetBSplineOrder(bSplineOrderSpinBox->value());
457   else if (interpolationComboBox->currentText() == "B-LUT (faster BSpline)") {
458     mFilter->SetInterpolationName("blut");
459     mFilter->SetBSplineOrder(bSplineOrderSpinBox->value());
460     mFilter->SetBLUTSampling(bLUTSpinBox->value());
461   }
462   if (gaussianFilterCheckBox->isChecked())
463     mFilter->SetGaussianSigma(sigma);
464   //  mFilter->SetOutputFileName(OutputFileName.toStdString());
465   mFilter->SetDefaultPixelValue(defaultPixelValueLineEdit->text().toDouble());
466   mFilter->SetInputVVImage(mCurrentImage);
467
468   // Go !
469   mFilter->Update();
470   mOutput = mFilter->GetOutputVVImage();
471   AddImage(mOutput,GetOutputFileName());
472   close();
473 }
474 //------------------------------------------------------------------------------
475
476
477 //------------------------------------------------------------------------------
478 std::string vvToolResample::GetOutputFileName() {
479   QFileInfo info(QString(mCurrentSlicerManager->GetFileName().c_str()));
480   return (info.path().toStdString() + "/resampled_" + info.fileName().toStdString());
481 }
482 //------------------------------------------------------------------------------
483