]> Creatis software - clitk.git/blob - vv/vvToolExtractLung.cxx
fb11061ddafe4e8447285daee98c7f01006bd8f2
[clitk.git] / vv / vvToolExtractLung.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 "vvToolExtractLung.h"
21 #include "vvToolStructureSetManager.h"
22 #include "vvSlicer.h"
23 #include "vvImageReader.h"
24 #include "vvImageWriter.h"
25 #include "vvLabelImageLoaderWidget.h"
26 #include "vvThreadedFilter.h"
27
28 // Qt
29 #include <QMessageBox>
30
31 //------------------------------------------------------------------------------
32 // Create the tool and automagically (I like this word) insert it in
33 // the main window menu.
34 ADD_TOOL(vvToolExtractLung);
35 //------------------------------------------------------------------------------
36
37
38 //------------------------------------------------------------------------------
39 vvToolExtractLung::vvToolExtractLung(vvMainWindowBase * parent, Qt::WindowFlags f):
40   vvToolWidgetBase(parent,f),
41   vvToolBase<vvToolExtractLung>(parent),
42   Ui::vvToolExtractLung()
43 {
44   // GUI
45   Ui_vvToolExtractLung::setupUi(mToolWidget);
46   mMaskLoaderBox->setEnabled(false);
47   mOptionsBox->setEnabled(false);
48   mPatientMaskInputWidget->SetText("Patient mask");
49   connect(mPatientMaskInputWidget, SIGNAL(accepted()), this, SLOT(PatientMaskInputIsSelected()));
50
51   // Default values
52   mArgsInfo = new ArgsInfoType;
53   cmdline_parser_clitkExtractLung_init(mArgsInfo);
54   SetGUIFromArgsInfo();
55   m_IsThreadInterrupted = false;
56
57   // Create a new ExtractLung filter
58   mFilter = new FilterType;  // used in AddInputSelector
59
60   // Add input selector
61   AddInputSelector("Select CT thorax image", mFilter);
62 }
63 //------------------------------------------------------------------------------
64
65
66 //------------------------------------------------------------------------------
67 vvToolExtractLung::~vvToolExtractLung()
68 {
69 }
70 //------------------------------------------------------------------------------
71
72
73 //------------------------------------------------------------------------------
74 void vvToolExtractLung::Initialize() {
75   SetToolName("ExtractLung");
76   SetToolMenuName("Extract lungs");
77   SetToolIconFilename(":/common/icons/lung-overlay.png");
78   SetToolTip("Extract lung mask from thorax CT.");
79   SetToolExperimental(true);
80   //  SetToolInMenu("Segmentation");
81 }
82 //------------------------------------------------------------------------------
83
84
85 //------------------------------------------------------------------------------
86 void vvToolExtractLung::InputIsSelected(vvSlicerManager *m)
87 {
88   // Hide selector
89   HideInputSelector(); // splitter
90   mToolInputSelectionWidget->hide();
91   mCurrentSlicerManager = m;
92   mCurrentImage = m->GetImage();
93   mMaskLoaderBox->setEnabled(true);
94   mLabelInput->setText(m->GetFileName().c_str());
95 }
96 //------------------------------------------------------------------------------
97
98
99 //------------------------------------------------------------------------------
100 void vvToolExtractLung::PatientMaskInputIsSelected()
101 {
102   // Get Patient mask and BG value
103   mPatient = mPatientMaskInputWidget->GetImage();  
104   mPatientBackgroundValue = mPatientMaskInputWidget->GetBackgroundValue();
105   
106   // Check patient dimension
107   if (mPatient->GetNumberOfDimensions() != 3) {
108     QMessageBox::information(this,tr("*Error*"), "Mask image must be 3D");
109     return;
110   }
111    
112   mMaskLoaderBox->setEnabled(false);
113   mOptionsBox->setEnabled(true);
114 }
115 //------------------------------------------------------------------------------
116
117
118 //------------------------------------------------------------------------------
119 void vvToolExtractLung::SetGUIFromArgsInfo() 
120 {
121   mAirUpperThresholdSlider->SetText("Upper threshold for air");
122   mAirUpperThresholdSlider->SetMinimum(-1200);
123   mAirUpperThresholdSlider->SetMaximum(2000);
124   DD(mArgsInfo->upper_arg);
125   mAirUpperThresholdSlider->SetValue(mArgsInfo->upper_arg);
126
127   mAirLowerThresholdSlider->SetText("Lower threshold for air");
128   mAirLowerThresholdSlider->SetMinimum(-1200);
129   mAirLowerThresholdSlider->SetMaximum(2000);
130   mAirLowerThresholdSlider->SetValue(mArgsInfo->lower_arg);
131
132 }
133 //------------------------------------------------------------------------------
134
135
136 //------------------------------------------------------------------------------
137 void vvToolExtractLung::GetArgsInfoFromGUI() 
138 {
139   // mArgsInfo->patientBG_arg = mPatientMaskInputWidget->GetBackgroundValue();
140   mArgsInfo->verboseOption_flag = true; // DEBUG. TO CHANGE
141   mArgsInfo->verboseStep_flag = true; // DEBUG. TO CHANGE
142   mArgsInfo->writeStep_flag = false;
143   mArgsInfo->input_given = 0;
144   // mArgsInfo->patient_given = 0;
145   mArgsInfo->output_given = 0;
146   mArgsInfo->outputTrachea_given = 0;
147   //  mArgsInfo->remove1_given = 0;
148   
149   mArgsInfo->upper_arg = mAirUpperThresholdSlider->GetValue();
150   mArgsInfo->lower_arg = mAirLowerThresholdSlider->GetValue();
151   if (mRadioButtonLowerThan->isChecked()) mArgsInfo->lower_given = 1;
152 }
153 //------------------------------------------------------------------------------
154
155
156 //------------------------------------------------------------------------------
157 void vvToolExtractLung::apply() 
158 {
159   // Change cursor to wait
160   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
161   
162   // Read options from GUI and put it in the ArgsInfo struct
163   GetArgsInfoFromGUI();
164   
165   // Check options
166   if (mArgsInfo->lower_given) {
167     if (mArgsInfo->lower_arg > mArgsInfo->upper_arg) {    
168       QApplication::restoreOverrideCursor(); 
169       QMessageBox::information(this,tr("Error"), "Lower threshold cannot be greater than upper threshold.");
170       return;
171     }
172   }
173
174   // Create new filter
175   if (mFilter) delete mFilter;
176   mFilter = new FilterType;  // needed when thread cancel the filter
177   // mFilter->StopOnErrorOff();
178   //  mFilter->SetIOVerbose(true);
179   mFilter->AddInputVVImage(mCurrentImage); // CT
180   mFilter->AddInputVVImage(mPatient); // patient mask
181   mFilter->SetArgsInfo(*mArgsInfo);
182
183   // Created threaded execution
184   vvThreadedFilter thread;
185   connect(&thread, SIGNAL(ThreadInterrupted()), this, SLOT(ThreadInterrupted()));
186   thread.SetFilter(mFilter);
187
188   try {
189     thread.Update();
190   }
191   catch(std::runtime_error e) {
192     DD("Error exception handling");
193     DD(m_IsThreadInterrupted);
194   // Check if the thread has been canceled. In this case, return
195   if (m_IsThreadInterrupted) {
196     m_IsThreadInterrupted = false;
197     QApplication::restoreOverrideCursor(); 
198     return;
199   }
200   disconnect(&thread, SIGNAL(ThreadInterrupted()), this, SLOT(ThreadInterrupted()));
201     
202   // Check error during filter
203   // if (mFilter->HasError()) {
204     QApplication::restoreOverrideCursor();
205     QMessageBox::information(this,tr("Error"), e.what());//mFilter->GetLastError().c_str());
206     return;
207   // }
208   } // end exception
209   
210   // Get output
211   std::vector<vvImage::Pointer> output = mFilter->GetOutputVVImages();
212   if (output.size() == 0) {
213     std::cerr << "Error : no output ?" << std::endl;
214     QApplication::restoreOverrideCursor();
215     close();
216     return;
217   }
218   
219   // Set Lung into VV
220   vvImage::Pointer lung = output[0];
221   std::ostringstream osstream;
222   osstream << "Lung_" << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
223   vvSlicerManager * v = AddImage(lung,osstream.str());
224   v->SetPreset(5);
225   vvToolStructureSetManager::AddImage(mCurrentSlicerManager, "Right lung", lung, 1, false); // Right is greater than Left
226   vvToolStructureSetManager::AddImage(mCurrentSlicerManager, "Left lung", lung, 2, false);  
227
228   // Set trachea into VV
229   if (output.size() == 2) {
230     vvImage::Pointer trachea = output[1];
231     std::ostringstream osstream;
232     osstream << "Trachea_" << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
233     vvSlicerManager * v = AddImage(trachea,osstream.str());
234     v->SetPreset(5);
235     vvToolStructureSetManager::AddImage(mCurrentSlicerManager, "Trachea", trachea, 0);
236   }
237
238   // End
239   QApplication::restoreOverrideCursor();
240   close();
241 }
242 //------------------------------------------------------------------------------
243
244
245 //------------------------------------------------------------------------------
246 bool vvToolExtractLung::close()
247 {
248   return vvToolWidgetBase::close();
249 }
250 //------------------------------------------------------------------------------
251
252
253 //------------------------------------------------------------------------------
254 void vvToolExtractLung::ThreadInterrupted() 
255
256   m_IsThreadInterrupted = true; 
257 }
258 //------------------------------------------------------------------------------
259