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://oncora1.lyon.fnclcc.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 "vvToolExtractLung.h"
21 #include "vvToolStructureSetManager.h"
23 #include "vvImageReader.h"
24 #include "vvImageWriter.h"
25 #include "vvLabelImageLoaderWidget.h"
26 #include "vvThreadedFilter.h"
29 #include <QMessageBox>
31 //------------------------------------------------------------------------------
32 // Create the tool and automagically (I like this word) insert it in
33 // the main window menu.
34 ADD_TOOL(vvToolExtractLung);
35 //------------------------------------------------------------------------------
38 //------------------------------------------------------------------------------
39 vvToolExtractLung::vvToolExtractLung(vvMainWindowBase * parent, Qt::WindowFlags f):
40 vvToolWidgetBase(parent,f),
41 vvToolBase<vvToolExtractLung>(parent),
42 Ui::vvToolExtractLung()
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()));
52 mArgsInfo = new ArgsInfoType;
53 cmdline_parser_clitkExtractLung_init(mArgsInfo);
55 m_IsThreadInterrupted = false;
57 // Create a new ExtractLung filter
58 mFilter = new FilterType; // used in AddInputSelector
61 AddInputSelector("Select CT thorax image", mFilter);
63 //------------------------------------------------------------------------------
66 //------------------------------------------------------------------------------
67 vvToolExtractLung::~vvToolExtractLung()
70 //------------------------------------------------------------------------------
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");
82 //------------------------------------------------------------------------------
85 //------------------------------------------------------------------------------
86 void vvToolExtractLung::InputIsSelected(vvSlicerManager *m)
89 HideInputSelector(); // splitter
90 mToolInputSelectionWidget->hide();
91 mCurrentSlicerManager = m;
92 mCurrentImage = m->GetImage();
93 mMaskLoaderBox->setEnabled(true);
94 mLabelInput->setText(m->GetFileName().c_str());
96 //------------------------------------------------------------------------------
99 //------------------------------------------------------------------------------
100 void vvToolExtractLung::PatientMaskInputIsSelected()
102 // Get Patient mask and BG value
103 mPatient = mPatientMaskInputWidget->GetImage();
104 mPatientBackgroundValue = mPatientMaskInputWidget->GetBackgroundValue();
106 // Check patient dimension
107 if (mPatient->GetNumberOfDimensions() != 3) {
108 QMessageBox::information(this,tr("*Error*"), "Mask image must be 3D");
112 mMaskLoaderBox->setEnabled(false);
113 mOptionsBox->setEnabled(true);
115 //------------------------------------------------------------------------------
118 //------------------------------------------------------------------------------
119 void vvToolExtractLung::SetGUIFromArgsInfo()
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);
127 mAirLowerThresholdSlider->SetText("Lower threshold for air");
128 mAirLowerThresholdSlider->SetMinimum(-1200);
129 mAirLowerThresholdSlider->SetMaximum(2000);
130 mAirLowerThresholdSlider->SetValue(mArgsInfo->lower_arg);
133 //------------------------------------------------------------------------------
136 //------------------------------------------------------------------------------
137 void vvToolExtractLung::GetArgsInfoFromGUI()
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;
149 mArgsInfo->upper_arg = mAirUpperThresholdSlider->GetValue();
150 mArgsInfo->lower_arg = mAirLowerThresholdSlider->GetValue();
151 if (mRadioButtonLowerThan->isChecked()) mArgsInfo->lower_given = 1;
153 //------------------------------------------------------------------------------
156 //------------------------------------------------------------------------------
157 void vvToolExtractLung::apply()
159 // Change cursor to wait
160 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
162 // Read options from GUI and put it in the ArgsInfo struct
163 GetArgsInfoFromGUI();
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.");
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);
183 // Created threaded execution
184 vvThreadedFilter thread;
185 connect(&thread, SIGNAL(ThreadInterrupted()), this, SLOT(ThreadInterrupted()));
186 thread.SetFilter(mFilter);
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();
200 disconnect(&thread, SIGNAL(ThreadInterrupted()), this, SLOT(ThreadInterrupted()));
202 // Check error during filter
203 // if (mFilter->HasError()) {
204 QApplication::restoreOverrideCursor();
205 QMessageBox::information(this,tr("Error"), e.what());//mFilter->GetLastError().c_str());
211 std::vector<vvImage::Pointer> output = mFilter->GetOutputVVImages();
212 if (output.size() == 0) {
213 std::cerr << "Error : no output ?" << std::endl;
214 QApplication::restoreOverrideCursor();
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());
225 vvToolStructureSetManager::AddImage(mCurrentSlicerManager, "Right lung", lung, 1, false); // Right is greater than Left
226 vvToolStructureSetManager::AddImage(mCurrentSlicerManager, "Left lung", lung, 2, false);
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());
235 vvToolStructureSetManager::AddImage(mCurrentSlicerManager, "Trachea", trachea, 0);
239 QApplication::restoreOverrideCursor();
242 //------------------------------------------------------------------------------
245 //------------------------------------------------------------------------------
246 bool vvToolExtractLung::close()
248 return vvToolWidgetBase::close();
250 //------------------------------------------------------------------------------
253 //------------------------------------------------------------------------------
254 void vvToolExtractLung::ThreadInterrupted()
256 m_IsThreadInterrupted = true;
258 //------------------------------------------------------------------------------