]> Creatis software - clitk.git/blob - vv/vvDeformationDialog.cxx
Fixed compilation with VC++ 9
[clitk.git] / vv / vvDeformationDialog.cxx
1 #include <vector>
2 #include <QComboBox>
3 #include <QThread>
4 #include <QFileDialog>
5 #include <QProgressDialog>
6 #include <QMessageBox>
7 #include <QFileInfo>
8
9 #include <itkImage.h>
10 #include <itkWarpImageFilter.h>
11 #include <itkJoinSeriesImageFilter.h>
12 #include <itkImageFileReader.h>
13 #include <itkSubtractImageFilter.h>
14 #include <itkDisplacementFieldJacobianDeterminantFilter.h>
15
16
17 #include <vtksys/SystemTools.hxx>
18 #include <itksys/SystemTools.hxx>
19
20 #include "clitkCommon.h"
21
22 #include "vvDeformationDialog.h"
23 #include "vvDeformableRegistration.h"
24 #include "vvSlicer.h"
25 #include "vvToITK.h"
26 #include "vvFromITK.h"
27 #include "vvSlicerManager.h"
28
29 vvSlicerManager * vvDeformationDialog::GetSelectedSlicer() const
30 {
31     return mSlicerManagers[inputSequenceBox->currentIndex()];
32 }
33
34 int vvDeformationDialog::GetReferenceFrameIndex() const
35 {
36     return refImageSlider->value();
37 }
38
39 vvDeformationDialog::vvDeformationDialog(int initialSlicer,const std::vector<vvSlicerManager*>& slicerManagers)
40         : mSlicerManagers(slicerManagers)
41 {
42     setupUi(this);
43     connect(this,SIGNAL(accepted()),this,SLOT(computeDeformationField()));
44     for (unsigned int i=0;i<slicerManagers.size();i++)
45         inputSequenceBox->addItem(vtksys::SystemTools::GetFilenameName(slicerManagers[i]->GetFileName()).c_str());
46     connect(inputSequenceBox,SIGNAL(currentIndexChanged(int)),this,SLOT(resetSlider(int)));
47     connect(refImageSlider,SIGNAL(valueChanged(int)),this,SLOT(updateSliderLabel(int)));
48     connect(outputPushButton, SIGNAL(clicked()), this, SLOT(selectOutputFile()));
49     inputSequenceBox->setCurrentIndex(initialSlicer);
50     resetSlider(initialSlicer);
51
52     //Compute ideal number of threads and update dialog accordingly
53     int best_thread=QThread::idealThreadCount();
54     threadSpin->setValue(best_thread);
55
56 }
57
58 void vvDeformationDialog::selectOutputFile()
59 {
60     QString Extensions = "MHD Images( *.mhd);;";
61     QString fileName = QFileDialog::getSaveFileName(this,
62                        tr("Save As"),
63                        itksys::SystemTools::GetFilenamePath(
64                            mSlicerManagers[inputSequenceBox->currentIndex()]->GetFileName()).c_str(),
65                        Extensions);
66     outputLineEdit->setText(fileName);
67 }
68
69 void vvDeformationDialog::updateSliderLabel(int refimage)
70 {
71     QString count;
72     count.setNum(refimage); //Normal people start counting at 1...
73     QString newlabel="Reference Image (";
74     newlabel+=count;
75     newlabel+=")";
76     refImageLabel->setText(newlabel);
77 }
78
79 void vvDeformationDialog::resetSlider(int slicer_index)
80 {
81     refImageSlider->setRange(0,mSlicerManagers[slicer_index]->GetSlicer(0)->GetImage()->GetSize()[3]-1);
82     int refimage=mSlicerManagers[slicer_index]->GetSlicer(0)->GetTSlice();
83     refImageSlider->setSliderPosition(refimage);
84     updateSliderLabel(refimage);
85 }
86
87 void vvDeformationDialog::computeDeformationField() {
88     vvImage::Pointer sequence=mSlicerManagers[inputSequenceBox->currentIndex()]->GetSlicer(0)->GetImage();
89     vtkImageData * first_image = sequence->GetVTKImages()[0];
90     if (!sequence->IsTimeSequence())
91     {
92         this->setResult(QDialog::Rejected);
93         QMessageBox::warning(this,tr("Image type error"), tr("Deformable image registration only makes sense on time sequences."));
94     }
95     else if ((first_image->GetSpacing()[0] != first_image->GetSpacing()[1]) || (first_image->GetSpacing()[0] != first_image->GetSpacing()[2]))
96     {
97         this->setResult(QDialog::Rejected);
98         QMessageBox::warning(this,tr("Image type error"), tr("Deformable registration only works well with isotropic voxels. Please resample the image."));
99         return;
100     }
101     else {
102         bool aborted=false;
103         QProgressDialog progress(this);
104         QProgressDialog cancel(this);
105         cancel.setLabelText("Canceling, please wait...");
106         cancel.setCancelButtonText(0);
107         cancel.hide();
108         //1 step per registration plus one for each of the image conversions
109         progress.setMaximum(mSlicerManagers[inputSequenceBox->currentIndex()]
110                             ->GetSlicer(0)->GetImage()->GetSize()[3]+2);
111         progress.setLabelText("Computing deformation model...");
112         progress.setMinimumDuration(0);
113         progress.setWindowModality(Qt::WindowModal);
114         progress.setCancelButtonText("Cancel");
115         qApp->processEvents();
116         QFileInfo info(outputLineEdit->text().toStdString().c_str());
117         if (info.isRelative()) //this is a bit hackish, but should work
118         {
119             QFileInfo im_info(mSlicerManagers[inputSequenceBox->currentIndex()]->GetFileName().c_str());
120             outputLineEdit->setText((im_info.path().toStdString() + "/" + outputLineEdit->text().toStdString()).c_str());
121         }
122         vvDeformableRegistration registrator(sequence,refImageSlider->value(), iterSpin->value(),threadSpin->value(), alphaSpin->value(), sigmaSpin->value(),outputLineEdit->text().toStdString(),stopSpin->value());
123         registrator.start();
124         while (!registrator.isFinished())
125         {
126             if (progress.wasCanceled() && !aborted)
127             {
128                 this->setResult(QDialog::Rejected);
129                 registrator.abort();
130                 aborted=true;
131                 progress.hide();
132                 cancel.show();
133             }
134             if (!aborted)
135                 progress.setValue(registrator.getProgress());
136             qApp->processEvents();
137             registrator.wait(50);
138         }
139         if (!aborted)
140         {
141             mOutput=registrator.getOutput();
142         }
143     }
144 }