1 /*# ---------------------------------------------------------------------
3 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
6 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
7 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 # This software is governed by the CeCILL-B license under French law and
10 # abiding by the rules of distribution of free software. You can use,
11 # modify and/ or redistribute the software under the terms of the CeCILL-B
12 # license as circulated by CEA, CNRS and INRIA at the following URL
13 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
14 # or in the file LICENSE.txt.
16 # As a counterpart to the access to the source code and rights to copy,
17 # modify and redistribute granted by the license, users are provided only
18 # with a limited warranty and the software's author, the holder of the
19 # economic rights, and the successive licensors have only limited
22 # The fact that you are presently reading this means that you have had
23 # knowledge of the CeCILL-B license and that you accept its terms.
24 # ------------------------------------------------------------------------ */
27 #include "vtkCylinderSource.h"
28 #include "vtkPolyDataMapper.h"
29 #include "vtkRenderer.h"
30 #include "vtkRenderWindow.h"
31 #include "vtkRenderWindowInteractor.h"
32 #include "vtkProperty.h"
33 #include "vtkCamera.h"
34 #include "vtkPoints.h"
35 #include "vtkCellArray.h"
36 #include "vtkPolyData.h"
37 #include "vtkPolyDataMapper.h"
38 #include "vtkPolyDataWriter.h"
39 #include "vtkPolyDataReader.h"
40 #include "vtkImageReader.h"
41 #include "vtkImageViewer.h"
42 #include "vtkImageViewer2.h"
43 #include "vtkImageToStructuredPoints.h"
45 #include "vtkExtractVOI.h"
46 #include "vtkImageClip.h"
47 #include "vtkImageResample.h"
48 #include "vtkImageCast.h"
49 #include "vtkImageThreshold.h"
50 #include "vtkImageCast.h"
51 #include "vtkImageSeedConnectivity.h"
52 #include "vtkImageData.h"
53 #include "vtkMarchingCubes.h"
54 #include "vtkImageReslice.h"
55 #include "vtkTransform.h"
56 #include "vtkSphereSource.h"
57 #include "vtkDoubleArray.h"
58 #include "vtkPointData.h"
59 #include "vtkCommand.h"
60 #include "vtkCallbackCommand.h"
61 #include "vtkImageResample.h"
63 #include "vtkStripper.h"
64 #include "vtkImageWriter.h"
65 #include "vtkBMPWriter.h"
66 #include "vtkImageCast.h"
67 #include "vtkPolyDataWriter.h"
69 #include "wxProcessingCTWidget.h"
71 #include <wx/splitter.h>
72 #include <wx/renderer.h>
73 //-------------------------------------------------------------------
74 //-------------------------------------------------------------------
75 //-------------------------------------------------------------------
79 BEGIN_EVENT_TABLE( wxProcessingCTWidget, wxPanel )
80 EVT_MENU( 12121, wxProcessingCTWidget::OnRefreshView )
83 //-------------------------------------------------------------------
86 wxProcessingCTWidget::wxProcessingCTWidget(wxWindow *parent, marInterfaceCT *mar)
87 : wxPanel( parent, -1)
89 wxSplitterWindow *pnlSplitter = new wxSplitterWindow( this , -1);
90 wxPanel *viewPanel = CreateViewPanel(pnlSplitter);
91 wxPanel *controlPanel = CreateControlPanel(pnlSplitter);
93 pnlSplitter -> SplitVertically( viewPanel, controlPanel ,300);
94 pnlSplitter -> SetMinimumPaneSize( 300 );
96 wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL );
97 sizer -> Add( pnlSplitter ,1,wxALL|wxGROW ,0);
98 this -> SetSizer(sizer);
99 this->SetAutoLayout(true);
100 // panel->SetSize(400,400);
110 //-------------------------------------------------------------------
111 wxProcessingCTWidget::~wxProcessingCTWidget(){
113 // _thresh->Delete();
114 // _connect->Delete();
120 delete _imageviewer2D_1;
121 delete _imageviewer2D_2;
122 delete _imageviewer2D_3;
124 //-------------------------------------------------------------------
125 wxPanel* wxProcessingCTWidget::CreateViewPanel(wxWindow *parent)
127 wxPanel *panel = new wxPanel(parent,-1);
128 wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
130 _imageviewer2D_1 = new wxVtk2DBaseView(panel);
131 _imageviewer2D_2 = new wxVtk2DBaseView(panel);
132 _imageviewer2D_3 = new wxVtk2DBaseView(panel);
133 wxVTKRenderWindowInteractor *iren = _imageviewer2D_1->GetWxVTKRenderWindowInteractor();
134 wxVTKRenderWindowInteractor *iren_2 = _imageviewer2D_2->GetWxVTKRenderWindowInteractor();
135 wxVTKRenderWindowInteractor *iren_3 = _imageviewer2D_3->GetWxVTKRenderWindowInteractor();
136 sizer->Add(iren , 1, wxGROW, 0);
137 sizer->Add(iren_2, 1, wxGROW, 0);
138 sizer->Add(iren_3, 1, wxGROW, 0);
141 panel->SetSizer(sizer);
142 panel->SetAutoLayout(true);
143 // panel->SetSize(400,400);
147 //-------------------------------------------------------------------
148 wxPanel* wxProcessingCTWidget::CreateControlPanel(wxWindow *parent)
151 wxPanel *panel = new wxPanel(parent,-1);
152 _lowthreshold = new wxSlider( panel, -1,65000 , 64000, 65000, wxDefaultPosition, wxSize(25,25), wxSL_HORIZONTAL | wxSL_LABELS | wxSL_AUTOTICKS );
153 _lowthreshold->SetTickFreq(50,0);
155 _midthreshold = new wxSlider( panel, -1, 65000 , 64000, 65000, wxDefaultPosition, wxSize(25,25), wxSL_HORIZONTAL | wxSL_LABELS | wxSL_AUTOTICKS );
156 _midthreshold->SetTickFreq(50,0);
159 _lowthresholdSpin1 = new wxSlider(panel , -1,5,1,10,wxDefaultPosition , wxSize(25,45), wxSL_VERTICAL | wxSL_AUTOTICKS |wxSL_LEFT );
160 _lowthresholdSpin1->SetRange(1,8);
161 _lowthresholdSpin1->SetValue(5);
162 Connect(_lowthresholdSpin1->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxProcessingCTWidget::OnSpinLowThresholdSpin1 );
163 // Connect(_lowthresholdSpin1->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnSpinLowThresholdSpin1 );
165 _lowthresholdSpin2 = new wxSlider(panel , -1,5,1,10,wxDefaultPosition , wxSize(25,45), wxSL_VERTICAL | wxSL_AUTOTICKS |wxSL_LEFT );
166 _lowthresholdSpin2->SetRange(1,8);
167 _lowthresholdSpin2->SetValue(5);
168 Connect(_lowthresholdSpin2->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxProcessingCTWidget::OnSpinLowThresholdSpin2 );
169 // Connect(_lowthresholdSpin2->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnSpinLowThresholdSpin2 );
174 // _highthreshold = new wxSlider( panel, -1, 50, 0, 100 , wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_LABELS );
175 _zslice = new wxSlider( panel, -1, 50, 0, 100 , wxDefaultPosition, wxSize(25,25), wxSL_HORIZONTAL | wxSL_LABELS | wxSL_AUTOTICKS );
176 _zslice->SetTickFreq(10,0);
177 _extract = new wxButton( panel, -1, _T("Axis extraction"));
178 // _midthreshold->SetSize(250,20);
180 //_highthreshold->SetSize(250,20); // Result Volume
182 // wxFlexGridSizer *sizer = new wxFlexGridSizer(1);
183 wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL );
185 int flag = wxALL | wxGROW ;
187 sizer->Add(new wxStaticText(panel,-1,_T(" ")) , 1, flag, 0);
188 sizer->Add(new wxStaticText(panel,-1,_T(" ")) , 1, flag, 0);
189 sizer->Add(new wxStaticText(panel,-1,_T("Lower vascular threshold")) , 1, flag, 0);
191 wxBoxSizer *sizerLowThreshold = new wxBoxSizer(wxHORIZONTAL );
192 sizerLowThreshold->Add(_lowthresholdSpin1 );
193 sizerLowThreshold->Add(_lowthreshold , 1, wxALL | wxGROW , 0);
194 sizer->Add(sizerLowThreshold , 1, wxALL | wxGROW , 0);
196 sizer->Add(new wxStaticText(panel,-1,_T(" ")) , 1, flag, 0);
197 sizer->Add(new wxStaticText(panel,-1,_T("Higher vascular threshold")) , 1, flag, 0);
199 wxBoxSizer *sizerMidThreshold = new wxBoxSizer(wxHORIZONTAL );
200 sizerMidThreshold->Add(_lowthresholdSpin2 );
201 sizerMidThreshold->Add(_midthreshold , 1, flag, 0);
202 sizer->Add(sizerMidThreshold , 1, flag, 0);
206 // sizer->Add(new wxStaticText(panel,-1," "));
207 // sizer->Add(new wxStaticText(panel,-1,"Calcification threshold"));
208 // sizer->Add(_highthreshold);
211 sizer->Add(new wxStaticText(panel,-1,_T(" ")) , 1, flag, 0);
212 sizer->Add(new wxStaticText(panel,-1,_T("Z Slice")) , 1, flag, 0);
213 sizer->Add(_zslice , 1, flag, 0);
214 sizer->Add(new wxStaticText(panel,-1,_T(" ")) , 1, flag, 0);
215 sizer->Add(_extract , 1, flag, 0);
217 // panel->SetSize(200,200);
218 panel->SetSizer(sizer);
219 panel->SetAutoLayout(true);
221 // panel->FitInside(parent);
223 Connect(_lowthreshold->GetId() , wxEVT_SCROLL_CHANGED , (wxObjectEventFunction) &wxProcessingCTWidget::OnLowThreshold);
224 Connect(_lowthreshold->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnLowThreshold);
225 Connect(_midthreshold->GetId() , wxEVT_SCROLL_CHANGED , (wxObjectEventFunction) &wxProcessingCTWidget::OnMidThreshold );
226 Connect(_midthreshold->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnMidThreshold );
230 // Connect(_highthreshold->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnHighThreshold );
232 Connect(_zslice->GetId() , wxEVT_SCROLL_CHANGED , (wxObjectEventFunction) &wxProcessingCTWidget::OnZSlice );
233 Connect(_zslice->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnZSlice );
235 Connect(_extract->GetId() , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &wxProcessingCTWidget::OnExtract );
240 //------------------------------------------------------------------------
242 void wxProcessingCTWidget::Refresh()
244 int z = (int)(_vtkbasedata_1->GetZ( ));
246 _vtkbasedata_1->SetZ( z );
247 _vtkbasedata_2->SetZ( z );
248 _vtkbasedata_3->SetZ( z );
250 _imageviewer2D_3->Refresh();
251 _imageviewer2D_1->Refresh();
252 _imageviewer2D_2->Refresh();
254 _imageviewer2D_3->RefreshView();
255 _imageviewer2D_1->RefreshView();
256 _imageviewer2D_2->RefreshView();
261 //----------------------------------------------------------------------------
262 void wxProcessingCTWidget::OnSpinLowThresholdSpin1(wxScrollEvent& event)
264 int value = _lowthreshold->GetValue();
265 int delta = (int) (pow( 4 , _lowthresholdSpin1->GetValue() ));
266 int min = value - delta/2;
267 int max = value + delta/2;
273 _lowthreshold->SetRange(min,max);
276 //----------------------------------------------------------------------------
277 void wxProcessingCTWidget::OnSpinLowThresholdSpin2(wxScrollEvent& event)
279 int value = _midthreshold->GetValue();
280 int delta = (int)(pow( 4 , _lowthresholdSpin2->GetValue() ));
281 int min=value - delta/2;
282 int max=value + delta/2;
288 _midthreshold->SetRange(min,max);
292 //----------------------------------------------------------------------------
293 void wxProcessingCTWidget::OnRefreshView(wxCommandEvent & event)
298 //------------------------------------------------------------------------
300 void wxProcessingCTWidget::ConfigureVTK(marImageData *marimagedata, int x, int y, int z)
308 vtkImageData *imagedata=marimagedata->GetImageData();
309 imagedata->UpdateInformation();
310 imagedata->SetUpdateExtent(imagedata->GetWholeExtent());
315 double puntoactualprov[3];
316 puntoactualprov[0] = x;
317 puntoactualprov[1] = y;
318 puntoactualprov[2] = z;
323 imagedata->GetSpacing(espprin);
324 imagedata->GetExtent(extprin);
328 // puntoactualprov[0]=puntoactualprov[0]*espprin[0];
329 // puntoactualprov[1]=puntoactualprov[1]*espprin[1];
330 // puntoactualprov[2]=puntoactualprov[2]*espprin[2];
332 imagedata->GetScalarRange( _range );
336 _lowthreshold->SetRange( (int)(_range[0]), (int)(_range[1]));
337 _lowthreshold->SetValue( (int)(_range[1]/4) );
339 _midthreshold->SetRange( (int)(_range[0]), (int)(_range[1]));
340 _midthreshold->SetValue( (int)(_range[1]/2) );
343 // _highthreshold->SetRange(_range[0], _range[1]);
344 // _highthreshold->SetValue( _range[1] );
346 _zslice->SetRange(extprin[4], extprin[5]);
347 _zslice->SetValue(extprin[5]/2);
350 _thresh = vtkImageThreshold::New();
351 _thresh->SetInput(imagedata);
352 //_thresh->ReleaseDataFlagOff();
353 _thresh->SetInValue(255);
354 _thresh->SetOutputScalarTypeToUnsignedShort();
355 _thresh->SetOutValue(0);
356 _thresh->ThresholdBetween(_lowthreshold->GetValue(), _range[1]);
358 vtkImageCast *cast = vtkImageCast::New();
359 cast->SetInput(_thresh->GetOutput());
360 cast->SetOutputScalarTypeToUnsignedChar();
364 _connect = vtkImageSeedConnectivity::New();
365 _connect->SetInput(cast->GetOutput());
366 _connect->SetInputConnectValue(255);
367 _connect->SetOutputConnectedValue(255);
368 _connect->SetOutputUnconnectedValue(0);
369 _connect->AddSeed( (int)(puntoactualprov[0]), (int)(puntoactualprov[1]), (int)(puntoactualprov[2]));
372 cast3 = vtkImageCast::New();
373 cast3->SetInput(_connect->GetOutput());
374 cast3->SetOutputScalarTypeToUnsignedShort();
377 _thresh2 = vtkImageThreshold::New();
378 _thresh2->SetInput(imagedata);
379 //_thresh2->ReleaseDataFlagOff();
380 _thresh2->SetInValue(255);
381 _thresh2->SetOutputScalarTypeToUnsignedShort();
382 _thresh2->SetOutValue(0);
383 _thresh2->ThresholdBetween(_lowthreshold->GetValue(), _midthreshold->GetValue());
385 vtkImageCast *cast2 = vtkImageCast::New();
386 cast2->SetInput(_thresh2->GetOutput());
387 cast2->SetOutputScalarTypeToUnsignedChar();
391 _connect2 = vtkImageSeedConnectivity::New();
392 _connect2->SetInput(cast2->GetOutput());
393 _connect2->SetInputConnectValue(255);
394 _connect2->SetOutputConnectedValue(255);
395 _connect2->SetOutputUnconnectedValue(0);
396 _connect2->AddSeed( (int)(puntoactualprov[0]), (int)(puntoactualprov[1]), (int)(puntoactualprov[2]) );
399 cast4 = vtkImageCast::New();
400 cast4->SetInput(_connect2->GetOutput());
401 cast4->SetOutputScalarTypeToUnsignedShort();
406 _vtkbasedata_1 = new vtkBaseData();
407 _vtkbasedata_1->SetMarImageData(marimagedata);
410 cast3->GetOutput()->UpdateInformation();
411 cast3->GetOutput()->SetUpdateExtent( cast3->GetOutput()->GetWholeExtent() );
412 cast3->GetOutput()->SetUpdateExtent( cast3->GetOutput()->GetWholeExtent() );
414 cast3->GetOutput()->Update();
415 _vtkbasedata_2 = new vtkBaseData();
416 _vtkbasedata_2->SetMarImageData( new marImageData(cast3->GetOutput()) );
419 cast4->GetOutput()->UpdateInformation();
420 cast4->GetOutput()->SetUpdateExtent(cast4->GetOutput()->GetWholeExtent());
421 cast4->GetOutput()->Update();
422 _vtkbasedata_3 = new vtkBaseData();
423 _vtkbasedata_3->SetMarImageData( new marImageData(cast4->GetOutput() ));
425 _imageviewer2D_1->SetVtkBaseData( _vtkbasedata_1 );
426 _imageviewer2D_1->Configure();
428 _imageviewer2D_2->SetVtkBaseData( _vtkbasedata_2 );
429 _imageviewer2D_2->Configure();
431 _imageviewer2D_3->SetVtkBaseData( _vtkbasedata_3 );
432 _imageviewer2D_3->Configure();
439 //------------------------------------------------------------------------
440 void wxProcessingCTWidget::MidThreshold()
442 _thresh2->ThresholdBetween(_lowthreshold->GetValue(), _midthreshold->GetValue());
447 //------------------------------------------------------------------------
448 void wxProcessingCTWidget::LowThreshold()
451 // _thresh->ThresholdBetween(_lowthreshold->GetValue(), _highthreshold->GetValue());
452 // _thresh->Update();
455 _thresh->ThresholdBetween(_lowthreshold->GetValue(), _range[1] );
462 //------------------------------------------------------------------------
463 void wxProcessingCTWidget::OnLowThreshold(wxScrollEvent& event)
468 //------------------------------------------------------------------------
469 void wxProcessingCTWidget::OnMidThreshold(wxScrollEvent& event){
474 //------------------------------------------------------------------------
476 //void wxProcessingCTWidget::OnHighThreshold(wxScrollEvent& event){
477 // _thresh->ThresholdBetween(_lowthreshold->GetValue(), _highthreshold->GetValue());
481 //------------------------------------------------------------------------
482 void wxProcessingCTWidget::OnZSlice(wxScrollEvent& event){
483 _vtkbasedata_1->SetZ( _zslice->GetValue() );
484 // _vtkbasedata_2->SetZ( _zslice->GetValue() );
485 // _vtkbasedata_3->SetZ( _zslice->GetValue() );
488 //------------------------------------------------------------------------
489 void wxProcessingCTWidget::OnExtract(wxCommandEvent& event){
494 vtkImageChangeInformation* change = vtkImageChangeInformation::New();
495 change->SetInput( _vtkbasedata_3->GetImageData() );
497 _vtkbasedata_3->GetImageData()->GetWholeExtent(ext);
498 change->SetExtentTranslation( -ext[0], -ext[2], -ext[4] );
501 vtkImageData *image = change->GetOutput();
503 marParameters *marParam = new marParameters();
504 marParam->copyFrom ( *(_mar->getParameters()) );
505 marParam->setDoubleParam( marParameters::e_RescaleIntercept , 0 );
506 marParam->setDoubleParam( marParameters::e_RescaleSlope , 1 );
508 marExperiment *newExperiment = new marExperiment( marParam );
510 kVolume *vol = new kVolume( image );
511 newExperiment->setVOI(ext);
512 newExperiment->initExperiment(vol);
513 newExperiment->setStartPoint( _x, _y, _z);
514 newExperiment->extractVascularTree();
516 //_mar->_experiment->initExperiment(new kVolume(data));
517 _mar->appendAxis(newExperiment->getAxis(0));
518 //_mar->_experiment->setVOI(ext);
520 _mar->prepareQuantification( );
522 wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED,20005);
523 _parent->ProcessEvent( ev );
525 int size = _mar->getNumberOfSlices( );
529 msg.Printf(_T("Axis Extracted"));
530 wxMessageDialog(this, msg,_T("Information")).ShowModal();
536 ff=fopen("c:/Temp/DATOS.txt","a+");
537 fprintf(ff,"z:%d - x:%d y:%d\n",size,ext[1]+1,ext[3]+1,ext[5]+1);
540 vtkImageWriter *w = vtkImageWriter::New();
543 for (int i = 0; i < size; i++){
544 std::string path = "C:/TEMP/";
545 w->SetInput(_mar->_experiment->getSliceImage(i));
550 path.append(fil.c_str());
551 w->SetFileName(path.c_str());
558 /* vtkBMPWriter *w = vtkBMPWriter::New();
559 vtkImageCast *c = vtkImageCast::New();
561 for (int i = 0; i < size; i++){
562 std::string path = "C:/TEMP/";
565 c->SetInput(_mar->_experiment->getSliceImage(i));
566 c->SetOutputScalarTypeToUnsignedChar();
569 w->SetInput(c->GetOutput());
574 path.append(fil.c_str());
576 w->SetFileName(path.c_str());
580 //Escritura a pcx con LibIDO
582 for ( int i = 0; i < size; i++){
583 PPIMAGE_USHORT imalibido = (PPIMAGE_USHORT) IdImaAlloc(128,128, IMA_USHORT);
584 for (int j = 0; j < 128; j++){
585 for (int k = 0; k < 128; k++){
586 imalibido[k][j] = (unsigned short)_mar->_experiment->getSliceImage(i)->GetScalarComponentAsDouble(j, k, 0, 0);
589 std::string path = "C:/TEMP/";
593 path.append(fil.c_str());
595 PPIMAGE_UCHAR imagennueva = IdImaRecad16To8(imalibido, -1, -1);
596 IdImaWritePCXFile((char*)path.c_str(), imagennueva);
597 IdImaClear((PPIMAGE)imalibido);
605 //------------------------------------------------------------------------
606 void wxProcessingCTWidget::SetThreshold(int min ,int max)
608 _lowthreshold->SetValue(min);
609 _midthreshold->SetValue(max);
612 //------------------------------------------------------------------------
613 void wxProcessingCTWidget::GetThreshold(int *min ,int *max)
615 *min = _lowthreshold->GetValue();
616 *max = _midthreshold->GetValue();
620 //------------------------------------------------------------------------