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