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