]> Creatis software - clitk.git/blob - vv/vvToolResample.cxx
minor bugfixes
[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 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 void vvToolResample::InputIsSelected(vvSlicerManager* m) {
128
129     mCurrentSlicerManager = m;
130     mCurrentImage = mCurrentSlicerManager->GetSlicer(0)->GetImage();
131     if (mCurrentImage.IsNull()) return;
132     mInputFileName = mCurrentSlicerManager->GetFileName().c_str();
133
134     // Set current information
135     mPixelType = mCurrentImage->GetScalarTypeAsString().c_str();
136     //ds      ComponentType = mCurrentImageGetNumberOfScalarComponents();
137     mDimension = mCurrentImage->GetNumberOfDimensions();
138
139     // Copy size, spacing ...
140     mInputOrigin.resize(mDimension);
141     mInputSpacing.resize(mDimension);
142     mInputSize.resize(mDimension);
143     for (int i = 0; i < mDimension;i++) {
144         mInputOrigin[i] = mCurrentImage->GetOrigin()[i];
145         mInputSpacing[i] = mCurrentImage->GetSpacing()[i];
146         mInputSize[i] = mCurrentImage->GetSize()[i];
147     }
148
149     // Get file format
150     mInputFileFormat = itksys::SystemTools::GetFilenameLastExtension(mInputFileName.toStdString()).c_str();
151
152     // Display infos
153     mInputFormatLabel->setText(mInputFileFormat);
154     mInputSizeLabel->setText(GetVectorIntAsString(mInputSize));
155     mInputDimLabel->setText(QString::number(mDimension)+"D");
156     mInputSpacingLabel->setText(GetVectorDoubleAsString(mInputSpacing));
157     mInputPixelTypeLabel->setText(mPixelType);
158     mInputMemoryLabel->setText(GetSizeInBytes(mInputSize));
159
160     // Set current size
161     scaleSizeRadioButton->setChecked(true);
162     UpdateControlSizeAndSpacing();
163     scaleSizeLineEdit->setText("100");
164     ComputeNewSizeFromScale();
165
166     // Update output
167     UpdateOutputInfo();
168 }
169 //====================================================================
170
171 //====================================================================
172 void vvToolResample::UpdateOutputInfo() {
173     mOutputSizeLabel->setText(GetVectorIntAsString(mOutputSize));
174     mOutputSpacingLabel->setText(GetVectorDoubleAsString(mOutputSpacing));
175     mOutputMemoryLabel->setText(GetSizeInBytes(mOutputSize));
176 }
177 //====================================================================
178
179 //====================================================================
180 QString vvToolResample::GetSizeInBytes(std::vector<int> & size) {
181     int t = 1;
182     for (unsigned int i=0; i<size.size(); i++) t *= size[i];
183     t *= mCurrentImage->GetScalarSize()*mCurrentImage->GetNumberOfScalarComponents();
184     QString result = QString::number(t);
185     result += " bytes (";
186     if (t > 1000000000) {
187         t /= 1000000000;
188         result += QString::number(t);
189         result += " GB)";
190     }
191     else if (t > 1000000) {
192         t /= 1000000;
193         result += QString::number(t);
194         result += " MB)";
195     }
196     else if (t > 1000) {
197         t /= 1000;
198         result += QString::number(t);
199         result += " KB)";
200     }
201     else result += ")";
202     return result;
203 }
204 //====================================================================
205
206 //====================================================================
207 QString vvToolResample::GetVectorDoubleAsString(std::vector<double> vectorDouble) {
208     QString result;
209     for (unsigned int i= 0; i<vectorDouble.size(); i++) {
210         if (i != 0)
211             result += " x ";
212         result += QString::number(vectorDouble[i]);
213     }
214     return result;
215 }
216 //====================================================================
217
218 //====================================================================
219 QString vvToolResample::GetVectorIntAsString(std::vector<int> vectorInt) {
220     QString result;
221     for (unsigned int i= 0; i<vectorInt.size(); i++) {
222         if (i != 0)
223             result += " x ";
224         result += QString::number(vectorInt[i]);
225     }
226     return result;
227 }
228 //====================================================================
229
230 //====================================================================
231 void vvToolResample::FillSizeEdit(std::vector<int> size) {
232     xSizeLineEdit->setText(QString::number(size[0]));
233     ySizeLineEdit->setText(QString::number(size[1]));
234     if (size.size() > 2)
235         zSizeLineEdit->setText(QString::number(size[2]));
236 }
237 //====================================================================
238
239 //====================================================================
240 void vvToolResample::FillSpacingEdit(std::vector<double> spacing) {
241     xSpacingLineEdit->setText(QString::number(spacing[0]));
242     ySpacingLineEdit->setText(QString::number(spacing[1]));
243     if (spacing.size() > 2)
244         zSpacingLineEdit->setText(QString::number(spacing[2]));
245 }
246 //====================================================================
247
248 //====================================================================
249 void vvToolResample::UpdateOutputSizeAndSpacing() {
250     mOutputSize.resize(mDimension);
251     mOutputSize = mInputSize;
252     mOutputSpacing.resize(mDimension);
253     mOutputSpacing = mInputSpacing;
254     mOutputSize[0] = (int)xSizeLineEdit->text().toDouble();
255     mOutputSize[1] = (int)ySizeLineEdit->text().toDouble();
256     if (mDimension > 2)
257         mOutputSize[2] = (int)zSizeLineEdit->text().toDouble();
258
259     mOutputSpacing[0] = xSpacingLineEdit->text().toDouble();
260     mOutputSpacing[1] = ySpacingLineEdit->text().toDouble();
261     if (mDimension > 2)
262         mOutputSpacing[2] = zSpacingLineEdit->text().toDouble();
263
264     UpdateOutputInfo();
265 }
266 //====================================================================
267
268 //====================================================================
269 void vvToolResample::UpdateControlSizeAndSpacing() {
270     scaleSizeLineEdit->setText("");
271     scaleSpacingLineEdit->setText("");
272     isoSizeLineEdit->setText("");
273     isoSpacingLineEdit->setText("");
274
275     xSizeLineEdit->setReadOnly(1);
276     ySizeLineEdit->setReadOnly(1);
277     zSizeLineEdit->setReadOnly(1);
278     scaleSizeLineEdit->setReadOnly(1);
279     isoSizeLineEdit->setReadOnly(1);
280
281     xSpacingLineEdit->setReadOnly(1);
282     ySpacingLineEdit->setReadOnly(1);
283     zSpacingLineEdit->setReadOnly(1);
284     scaleSpacingLineEdit->setReadOnly(1);
285     isoSpacingLineEdit->setReadOnly(1);
286
287     if (sizeRadioButton->isChecked()) {
288         xSizeLineEdit->setReadOnly(0);
289         ySizeLineEdit->setReadOnly(0);
290         if (mDimension > 2)
291             zSizeLineEdit->setReadOnly(0);
292     }
293     else {
294         if (spacingRadioButton->isChecked()) {
295             xSpacingLineEdit->setReadOnly(0);
296             ySpacingLineEdit->setReadOnly(0);
297             if (mDimension > 2)
298                 zSpacingLineEdit->setReadOnly(0);
299         }
300         else if (scaleSizeRadioButton->isChecked())
301             scaleSizeLineEdit->setReadOnly(0);
302         else if (scaleSpacingRadioButton->isChecked())
303             scaleSpacingLineEdit->setReadOnly(0);
304         else if (isoSizeRadioButton->isChecked())
305             isoSizeLineEdit->setReadOnly(0);
306         else if (isoSpacingRadioButton->isChecked())
307             isoSpacingLineEdit->setReadOnly(0);
308     }
309 }
310 //====================================================================
311
312 //====================================================================
313 void vvToolResample::ComputeNewSpacingFromSize() {
314     double newSpacing = mInputSpacing[0]*mInputSize[0];
315     xSpacingLineEdit->setText(QString::number(newSpacing/xSizeLineEdit->text().toDouble()));
316     newSpacing = mInputSpacing[1]*mInputSize[1];
317     ySpacingLineEdit->setText(QString::number(newSpacing/ySizeLineEdit->text().toDouble()));
318     if (mDimension > 2)
319     {
320         newSpacing = mInputSpacing[2]*mInputSize[2];
321         zSpacingLineEdit->setText(QString::number(newSpacing/zSizeLineEdit->text().toDouble()));
322     }
323     UpdateOutputSizeAndSpacing();
324 }
325 //====================================================================
326
327 //====================================================================
328 void vvToolResample::ComputeNewSizeFromSpacing() {
329     double newSize = mInputSpacing[0]*mInputSize[0];
330     xSizeLineEdit->setText(QString::number(newSize/xSpacingLineEdit->text().toDouble()));
331     newSize = mInputSpacing[1]*mInputSize[1];
332     ySizeLineEdit->setText(QString::number(newSize/ySpacingLineEdit->text().toDouble()));
333     if (mDimension > 2)
334     {
335         newSize = mInputSpacing[2]*mInputSize[2];
336         zSizeLineEdit->setText(QString::number(newSize/zSpacingLineEdit->text().toDouble()));
337     }
338     UpdateOutputSizeAndSpacing();
339 }
340 //====================================================================
341
342 //====================================================================
343 void vvToolResample::ComputeNewSpacingFromScale() {
344     xSpacingLineEdit->setText(QString::number(mInputSpacing[0]*scaleSpacingLineEdit->text().toDouble()/100));
345     ySpacingLineEdit->setText(QString::number(mInputSpacing[1]*scaleSpacingLineEdit->text().toDouble()/100));
346     if (mDimension > 2)
347         zSpacingLineEdit->setText(QString::number(mInputSpacing[2]*scaleSpacingLineEdit->text().toDouble()/100));
348     ComputeNewSizeFromSpacing();
349 }
350 //====================================================================
351
352 //====================================================================
353 void vvToolResample::ComputeNewSizeFromScale() {
354     xSizeLineEdit->setText(QString::number(mInputSize[0]*scaleSizeLineEdit->text().toDouble()/100));
355     ySizeLineEdit->setText(QString::number(mInputSize[1]*scaleSizeLineEdit->text().toDouble()/100));
356     if (mDimension > 2)
357         zSizeLineEdit->setText(QString::number(mInputSize[2]*scaleSizeLineEdit->text().toDouble()/100));
358     ComputeNewSpacingFromSize();
359 }
360 //====================================================================
361
362 //====================================================================
363 void vvToolResample::ComputeNewSpacingFromIso() {
364     xSpacingLineEdit->setText(QString::number(isoSpacingLineEdit->text().toDouble()));
365     ySpacingLineEdit->setText(QString::number(isoSpacingLineEdit->text().toDouble()));
366     if (mDimension > 2)
367         zSpacingLineEdit->setText(QString::number(isoSpacingLineEdit->text().toDouble()));
368     ComputeNewSizeFromSpacing();
369 }
370 //====================================================================
371
372 //====================================================================
373 void vvToolResample::ComputeNewSizeFromIso() {
374     xSizeLineEdit->setText(QString::number(isoSizeLineEdit->text().toDouble()));
375     ySizeLineEdit->setText(QString::number(isoSizeLineEdit->text().toDouble()));
376     if (mDimension > 2)
377         zSizeLineEdit->setText(QString::number(isoSizeLineEdit->text().toDouble()));
378     ComputeNewSpacingFromSize();
379 }
380 //====================================================================
381
382 //====================================================================
383 void vvToolResample::UpdateInterpolation() {
384     if (interpolationComboBox->currentText() == "BSpline") {
385         bSplineLabel->show();
386         bSplineOrderSpinBox->show();
387         bLUTFactorLabel->hide();
388         bLUTSpinBox->hide();
389     }
390     else if (interpolationComboBox->currentText() == "Blut (faster BSpline)")   {
391         bSplineLabel->show();
392         bSplineOrderSpinBox->show();
393         bLUTFactorLabel->show();
394         bLUTSpinBox->show();
395     }
396     else {
397         bSplineLabel->hide();
398         bSplineOrderSpinBox->hide();
399         bLUTFactorLabel->hide();
400         bLUTSpinBox->hide();
401     }
402 }
403 //====================================================================
404
405 //====================================================================
406 void vvToolResample::UpdateGaussianFilter() {
407     if (gaussianFilterCheckBox->isChecked()) {
408         gaussianFilterLabel->show();
409         xGaussianLineEdit->show();
410         yGaussianLineEdit->show();
411         if (mDimension > 2)
412             zGaussianLineEdit->show();
413     }
414     else {
415         gaussianFilterLabel->hide();
416         xGaussianLineEdit->hide();
417         yGaussianLineEdit->hide();
418         zGaussianLineEdit->hide();
419     }
420 }
421 //====================================================================
422
423
424 //====================================================================
425 void vvToolResample::apply() {
426
427     // Get resampler options
428     std::vector<double> sigma;
429     sigma.push_back(xGaussianLineEdit->text().toDouble());
430     sigma.push_back(yGaussianLineEdit->text().toDouble());
431     if (mDimension > 2) sigma.push_back(zGaussianLineEdit->text().toDouble());
432
433     mFilter->SetOutputSize(mOutputSize);
434     mFilter->SetOutputSpacing(mOutputSpacing);
435     mFilter->SetInterpolationName(interpolationComboBox->currentText().toLower().toStdString());
436
437     if (interpolationComboBox->currentText() == "BSpline")
438         mFilter->SetBSplineOrder(bSplineOrderSpinBox->value());
439     else if (interpolationComboBox->currentText() == "Blut (faster BSpline)") {
440         mFilter->SetInterpolationName("blut");
441         mFilter->SetBSplineOrder(bSplineOrderSpinBox->value());
442         mFilter->SetBLUTSampling(bLUTSpinBox->value());
443     }
444     if (gaussianFilterCheckBox->isChecked())
445         mFilter->SetGaussianSigma(sigma);
446     //  mFilter->SetOutputFileName(OutputFileName.toStdString());
447     mFilter->SetDefaultPixelValue(defaultPixelValueLineEdit->text().toDouble());
448     mFilter->SetInputVVImage(mCurrentImage);
449
450     // Go !
451     mFilter->Update();
452     mOutput = mFilter->GetOutputVVImage();
453     AddImage(mOutput,GetOutputFileName());
454     close();
455 }
456 //====================================================================
457 std::string vvToolResample::GetOutputFileName()
458 {
459     QFileInfo info(QString(mCurrentSlicerManager->GetFileName().c_str()));
460     return (info.path().toStdString() + "/resampled_" + info.fileName().toStdString());
461 }
462