1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
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.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
20 #include "vvToolResample.h"
22 #include "vvToolCreator.h"
26 #include <QMessageBox>
29 #define COLUMN_IMAGE_NAME 7
31 ADD_TOOL(vvToolResample);
34 #define SetArgOptionString(OPTION, VALUE) \
36 OPTION##_given = VALUE.size(); \
37 OPTION##_arg = new char[VALUE.size()]; \
38 strcpy(OPTION##_arg, VALUE.c_str()); \
41 //------------------------------------------------------------------------------
42 vvToolResample::vvToolResample(vvMainWindowBase * parent, Qt::WindowFlags f):
43 vvToolWidgetBase(parent,f),
44 vvToolBase<vvToolResample>(parent),
47 Ui_vvToolResample::setupUi(mToolWidget);
49 mFilter = clitk::ResampleImageGenericFilter::New();
50 //mFilter = clitk::ImageResampleGenericFilter::New();
53 mInputFileFormat = "";
56 mCurrentSlicerManager=NULL;
59 mInputSpacing.resize(0);
60 mInputOrigin.resize(0);
61 mOutputSize.resize(0);
62 mOutputSpacing.resize(0);
64 xSizeLineEdit->setText("");
65 ySizeLineEdit->setText("");
66 zSizeLineEdit->setText("");
67 xSpacingLineEdit->setText("");
68 ySpacingLineEdit->setText("");
69 zSpacingLineEdit->setText("");
70 scaleSizeLineEdit->setText("");
71 scaleSpacingLineEdit->setText("");
73 sizeRadioButton->setChecked(0);
74 scaleSizeRadioButton->setChecked(0);
75 isoSizeRadioButton->setChecked(0);
76 spacingRadioButton->setChecked(0);
77 scaleSpacingRadioButton->setChecked(0);
78 isoSpacingRadioButton->setChecked(0);
80 gaussianFilterCheckBox->setCheckState(Qt::Unchecked);
82 xGaussianLineEdit->hide();
83 yGaussianLineEdit->hide();
84 zGaussianLineEdit->hide();
85 gaussianFilterLabel->hide();
88 bSplineOrderSpinBox->hide();
89 bLUTFactorLabel->hide();
94 qPalette.setColor(QPalette::Foreground, QColor(Qt::blue));
95 mInputFormatLabel->setPalette(qPalette);
96 mInputDimLabel->setPalette(qPalette);
97 mInputPixelTypeLabel->setPalette(qPalette);
98 mInputSizeLabel->setPalette(qPalette);
99 mInputSpacingLabel->setPalette(qPalette);
101 // Set how many inputs are needed for this tool
102 AddInputSelector("Select an image to resample", mFilter);
104 // Connect signals & slots
106 connect(sizeRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
107 connect(scaleSizeRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
108 connect(isoSizeRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
109 connect(spacingRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
110 connect(scaleSpacingRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
111 connect(isoSpacingRadioButton, SIGNAL(clicked()), this, SLOT(UpdateControlSizeAndSpacing()));
113 connect(xSizeLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSpacingFromSize()));
114 connect(ySizeLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSpacingFromSize()));
115 connect(zSizeLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSpacingFromSize()));
116 connect(xSpacingLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSizeFromSpacing()));
117 connect(ySpacingLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSizeFromSpacing()));
118 connect(zSpacingLineEdit, SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSizeFromSpacing()));
119 connect(scaleSizeLineEdit,SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSizeFromScale()));
120 connect(scaleSpacingLineEdit,SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSpacingFromScale()));
121 connect(isoSizeLineEdit,SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSizeFromIso()));
122 connect(isoSpacingLineEdit,SIGNAL(textEdited(QString)),this,SLOT(ComputeNewSpacingFromIso()));
124 connect(gaussianFilterCheckBox,SIGNAL(stateChanged(int)),this,SLOT(UpdateGaussianFilter()));
125 connect(interpolationComboBox,SIGNAL(currentIndexChanged(QString)),this,SLOT(UpdateInterpolation()));
127 //------------------------------------------------------------------------------
130 //------------------------------------------------------------------------------
131 void vvToolResample::Initialize()
133 SetToolName("Resample Image");
134 SetToolMenuName("Resample");
135 SetToolIconFilename(":/common/icons/resample.png");
136 SetToolTip("Resample image with various interpolation methods.");
138 //------------------------------------------------------------------------------
141 //------------------------------------------------------------------------------
142 void vvToolResample::InputIsSelected(vvSlicerManager* m)
145 mCurrentSlicerManager = m;
146 mCurrentImage = mCurrentSlicerManager->GetSlicer(0)->GetImage();
147 if (mCurrentImage.IsNull()) return;
148 mInputFileName = mCurrentSlicerManager->GetFileName().c_str();
150 // Set current information
151 mPixelType = mCurrentImage->GetScalarTypeAsITKString().c_str();
152 //ds ComponentType = mCurrentImageGetNumberOfScalarComponents();
153 mDimension = mCurrentImage->GetNumberOfDimensions();
155 // Copy size, spacing ...
156 mInputOrigin.resize(mDimension);
157 mInputSpacing.resize(mDimension);
158 mInputSize.resize(mDimension);
159 for (int i = 0; i < mDimension; i++) {
160 mInputOrigin[i] = mCurrentImage->GetOrigin()[i];
161 mInputSpacing[i] = mCurrentImage->GetSpacing()[i];
162 mInputSize[i] = mCurrentImage->GetSize()[i];
166 mInputFileFormat = itksys::SystemTools::GetFilenameLastExtension(mInputFileName.toStdString()).c_str();
169 mInputFormatLabel->setText(mInputFileFormat);
170 mInputSizeLabel->setText(GetVectorIntAsString(mInputSize));
171 mInputDimLabel->setText(QString::number(mDimension)+"D");
172 mInputSpacingLabel->setText(GetVectorDoubleAsString(mInputSpacing));
173 mInputPixelTypeLabel->setText(mPixelType);
174 mInputMemoryLabel->setText(GetSizeInBytes(mInputSize));
177 scaleSizeRadioButton->setChecked(true);
178 UpdateControlSizeAndSpacing();
179 scaleSizeLineEdit->setText("100");
180 ComputeNewSizeFromScale();
185 //------------------------------------------------------------------------------
188 //------------------------------------------------------------------------------
189 void vvToolResample::UpdateOutputInfo()
191 mOutputSizeLabel->setText(GetVectorIntAsString(mOutputSize));
192 mOutputSpacingLabel->setText(GetVectorDoubleAsString(mOutputSpacing));
193 mOutputMemoryLabel->setText(GetSizeInBytes(mOutputSize));
195 //------------------------------------------------------------------------------
198 //------------------------------------------------------------------------------
199 QString vvToolResample::GetSizeInBytes(std::vector<int> & size)
202 for (unsigned int i=0; i<size.size(); i++) t *= size[i];
203 t *= mCurrentImage->GetScalarSize()*mCurrentImage->GetNumberOfScalarComponents();
204 QString result = QString::number(t);
205 result += " bytes (";
206 if (t > 1000000000) {
208 result += QString::number(t);
210 } else if (t > 1000000) {
212 result += QString::number(t);
214 } else if (t > 1000) {
216 result += QString::number(t);
218 } else result += ")";
221 //------------------------------------------------------------------------------
224 //------------------------------------------------------------------------------
225 QString vvToolResample::GetVectorDoubleAsString(std::vector<double> vectorDouble)
228 for (unsigned int i= 0; i<vectorDouble.size(); i++) {
231 result += QString::number(vectorDouble[i]);
235 //------------------------------------------------------------------------------
238 //------------------------------------------------------------------------------
239 QString vvToolResample::GetVectorIntAsString(std::vector<int> vectorInt)
242 for (unsigned int i= 0; i<vectorInt.size(); i++) {
245 result += QString::number(vectorInt[i]);
249 //------------------------------------------------------------------------------
252 //------------------------------------------------------------------------------
253 void vvToolResample::FillSizeEdit(std::vector<int> size)
255 xSizeLineEdit->setText(QString::number(size[0]));
256 ySizeLineEdit->setText(QString::number(size[1]));
258 zSizeLineEdit->setText(QString::number(size[2]));
260 //------------------------------------------------------------------------------
263 //------------------------------------------------------------------------------
264 void vvToolResample::FillSpacingEdit(std::vector<double> spacing)
266 xSpacingLineEdit->setText(QString::number(spacing[0]));
267 ySpacingLineEdit->setText(QString::number(spacing[1]));
268 if (spacing.size() > 2)
269 zSpacingLineEdit->setText(QString::number(spacing[2]));
271 //------------------------------------------------------------------------------
274 //------------------------------------------------------------------------------
275 void vvToolResample::UpdateOutputSizeAndSpacing()
277 mOutputSize.resize(mDimension);
278 mOutputSize = mInputSize;
279 mOutputSpacing.resize(mDimension);
280 mOutputSpacing = mInputSpacing;
281 mOutputSize[0] = (int)xSizeLineEdit->text().toDouble();
282 mOutputSize[1] = (int)ySizeLineEdit->text().toDouble();
284 mOutputSize[2] = (int)zSizeLineEdit->text().toDouble();
286 mOutputSpacing[0] = xSpacingLineEdit->text().toDouble();
287 mOutputSpacing[1] = ySpacingLineEdit->text().toDouble();
289 mOutputSpacing[2] = zSpacingLineEdit->text().toDouble();
293 //------------------------------------------------------------------------------
296 //------------------------------------------------------------------------------
297 void vvToolResample::UpdateControlSizeAndSpacing()
299 scaleSizeLineEdit->setText("");
300 scaleSpacingLineEdit->setText("");
301 isoSizeLineEdit->setText("");
302 isoSpacingLineEdit->setText("");
304 xSizeLineEdit->setReadOnly(1);
305 ySizeLineEdit->setReadOnly(1);
306 zSizeLineEdit->setReadOnly(1);
307 scaleSizeLineEdit->setReadOnly(1);
308 isoSizeLineEdit->setReadOnly(1);
310 xSpacingLineEdit->setReadOnly(1);
311 ySpacingLineEdit->setReadOnly(1);
312 zSpacingLineEdit->setReadOnly(1);
313 scaleSpacingLineEdit->setReadOnly(1);
314 isoSpacingLineEdit->setReadOnly(1);
316 if (sizeRadioButton->isChecked()) {
317 xSizeLineEdit->setReadOnly(0);
318 ySizeLineEdit->setReadOnly(0);
320 zSizeLineEdit->setReadOnly(0);
322 if (spacingRadioButton->isChecked()) {
323 xSpacingLineEdit->setReadOnly(0);
324 ySpacingLineEdit->setReadOnly(0);
326 zSpacingLineEdit->setReadOnly(0);
327 } else if (scaleSizeRadioButton->isChecked())
328 scaleSizeLineEdit->setReadOnly(0);
329 else if (scaleSpacingRadioButton->isChecked())
330 scaleSpacingLineEdit->setReadOnly(0);
331 else if (isoSizeRadioButton->isChecked())
332 isoSizeLineEdit->setReadOnly(0);
333 else if (isoSpacingRadioButton->isChecked())
334 isoSpacingLineEdit->setReadOnly(0);
337 //------------------------------------------------------------------------------
340 //------------------------------------------------------------------------------
341 void vvToolResample::ComputeNewSpacingFromSize()
343 double newSpacing = mInputSpacing[0]*mInputSize[0];
344 xSpacingLineEdit->setText(QString::number(newSpacing/xSizeLineEdit->text().toDouble()));
345 newSpacing = mInputSpacing[1]*mInputSize[1];
346 ySpacingLineEdit->setText(QString::number(newSpacing/ySizeLineEdit->text().toDouble()));
347 if (mDimension > 2) {
348 newSpacing = mInputSpacing[2]*mInputSize[2];
349 zSpacingLineEdit->setText(QString::number(newSpacing/zSizeLineEdit->text().toDouble()));
351 UpdateOutputSizeAndSpacing();
353 //------------------------------------------------------------------------------
356 //------------------------------------------------------------------------------
357 void vvToolResample::ComputeNewSizeFromSpacing()
359 double newSize = mInputSpacing[0]*mInputSize[0];
360 xSizeLineEdit->setText(QString::number(newSize/xSpacingLineEdit->text().toDouble()));
361 newSize = mInputSpacing[1]*mInputSize[1];
362 ySizeLineEdit->setText(QString::number(newSize/ySpacingLineEdit->text().toDouble()));
363 if (mDimension > 2) {
364 newSize = mInputSpacing[2]*mInputSize[2];
365 zSizeLineEdit->setText(QString::number(newSize/zSpacingLineEdit->text().toDouble()));
367 UpdateOutputSizeAndSpacing();
369 //------------------------------------------------------------------------------
372 //------------------------------------------------------------------------------
373 void vvToolResample::ComputeNewSpacingFromScale()
375 xSpacingLineEdit->setText(QString::number(mInputSpacing[0]*scaleSpacingLineEdit->text().toDouble()/100));
376 ySpacingLineEdit->setText(QString::number(mInputSpacing[1]*scaleSpacingLineEdit->text().toDouble()/100));
378 zSpacingLineEdit->setText(QString::number(mInputSpacing[2]*scaleSpacingLineEdit->text().toDouble()/100));
379 ComputeNewSizeFromSpacing();
381 //------------------------------------------------------------------------------
384 //------------------------------------------------------------------------------
385 void vvToolResample::ComputeNewSizeFromScale()
387 xSizeLineEdit->setText(QString::number(mInputSize[0]*scaleSizeLineEdit->text().toDouble()/100));
388 ySizeLineEdit->setText(QString::number(mInputSize[1]*scaleSizeLineEdit->text().toDouble()/100));
390 zSizeLineEdit->setText(QString::number(mInputSize[2]*scaleSizeLineEdit->text().toDouble()/100));
391 ComputeNewSpacingFromSize();
393 //------------------------------------------------------------------------------
396 //------------------------------------------------------------------------------
397 void vvToolResample::ComputeNewSpacingFromIso()
399 xSpacingLineEdit->setText(QString::number(isoSpacingLineEdit->text().toDouble()));
400 ySpacingLineEdit->setText(QString::number(isoSpacingLineEdit->text().toDouble()));
402 zSpacingLineEdit->setText(QString::number(isoSpacingLineEdit->text().toDouble()));
403 ComputeNewSizeFromSpacing();
405 //------------------------------------------------------------------------------
408 //------------------------------------------------------------------------------
409 void vvToolResample::ComputeNewSizeFromIso()
411 xSizeLineEdit->setText(QString::number(isoSizeLineEdit->text().toDouble()));
412 ySizeLineEdit->setText(QString::number(isoSizeLineEdit->text().toDouble()));
414 zSizeLineEdit->setText(QString::number(isoSizeLineEdit->text().toDouble()));
415 ComputeNewSpacingFromSize();
417 //------------------------------------------------------------------------------
420 //------------------------------------------------------------------------------
421 void vvToolResample::UpdateInterpolation()
423 if (interpolationComboBox->currentText() == "BSpline") {
424 bSplineLabel->show();
425 bSplineOrderSpinBox->show();
426 bLUTFactorLabel->hide();
428 } else if (interpolationComboBox->currentText() == "Blut (faster BSpline)") {
429 bSplineLabel->show();
430 bSplineOrderSpinBox->show();
431 bLUTFactorLabel->show();
434 bSplineLabel->hide();
435 bSplineOrderSpinBox->hide();
436 bLUTFactorLabel->hide();
440 //------------------------------------------------------------------------------
443 //------------------------------------------------------------------------------
444 void vvToolResample::UpdateGaussianFilter()
446 if (gaussianFilterCheckBox->isChecked()) {
447 gaussianFilterLabel->show();
448 xGaussianLineEdit->show();
449 yGaussianLineEdit->show();
451 zGaussianLineEdit->show();
453 gaussianFilterLabel->hide();
454 xGaussianLineEdit->hide();
455 yGaussianLineEdit->hide();
456 zGaussianLineEdit->hide();
459 //------------------------------------------------------------------------------
462 //------------------------------------------------------------------------------
463 void vvToolResample::apply()
466 // Get resampler options
467 std::vector<double> sigma;
468 sigma.push_back(xGaussianLineEdit->text().toDouble());
469 sigma.push_back(yGaussianLineEdit->text().toDouble());
470 if (mDimension > 2) sigma.push_back(zGaussianLineEdit->text().toDouble());
471 if (mDimension == 4) sigma.push_back(0.01); //FIXME Don't filter along the temporal direction
474 clitk::ResampleImageGenericFilter::ArgsInfoType mArgsInfo;
476 // Initialisation to default
477 cmdline_parser_clitkResampleImage_init(&mArgsInfo);
478 mArgsInfo.input_given = 0;
479 mArgsInfo.output_given = 0;
481 // Size and spacing options
482 mArgsInfo.size_given = mDimension;
483 mArgsInfo.spacing_given = mDimension;
484 mArgsInfo.size_arg = new int[mDimension];
485 mArgsInfo.spacing_arg = new float[mDimension];
486 for(int i=0; i<mDimension; i++) {
487 mArgsInfo.size_arg[i] = mOutputSize[i];
488 mArgsInfo.spacing_arg[i] = mOutputSpacing[i];
491 if (sizeRadioButton->isChecked() ||
492 scaleSizeRadioButton->isChecked() ||
493 isoSizeRadioButton->isChecked()) {
494 mArgsInfo.spacing_given=0;
496 if (spacingRadioButton->isChecked() ||
497 scaleSpacingRadioButton->isChecked() ||
498 isoSpacingRadioButton->isChecked()) {
499 mArgsInfo.size_given=0;
502 // Interpolation options
503 std::string interp = interpolationComboBox->currentText().toLower().toStdString();
504 if (interp == "nn") SetArgOptionString(mArgsInfo.interp, std::string("nn"));
505 if (interp == "linear") SetArgOptionString(mArgsInfo.interp, std::string("linear"));
506 if (interp == "bspline") SetArgOptionString(mArgsInfo.interp, std::string("bspline"));
507 if (interp == "blut (faster bspline)") SetArgOptionString(mArgsInfo.interp, std::string("blut"));
508 if (interp == "windowed sinc") SetArgOptionString(mArgsInfo.interp, std::string("windowed sinc"));
510 if (interp == "bspline") {
511 mArgsInfo.order_arg = bSplineOrderSpinBox->value();
514 if (interp == "blut (faster bspline)") {
515 mArgsInfo.order_arg = bSplineOrderSpinBox->value();
516 mArgsInfo.sampling_arg = bLUTSpinBox->value();
521 if (gaussianFilterCheckBox->isChecked()) {
522 mArgsInfo.gauss_given = mDimension;
523 mArgsInfo.gauss_arg = new float[mDimension];
524 for(int i=0; i<mDimension; i++) {
525 mArgsInfo.gauss_arg[i] = sigma[i];
528 mArgsInfo.default_arg = defaultPixelValueLineEdit->text().toDouble();
531 mArgsInfo.thread_arg = QThread::idealThreadCount();
532 mArgsInfo.thread_given = 1;
534 // Set options to filter
535 mFilter->SetArgsInfo(mArgsInfo);
536 mFilter->SetInputVVImage(mCurrentImage);
540 mOutput = mFilter->GetOutputVVImage();
541 AddImage(mOutput,GetOutputFileName());
544 //------------------------------------------------------------------------------
547 //------------------------------------------------------------------------------
548 std::string vvToolResample::GetOutputFileName()
550 QFileInfo info(QString(mCurrentSlicerManager->GetFileName().c_str()));
551 return (info.path().toStdString() + "/resampled_" + info.fileName().toStdString());
553 //------------------------------------------------------------------------------