#include "vtkActor.h" #include "vtkCylinderSource.h" #include "vtkPolyDataMapper.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkProperty.h" #include "vtkCamera.h" #include "vtkPoints.h" #include "vtkCellArray.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkPolyDataWriter.h" #include "vtkPolyDataReader.h" #include "vtkImageReader.h" #include "vtkImageViewer.h" #include "vtkImageViewer2.h" #include "vtkImageToStructuredPoints.h" #include "vtkExtractVOI.h" #include "vtkImageClip.h" #include "vtkImageResample.h" #include "vtkImageCast.h" #include "vtkImageThreshold.h" #include "vtkImageCast.h" #include "vtkImageSeedConnectivity.h" #include "vtkImageData.h" #include "vtkMarchingCubes.h" #include "vtkImageReslice.h" #include "vtkTransform.h" #include "vtkSphereSource.h" #include "vtkDoubleArray.h" #include "vtkPointData.h" #include "vtkCommand.h" #include "vtkCallbackCommand.h" #include "vtkImageResample.h" #include "vtkMath.h" #include "vtkStripper.h" #include "vtkImageWriter.h" #include "vtkBMPWriter.h" #include "vtkImageCast.h" #include "vtkPolyDataWriter.h" #include "wxProcessingCTWidget.h" #include #include //------------------------------------------------------------------- //------------------------------------------------------------------- //------------------------------------------------------------------- BEGIN_EVENT_TABLE( wxProcessingCTWidget, wxPanel ) EVT_MENU( 12121, wxProcessingCTWidget::OnRefreshView ) END_EVENT_TABLE( ); //------------------------------------------------------------------- wxProcessingCTWidget::wxProcessingCTWidget(wxWindow *parent, marInterfaceCT *mar) : wxPanel( parent, -1) { wxSplitterWindow *pnlSplitter = new wxSplitterWindow( this , -1); wxPanel *viewPanel = CreateViewPanel(pnlSplitter); wxPanel *controlPanel = CreateControlPanel(pnlSplitter); pnlSplitter -> SplitVertically( viewPanel, controlPanel ,300); pnlSplitter -> SetMinimumPaneSize( 300 ); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL ); sizer -> Add( pnlSplitter ,1,wxALL|wxGROW ,0); this -> SetSizer(sizer); this->SetAutoLayout(true); // panel->SetSize(400,400); this->Layout(); //EEDxx2.4 // FitInside(); _mar = mar; _range[0]=0; _range[1]=255; } //------------------------------------------------------------------- wxProcessingCTWidget::~wxProcessingCTWidget(){ // MAZV 27 sep 2006 // _thresh->Delete(); // _connect->Delete(); _connect2->Delete(); _thresh2->Delete(); delete _imageviewer2D_1; delete _imageviewer2D_2; delete _imageviewer2D_3; } //------------------------------------------------------------------- wxPanel* wxProcessingCTWidget::CreateViewPanel(wxWindow *parent) { wxPanel *panel = new wxPanel(parent,-1); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); _imageviewer2D_1 = new wxVtk2DBaseView(panel); _imageviewer2D_2 = new wxVtk2DBaseView(panel); _imageviewer2D_3 = new wxVtk2DBaseView(panel); wxVTKRenderWindowInteractor *iren = _imageviewer2D_1->GetWxVTKRenderWindowInteractor(); wxVTKRenderWindowInteractor *iren_2 = _imageviewer2D_2->GetWxVTKRenderWindowInteractor(); wxVTKRenderWindowInteractor *iren_3 = _imageviewer2D_3->GetWxVTKRenderWindowInteractor(); sizer->Add(iren , 1, wxGROW, 0); sizer->Add(iren_2, 1, wxGROW, 0); sizer->Add(iren_3, 1, wxGROW, 0); panel->SetSizer(sizer); panel->SetAutoLayout(true); // panel->SetSize(400,400); panel->Layout(); return panel; } //------------------------------------------------------------------- wxPanel* wxProcessingCTWidget::CreateControlPanel(wxWindow *parent) { _parent=parent; wxPanel *panel = new wxPanel(parent,-1); _lowthreshold = new wxSlider( panel, -1,65000 , 64000, 65000, wxDefaultPosition, wxSize(25,25), wxSL_HORIZONTAL | wxSL_LABELS | wxSL_AUTOTICKS ); _lowthreshold->SetTickFreq(50,0); _midthreshold = new wxSlider( panel, -1, 65000 , 64000, 65000, wxDefaultPosition, wxSize(25,25), wxSL_HORIZONTAL | wxSL_LABELS | wxSL_AUTOTICKS ); _midthreshold->SetTickFreq(50,0); _lowthresholdSpin1 = new wxSlider(panel , -1,5,1,10,wxDefaultPosition , wxSize(25,45), wxSL_VERTICAL | wxSL_AUTOTICKS |wxSL_LEFT ); _lowthresholdSpin1->SetRange(1,8); _lowthresholdSpin1->SetValue(5); Connect(_lowthresholdSpin1->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxProcessingCTWidget::OnSpinLowThresholdSpin1 ); // Connect(_lowthresholdSpin1->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnSpinLowThresholdSpin1 ); _lowthresholdSpin2 = new wxSlider(panel , -1,5,1,10,wxDefaultPosition , wxSize(25,45), wxSL_VERTICAL | wxSL_AUTOTICKS |wxSL_LEFT ); _lowthresholdSpin2->SetRange(1,8); _lowthresholdSpin2->SetValue(5); Connect(_lowthresholdSpin2->GetId() , wxEVT_COMMAND_SLIDER_UPDATED , (wxObjectEventFunction) &wxProcessingCTWidget::OnSpinLowThresholdSpin2 ); // Connect(_lowthresholdSpin2->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnSpinLowThresholdSpin2 ); // MAZV 27 sep 2006 // _highthreshold = new wxSlider( panel, -1, 50, 0, 100 , wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_LABELS ); _zslice = new wxSlider( panel, -1, 50, 0, 100 , wxDefaultPosition, wxSize(25,25), wxSL_HORIZONTAL | wxSL_LABELS | wxSL_AUTOTICKS ); _zslice->SetTickFreq(10,0); _extract = new wxButton( panel, -1, _T("Axis extraction")); // _midthreshold->SetSize(250,20); // MAZV 27 sep 2006 //_highthreshold->SetSize(250,20); // Result Volume // wxFlexGridSizer *sizer = new wxFlexGridSizer(1); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL ); int flag = wxALL | wxGROW ; sizer->Add(new wxStaticText(panel,-1,_T(" ")) , 1, flag, 0); sizer->Add(new wxStaticText(panel,-1,_T(" ")) , 1, flag, 0); sizer->Add(new wxStaticText(panel,-1,_T("Lower vascular threshold")) , 1, flag, 0); wxBoxSizer *sizerLowThreshold = new wxBoxSizer(wxHORIZONTAL ); sizerLowThreshold->Add(_lowthresholdSpin1 ); sizerLowThreshold->Add(_lowthreshold , 1, wxALL | wxGROW , 0); sizer->Add(sizerLowThreshold , 1, wxALL | wxGROW , 0); sizer->Add(new wxStaticText(panel,-1,_T(" ")) , 1, flag, 0); sizer->Add(new wxStaticText(panel,-1,_T("Higher vascular threshold")) , 1, flag, 0); wxBoxSizer *sizerMidThreshold = new wxBoxSizer(wxHORIZONTAL ); sizerMidThreshold->Add(_lowthresholdSpin2 ); sizerMidThreshold->Add(_midthreshold , 1, flag, 0); sizer->Add(sizerMidThreshold , 1, flag, 0); // MAZV 27 sep 2006 // sizer->Add(new wxStaticText(panel,-1," ")); // sizer->Add(new wxStaticText(panel,-1,"Calcification threshold")); // sizer->Add(_highthreshold); sizer->Add(new wxStaticText(panel,-1,_T(" ")) , 1, flag, 0); sizer->Add(new wxStaticText(panel,-1,_T("Z Slice")) , 1, flag, 0); sizer->Add(_zslice , 1, flag, 0); sizer->Add(new wxStaticText(panel,-1,_T(" ")) , 1, flag, 0); sizer->Add(_extract , 1, flag, 0); // panel->SetSize(200,200); panel->SetSizer(sizer); panel->SetAutoLayout(true); panel->Layout(); // panel->FitInside(parent); Connect(_lowthreshold->GetId() , wxEVT_SCROLL_CHANGED , (wxObjectEventFunction) &wxProcessingCTWidget::OnLowThreshold); Connect(_lowthreshold->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnLowThreshold); Connect(_midthreshold->GetId() , wxEVT_SCROLL_CHANGED , (wxObjectEventFunction) &wxProcessingCTWidget::OnMidThreshold ); Connect(_midthreshold->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnMidThreshold ); // MAZV 27 sep 2006 // Connect(_highthreshold->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnHighThreshold ); Connect(_zslice->GetId() , wxEVT_SCROLL_CHANGED , (wxObjectEventFunction) &wxProcessingCTWidget::OnZSlice ); Connect(_zslice->GetId() , wxEVT_SCROLL_THUMBTRACK , (wxObjectEventFunction) &wxProcessingCTWidget::OnZSlice ); Connect(_extract->GetId() , wxEVT_COMMAND_BUTTON_CLICKED , (wxObjectEventFunction) &wxProcessingCTWidget::OnExtract ); return panel; } //------------------------------------------------------------------------ void wxProcessingCTWidget::Refresh() { int z = (int)(_vtkbasedata_1->GetZ( )); _vtkbasedata_1->SetZ( z ); _vtkbasedata_2->SetZ( z ); _vtkbasedata_3->SetZ( z ); _imageviewer2D_3->Refresh(); _imageviewer2D_1->Refresh(); _imageviewer2D_2->Refresh(); _imageviewer2D_3->RefreshView(); _imageviewer2D_1->RefreshView(); _imageviewer2D_2->RefreshView(); } //---------------------------------------------------------------------------- void wxProcessingCTWidget::OnSpinLowThresholdSpin1(wxScrollEvent& event) { int value = _lowthreshold->GetValue(); int delta = (int) (pow( 4 , _lowthresholdSpin1->GetValue() )); int min = value - delta/2; int max = value + delta/2; if (min<0) { min=0; max=delta; } _lowthreshold->SetRange(min,max); } //---------------------------------------------------------------------------- void wxProcessingCTWidget::OnSpinLowThresholdSpin2(wxScrollEvent& event) { int value = _midthreshold->GetValue(); int delta = (int)(pow( 4 , _lowthresholdSpin2->GetValue() )); int min=value - delta/2; int max=value + delta/2; if (min<0) { min=0; max=delta; } _midthreshold->SetRange(min,max); } //---------------------------------------------------------------------------- void wxProcessingCTWidget::OnRefreshView(wxCommandEvent & event) { Refresh(); } //------------------------------------------------------------------------ void wxProcessingCTWidget::ConfigureVTK(marImageData *marimagedata, int x, int y, int z) { wxBusyCursor wait; _x = x; _y = y; _z = z; vtkImageData *imagedata=marimagedata->GetImageData(); imagedata->UpdateInformation(); imagedata->SetUpdateExtent(imagedata->GetWholeExtent()); imagedata->Update(); data = imagedata; double puntoactualprov[3]; puntoactualprov[0] = x; puntoactualprov[1] = y; puntoactualprov[2] = z; double espprin[3]; int extprin[6]; imagedata->GetSpacing(espprin); imagedata->GetExtent(extprin); // MAZV 27 sep 2006 // puntoactualprov[0]=puntoactualprov[0]*espprin[0]; // puntoactualprov[1]=puntoactualprov[1]*espprin[1]; // puntoactualprov[2]=puntoactualprov[2]*espprin[2]; imagedata->GetScalarRange( _range ); // Update Controls _lowthreshold->SetRange( (int)(_range[0]), (int)(_range[1])); _lowthreshold->SetValue( (int)(_range[1]/4) ); _midthreshold->SetRange( (int)(_range[0]), (int)(_range[1])); _midthreshold->SetValue( (int)(_range[1]/2) ); // MAZV 27 sep 2006 // _highthreshold->SetRange(_range[0], _range[1]); // _highthreshold->SetValue( _range[1] ); _zslice->SetRange(extprin[4], extprin[5]); _zslice->SetValue(extprin[5]/2); _thresh = vtkImageThreshold::New(); _thresh->SetInput(imagedata); //_thresh->ReleaseDataFlagOff(); _thresh->SetInValue(255); _thresh->SetOutputScalarTypeToUnsignedShort(); _thresh->SetOutValue(0); _thresh->ThresholdBetween(_lowthreshold->GetValue(), _range[1]); vtkImageCast *cast = vtkImageCast::New(); cast->SetInput(_thresh->GetOutput()); cast->SetOutputScalarTypeToUnsignedChar(); cast->Update(); _connect = vtkImageSeedConnectivity::New(); _connect->SetInput(cast->GetOutput()); _connect->SetInputConnectValue(255); _connect->SetOutputConnectedValue(255); _connect->SetOutputUnconnectedValue(0); _connect->AddSeed( (int)(puntoactualprov[0]), (int)(puntoactualprov[1]), (int)(puntoactualprov[2])); _connect->Update(); cast3 = vtkImageCast::New(); cast3->SetInput(_connect->GetOutput()); cast3->SetOutputScalarTypeToUnsignedShort(); cast3->Update(); _thresh2 = vtkImageThreshold::New(); _thresh2->SetInput(imagedata); //_thresh2->ReleaseDataFlagOff(); _thresh2->SetInValue(255); _thresh2->SetOutputScalarTypeToUnsignedShort(); _thresh2->SetOutValue(0); _thresh2->ThresholdBetween(_lowthreshold->GetValue(), _midthreshold->GetValue()); vtkImageCast *cast2 = vtkImageCast::New(); cast2->SetInput(_thresh2->GetOutput()); cast2->SetOutputScalarTypeToUnsignedChar(); cast2->Update(); _connect2 = vtkImageSeedConnectivity::New(); _connect2->SetInput(cast2->GetOutput()); _connect2->SetInputConnectValue(255); _connect2->SetOutputConnectedValue(255); _connect2->SetOutputUnconnectedValue(0); _connect2->AddSeed( (int)(puntoactualprov[0]), (int)(puntoactualprov[1]), (int)(puntoactualprov[2]) ); _connect2->Update(); cast4 = vtkImageCast::New(); cast4->SetInput(_connect2->GetOutput()); cast4->SetOutputScalarTypeToUnsignedShort(); cast4->Update(); // Interface Update _vtkbasedata_1 = new vtkBaseData(); _vtkbasedata_1->SetMarImageData(marimagedata); cast3->GetOutput()->UpdateInformation(); cast3->GetOutput()->SetUpdateExtent( cast3->GetOutput()->GetWholeExtent() ); cast3->GetOutput()->SetUpdateExtent( cast3->GetOutput()->GetWholeExtent() ); cast3->GetOutput()->Update(); _vtkbasedata_2 = new vtkBaseData(); _vtkbasedata_2->SetMarImageData( new marImageData(cast3->GetOutput()) ); cast4->GetOutput()->UpdateInformation(); cast4->GetOutput()->SetUpdateExtent(cast4->GetOutput()->GetWholeExtent()); cast4->GetOutput()->Update(); _vtkbasedata_3 = new vtkBaseData(); _vtkbasedata_3->SetMarImageData( new marImageData(cast4->GetOutput() )); _imageviewer2D_1->SetVtkBaseData( _vtkbasedata_1 ); _imageviewer2D_1->Configure(); _imageviewer2D_2->SetVtkBaseData( _vtkbasedata_2 ); _imageviewer2D_2->Configure(); _imageviewer2D_3->SetVtkBaseData( _vtkbasedata_3 ); _imageviewer2D_3->Configure(); // EED 31 Mai 2007 // Refresh(); } //------------------------------------------------------------------------ void wxProcessingCTWidget::MidThreshold() { _thresh2->ThresholdBetween(_lowthreshold->GetValue(), _midthreshold->GetValue()); _thresh2->Update(); } //------------------------------------------------------------------------ void wxProcessingCTWidget::LowThreshold() { // MAZV 27 sep 2006 // _thresh->ThresholdBetween(_lowthreshold->GetValue(), _highthreshold->GetValue()); // _thresh->Update(); // MAZV 3 oct 2006 _thresh->ThresholdBetween(_lowthreshold->GetValue(), _range[1] ); _thresh->Update(); MidThreshold(); } //------------------------------------------------------------------------ void wxProcessingCTWidget::OnLowThreshold(wxScrollEvent& event) { LowThreshold(); Refresh(); } //------------------------------------------------------------------------ void wxProcessingCTWidget::OnMidThreshold(wxScrollEvent& event){ MidThreshold(); Refresh(); } //------------------------------------------------------------------------ // MAZV 27 sep 2006 //void wxProcessingCTWidget::OnHighThreshold(wxScrollEvent& event){ // _thresh->ThresholdBetween(_lowthreshold->GetValue(), _highthreshold->GetValue()); // Refresh(); //} //------------------------------------------------------------------------ void wxProcessingCTWidget::OnZSlice(wxScrollEvent& event){ _vtkbasedata_1->SetZ( _zslice->GetValue() ); // _vtkbasedata_2->SetZ( _zslice->GetValue() ); // _vtkbasedata_3->SetZ( _zslice->GetValue() ); Refresh(); } //------------------------------------------------------------------------ void wxProcessingCTWidget::OnExtract(wxCommandEvent& event){ wxBusyCursor wait; int ext[6]; vtkImageChangeInformation* change = vtkImageChangeInformation::New(); change->SetInput( _vtkbasedata_3->GetImageData() ); _vtkbasedata_3->GetImageData()->GetWholeExtent(ext); change->SetExtentTranslation( -ext[0], -ext[2], -ext[4] ); change->Update(); vtkImageData *image = change->GetOutput(); marParameters *marParam = new marParameters(); marParam->copyFrom ( *(_mar->getParameters()) ); marParam->setDoubleParam( marParameters::e_RescaleIntercept , 0 ); marParam->setDoubleParam( marParameters::e_RescaleSlope , 1 ); marExperiment *newExperiment = new marExperiment( marParam ); kVolume *vol = new kVolume( image ); newExperiment->setVOI(ext); newExperiment->initExperiment(vol); newExperiment->setStartPoint( _x, _y, _z); newExperiment->extractVascularTree(); //_mar->_experiment->initExperiment(new kVolume(data)); _mar->appendAxis(newExperiment->getAxis(0)); //_mar->_experiment->setVOI(ext); _mar->setAxis(0); _mar->prepareQuantification( ); wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED,20005); _parent->ProcessEvent( ev ); int size = _mar->getNumberOfSlices( ); if (size != 0){ wxString msg; msg.Printf(_T("Axis Extracted")); wxMessageDialog(this, msg,_T("Information")).ShowModal(); } /* FILE *ff; ff=fopen("c:/Temp/DATOS.txt","a+"); fprintf(ff,"z:%d - x:%d y:%d\n",size,ext[1]+1,ext[3]+1,ext[5]+1); fclose(ff); vtkImageWriter *w = vtkImageWriter::New(); for (int i = 0; i < size; i++){ std::string path = "C:/TEMP/"; w->SetInput(_mar->_experiment->getSliceImage(i)); char *f = ""; f = itoa(i, f, 10); std::string fil(f); path.append(fil.c_str()); w->SetFileName(path.c_str()); w->Write(); } w->Delete(); */ /* vtkBMPWriter *w = vtkBMPWriter::New(); vtkImageCast *c = vtkImageCast::New(); for (int i = 0; i < size; i++){ std::string path = "C:/TEMP/"; c->SetInput(_mar->_experiment->getSliceImage(i)); c->SetOutputScalarTypeToUnsignedChar(); c->Update(); w->SetInput(c->GetOutput()); char *f = ""; f = itoa(i, f, 10); std::string fil(f); path.append(fil.c_str()); path.append(".bmp"); w->SetFileName(path.c_str()); w->Write(); }*/ //Escritura a pcx con LibIDO /* for ( int i = 0; i < size; i++){ PPIMAGE_USHORT imalibido = (PPIMAGE_USHORT) IdImaAlloc(128,128, IMA_USHORT); for (int j = 0; j < 128; j++){ for (int k = 0; k < 128; k++){ imalibido[k][j] = (unsigned short)_mar->_experiment->getSliceImage(i)->GetScalarComponentAsDouble(j, k, 0, 0); } } std::string path = "C:/TEMP/"; char *f = ""; f = itoa(i, f, 10); std::string fil(f); path.append(fil.c_str()); path.append(".pcx"); PPIMAGE_UCHAR imagennueva = IdImaRecad16To8(imalibido, -1, -1); IdImaWritePCXFile((char*)path.c_str(), imagennueva); IdImaClear((PPIMAGE)imalibido); } */ } //------------------------------------------------------------------------ void wxProcessingCTWidget::SetThreshold(int min ,int max) { _lowthreshold->SetValue(min); _midthreshold->SetValue(max); LowThreshold(); } //------------------------------------------------------------------------ void wxProcessingCTWidget::GetThreshold(int *min ,int *max) { *min = _lowthreshold->GetValue(); *max = _midthreshold->GetValue(); } //------------------------------------------------------------------------