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