]> Creatis software - clitk.git/blob - vv/vvToolHistogram.cxx
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
[clitk.git] / vv / vvToolHistogram.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://www.centreleonberard.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 #include <QFileDialog>
20 #include <QShortcut>
21
22 #include <algorithm>
23
24 // vv
25 #include "vvToolHistogram.h"
26 #include "vvProgressDialog.h"
27 #include "vvSlicerManager.h"
28 #include "vvSlicer.h"
29 #include "vvToolInputSelectorWidget.h"
30
31 // vtk
32 #include <vtkAxis.h>
33 #include <vtkImageActor.h>
34 #include <vtkCamera.h>
35 #include <vtkImageClip.h>
36 #include <vtkRenderWindow.h>
37 #include <vtkChartXY.h>
38 #include <vtkPlot.h>
39 #include <vtkRendererCollection.h>
40 #include <vtkRenderer.h>
41
42 #include <vtkLine.h>
43 #include <vtkCellArray.h>
44 #include <vtkCellData.h>
45 #include <vtkPolyDataMapper.h>
46 #include <vtkProperty.h>
47 #include <vtkBox.h>
48 #include <vtkInformation.h>
49
50 #ifdef Q_OS_OSX
51 # include "vvOSXHelper.h"
52 #endif
53
54 //------------------------------------------------------------------------------
55 // Create the tool and automagically (I like this word) insert it in
56 // the main window menu.
57 ADD_TOOL(vvToolHistogram);
58 //------------------------------------------------------------------------------
59
60
61 //------------------------------------------------------------------------------
62 void vvToolHistogram::Initialize()
63
64   SetToolName("Histogram");
65   SetToolMenuName("Intensity Histogram");
66   SetToolIconFilename(":/common/icons/histogram.png");
67   SetToolTip("Display the histogram of the image.");
68   SetToolExperimental(false);
69 }
70 //------------------------------------------------------------------------------
71
72
73 //------------------------------------------------------------------------------
74 vvToolHistogram::vvToolHistogram(vvMainWindowBase * parent, Qt::WindowFlags f)
75   :vvToolWidgetBase(parent,f),
76    vvToolBase<vvToolHistogram>(parent),
77    Ui::vvToolHistogram()
78
79   // GUI Initialization
80   Ui_vvToolHistogram::setupUi(mToolWidget);
81
82   // Connect signals & slots
83   connect(mSaveHistogramButton, SIGNAL(clicked()), this, SLOT(SaveAs()));
84
85   // Initialize some widget
86   HistogramWidget->hide();
87     
88   mView = vtkSmartPointer<vtkContextView>::New();
89   vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
90   chart->SetAutoSize(false);
91   chart->SetRenderEmpty(true);
92   mView->GetScene()->AddItem(chart);
93   this->HistogramWidget->GetRenderWindow()->GetRenderers()->RemoveAllItems();
94   this->HistogramWidget->GetRenderWindow()->AddRenderer(mView->GetRenderer());
95   HistogramWidget->show();
96
97 #ifdef Q_OS_OSX
98   disableGLHiDPI(HistogramWidget->winId());
99 #endif
100
101   // Main filter
102   mFilter = clitk::HistogramImageGenericFilter::New();
103
104   // Set how many inputs are needed for this tool
105   AddInputSelector("Select one image", mFilter);
106 }
107 //------------------------------------------------------------------------------
108
109
110 //------------------------------------------------------------------------------
111 vvToolHistogram::~vvToolHistogram()
112
113 }
114 //------------------------------------------------------------------------------
115
116
117 //------------------------------------------------------------------------------
118 void vvToolHistogram::computeHistogram()
119 {
120     if (!mCurrentSlicerManager) close();
121     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
122     GetArgsInfoFromGUI();
123     HistogramWidget->hide();
124    
125     // Main filter
126     mFilter->SetInputVVImage(mCurrentImage);
127     mFilter->SetArgsInfo(mArgsInfo);
128     mFilter->Update();
129     
130     //Creation of the XY chart
131     vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
132     vtkSmartPointer<vtkFloatArray> arrX = vtkSmartPointer<vtkFloatArray>::New();
133     vtkSmartPointer<vtkFloatArray> arrY = vtkSmartPointer<vtkFloatArray>::New();
134     arrX = mFilter->GetArrayX();
135     arrY = mFilter->GetArrayY();
136     arrX->SetName("Intensity");
137     arrY->SetName("#Voxels");
138     
139     table->AddColumn(arrX);
140     table->AddColumn(arrY);
141     
142     mView->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
143  
144     vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
145     chart->SetAutoSize(true);
146     mView->GetScene()->ClearItems();
147     mView->GetScene()->AddItem(chart);
148     vtkPlot *line = chart->AddPlot(vtkChart::LINE);
149 #if VTK_MAJOR_VERSION <= 5
150     line->SetInput(table, 0, 1);
151 #else
152     line->SetInputData(table, 0, 1);
153 #endif
154     line->SetColor(0, 255, 0, 255);
155     line->SetWidth(1.0);
156     chart->GetAxis(vtkAxis::LEFT)->SetTitle("#Voxels");
157     chart->GetAxis(vtkAxis::BOTTOM)->SetTitle("Intensity");
158     
159     this->HistogramWidget->GetRenderWindow()->GetRenderers()->RemoveAllItems();
160     this->HistogramWidget->GetRenderWindow()->AddRenderer(mView->GetRenderer());
161     HistogramWidget->show();
162     
163     QApplication::restoreOverrideCursor();
164 }
165 //------------------------------------------------------------------------------
166
167
168 //------------------------------------------------------------------------------
169 void vvToolHistogram::RemoveVTKObjects()
170
171   if (mCurrentSlicerManager)
172   {
173     connect(mCurrentSlicerManager, SIGNAL(callAddLandmark(float,float,float,float)), mCurrentSlicerManager, SLOT(AddLandmark(float,float,float,float)));
174
175     mCurrentSlicerManager->Render();
176   }
177 }
178 //------------------------------------------------------------------------------
179
180
181 //------------------------------------------------------------------------------
182 bool vvToolHistogram::close()
183
184   //RemoveVTKObjects();
185
186   return vvToolWidgetBase::close();
187 }
188 //------------------------------------------------------------------------------
189
190
191 //------------------------------------------------------------------------------
192 void vvToolHistogram::closeEvent(QCloseEvent *event)
193
194   RemoveVTKObjects();
195   event->accept();
196 }
197 //------------------------------------------------------------------------------
198
199
200 //------------------------------------------------------------------------------
201 void vvToolHistogram::reject()
202
203   // DD("vvToolHistogram::reject");
204   RemoveVTKObjects();
205   return vvToolWidgetBase::reject();
206 }
207 //------------------------------------------------------------------------------
208
209
210 //------------------------------------------------------------------------------
211 void vvToolHistogram::InputIsSelected(vvSlicerManager * m)
212
213   mCurrentSlicerManager = m;
214
215   mSaveHistogramButton->setEnabled(true);
216   mTextFileName = "Histogram.txt";
217
218   computeHistogram();
219
220   disconnect(mCurrentSlicerManager, SIGNAL(callAddLandmark(float,float,float,float)), mCurrentSlicerManager, SLOT(AddLandmark(float,float,float,float)));
221 }
222 //------------------------------------------------------------------------------
223
224
225 //------------------------------------------------------------------------------
226 void vvToolHistogram::GetArgsInfoFromGUI()
227
228
229   /* //KEEP THIS FOR READING GGO FROM FILE
230      int argc=1;
231      std::string a = "toto";
232      char * const* argv = new char*;
233      //a.c_str();
234      struct cmdline_parser_params p;
235      p.check_required = 0;
236      int good = cmdline_parser_ext(argc, argv, &args_info, &p);
237      DD(good);
238   */
239   cmdline_parser_clitkHistogramImage_init(&mArgsInfo); // Initialisation to default
240
241   mArgsInfo.verbose_flag = false;
242
243   // Required (even if not used)
244   mArgsInfo.input_given = 0;
245   mArgsInfo.output_given = 0;
246
247   mArgsInfo.input_arg = new char;
248   mArgsInfo.output_arg = new char;
249
250 }
251 //------------------------------------------------------------------------------
252
253
254 //------------------------------------------------------------------------------
255 void vvToolHistogram::apply()
256
257   close();
258 }
259 //------------------------------------------------------------------------------
260
261
262 //------------------------------------------------------------------------------
263 void vvToolHistogram::SaveAs()
264
265   QStringList OutputListeFormat;
266   OutputListeFormat.clear();
267   OutputListeFormat.push_back(".txt");
268   
269   QString Extensions = "AllFiles(*.*)";
270   for (int i = 0; i < OutputListeFormat.count(); i++) {
271     Extensions += ";;Text File ( *";
272     Extensions += OutputListeFormat[i];
273     Extensions += ")";
274   }
275   QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), mTextFileName.c_str(), Extensions);
276   if (!fileName.isEmpty()) {
277     std::string fileformat = itksys::SystemTools::GetFilenameLastExtension(fileName.toStdString());
278     QString fileQFormat = fileformat.c_str();
279     if (OutputListeFormat.contains(fileformat.c_str()) || fileQFormat.isEmpty()) {
280         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
281         std::string action = "Saving";
282         vvProgressDialog progress("Saving "+fileName.toStdString());
283         qApp->processEvents();
284         
285         if (!mCurrentSlicerManager) {
286             close();
287             return;
288         }
289
290         // Output
291         mTextFileName = fileName.toStdString();
292         if (fileQFormat.isEmpty())
293             mTextFileName += ".txt";
294         ofstream fileOpen(mTextFileName.c_str(), std::ofstream::trunc);
295   
296         if(!fileOpen) {
297             cerr << "Error during saving" << endl;
298             QApplication::restoreOverrideCursor();
299             close();
300             return;
301         }
302         
303         vtkSmartPointer<vtkFloatArray> arrX = vtkSmartPointer<vtkFloatArray>::New();
304         vtkSmartPointer<vtkFloatArray> arrY = vtkSmartPointer<vtkFloatArray>::New();
305         vtkSmartPointer<vtkFloatArray> coords = vtkSmartPointer<vtkFloatArray>::New();
306         arrX = mFilter->GetArrayX();
307         arrY = mFilter->GetArrayY();
308         int i(0);
309         fileOpen << "Value represents the number of voxels around the corresponding intensity (by default the windows size around intensity is log(range))" << endl;
310         fileOpen << "Intensity" << "\t" << "Value" << endl;
311    
312         while (i<arrX->GetNumberOfTuples()) {
313             fileOpen << arrX->GetTuple(i)[0] << "\t" << arrY->GetTuple(i)[0] << endl;
314             ++i;
315         }
316
317         fileOpen.close();
318         QApplication::restoreOverrideCursor();
319     } else {
320       QString error = fileformat.c_str();
321       error += " format unknown !!!\n";
322       QMessageBox::information(this,tr("Saving Problem"),error);
323       SaveAs();
324     }
325   }
326 }
327 //------------------------------------------------------------------------------