#include "wxVtkImageFlip.h" #include "wxVTKRenderWindowInteractor.h" #include "vtkViewImage2D.h" #include "vtkImageData.h" #include #include #include #include #include #include #include #include #include wxVtkImageFlip::wxVtkImageFlip (wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) { this->AcquisitionTxt = new wxStaticText(this, -1, wxT("Acquisition Orientation:")); this->ComboAcquisition = new wxComboBox (this, COMBOBOX_ACQ, wxT ("Change the acquisition flag...")); this->ComboAcquisition ->SetWindowStyle (wxCB_DROPDOWN); this->ComboAcquisition ->Append (wxT("AXIAL")); this->ComboAcquisition ->Append (wxT("SAGITTAL")); this->ComboAcquisition ->Append (wxT("CORONAL")); this->ComboAcquisition ->SetSelection (0); this->ButtonFlipRL = new wxButton (this, BUTTON_FLIPRL, wxT("Flip R-L"), wxDefaultPosition, wxSize (64,64)); this->ButtonFlipFH = new wxButton (this, BUTTON_FLIPFH, wxT("Flip I-S"), wxDefaultPosition, wxSize (64,64)); this->ButtonFlipAP = new wxButton (this, BUTTON_FLIPAP, wxT("Flip A-P"), wxDefaultPosition, wxSize (64,64)); this->ButtonCANCEL = new wxButton (this, BUTTON_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize (80,30)); this->ButtonOK = new wxButton (this, BUTTON_OK, wxT("OK"), wxDefaultPosition, wxSize (80,30)); this->ButtonSave = new wxButton (this, BUTTON_SAVE, wxT("Save..."), wxDefaultPosition, wxSize (80,30)); long viewstyle = wxWANTS_CHARS | wxNO_FULL_REPAINT_ON_RESIZE | wxSUNKEN_BORDER; this->VtkView1 = new wxVTKRenderWindowInteractor (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle, wxT("")); this->VtkView2 = new wxVTKRenderWindowInteractor (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle, wxT("")); this->VtkView3 = new wxVTKRenderWindowInteractor (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle, wxT("")); this->View1 = vtkViewImage2D::New(); //new wxVtkViewImage2D (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle, wxT(""), wxVtkViewImage2D::AXIAL_ID); this->View2 = vtkViewImage2D::New(); //new wxVtkViewImage2D (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle ); this->View3 = vtkViewImage2D::New(); //new wxVtkViewImage2D (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, viewstyle ); vtkRenderer* rend1 = vtkRenderer::New(); vtkRenderer* rend2 = vtkRenderer::New(); vtkRenderer* rend3 = vtkRenderer::New(); this->VtkView1->GetRenderWindow()->AddRenderer (rend1); this->VtkView2->GetRenderWindow()->AddRenderer (rend2); this->VtkView3->GetRenderWindow()->AddRenderer (rend3); this->View1->SetRenderWindow (this->VtkView1->GetRenderWindow()); this->View2->SetRenderWindow (this->VtkView2->GetRenderWindow()); this->View3->SetRenderWindow (this->VtkView3->GetRenderWindow()); this->View1->SetRenderer (rend1); this->View2->SetRenderer (rend2); this->View3->SetRenderer (rend3); rend1->Delete(); rend2->Delete(); rend3->Delete(); this->Image = 0; this->FirstRender = 0; this->ImageDim[0] = 0; this->ImageDim[1] = 0; this->ImageDim[2] = 0; this->ImageOrigin[0] = 0; this->ImageOrigin[1] = 0; this->ImageOrigin[2] = 0; this->ImageCenter[0] = 0; this->ImageCenter[1] = 0; this->ImageCenter[2] = 0; this->AcquisitionFlag = ACQ_AXIAL; this->AxesFlipped[0] = 0; this->AxesFlipped[1] = 0; this->AxesFlipped[2] = 0; this->Reslicer = vtkImageReslice::New(); this->Reslicer->InterpolateOff(); this->SetProperties(); this->DoLayout(); } wxVtkImageFlip::~wxVtkImageFlip() { this->View1->Detach(); this->View2->Detach(); this->View3->Detach(); this->VtkView1->Delete(); this->VtkView2->Delete(); this->VtkView3->Delete(); this->View1->Delete(); this->View2->Delete(); this->View3->Delete(); this->Reslicer->Delete(); } void wxVtkImageFlip::SetProperties() { this->View1->SetBackgroundColor (0.0, 0.0, 0.0); this->View2->SetBackgroundColor (0.0, 0.0, 0.0); this->View3->SetBackgroundColor (0.0, 0.0, 0.0); this->View1->SetAboutData ("AXIAL"); this->View2->SetAboutData ("CORONAL"); this->View3->SetAboutData ("SAGITTAL"); this->View1->SetOrientation( vtkViewImage2D::AXIAL_ID); this->View2->SetOrientation( vtkViewImage2D::CORONAL_ID); this->View3->SetOrientation( vtkViewImage2D::SAGITTAL_ID); this->View1->AddChild (this->View2); this->View2->AddChild (this->View3); this->View3->AddChild (this->View1); this->View1->SetShowAnnotations (false); this->View2->SetShowAnnotations (false); this->View3->SetShowAnnotations (false); } void wxVtkImageFlip::DoLayout() { wxBoxSizer* sizermain = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sizerviews = new wxBoxSizer (wxHORIZONTAL); wxBoxSizer* sizerbuttons = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sizerOK = new wxBoxSizer(wxHORIZONTAL); sizerviews ->Add (this->VtkView1, 1, wxALL|wxEXPAND, 5); sizerviews ->Add (this->VtkView2, 1, wxALL|wxEXPAND, 5); sizerviews ->Add (this->VtkView3, 1, wxALL|wxEXPAND, 5); sizerbuttons ->Add (this->AcquisitionTxt, 0, wxALL|wxFIXED_MINSIZE, 5); sizerbuttons ->Add (this->ComboAcquisition, 0, wxALL|wxFIXED_MINSIZE, 5); sizerbuttons ->Add (this->ButtonFlipFH, 0, wxALL|wxEXPAND, 5); sizerbuttons ->Add (this->ButtonFlipRL, 0, wxALL|wxEXPAND, 5); sizerbuttons ->Add (this->ButtonFlipAP, 0, wxALL|wxEXPAND, 5); sizerOK ->Add (this->ButtonSave, 0, wxALL|wxEXPAND, 5); sizerOK ->Add (this->ButtonCANCEL, 0, wxALL|wxEXPAND, 5); sizerOK ->Add (this->ButtonOK, 0, wxALL|wxEXPAND, 5); sizermain ->Add (sizerviews, 1, wxALL|wxEXPAND, 0); sizermain ->Add (sizerbuttons, 0, wxCENTER, 0); sizermain ->Add (sizerOK, 0, wxALIGN_RIGHT, 0); this->SetAutoLayout(true); this->SetSizerAndFit (sizermain); this->SetSize (wxSize (700,400)); this->Layout(); } BEGIN_EVENT_TABLE (wxVtkImageFlip, wxDialog) EVT_COMBOBOX (COMBOBOX_ACQ, wxVtkImageFlip::OnComboAcquisition) EVT_BUTTON (BUTTON_FLIPRL, wxVtkImageFlip::OnButtonFlipRL) EVT_BUTTON (BUTTON_FLIPAP, wxVtkImageFlip::OnButtonFlipAP) EVT_BUTTON (BUTTON_FLIPFH, wxVtkImageFlip::OnButtonFlipFH) EVT_BUTTON (BUTTON_CANCEL, wxVtkImageFlip::OnButtonCANCEL) EVT_BUTTON (BUTTON_OK, wxVtkImageFlip::OnButtonOK) EVT_BUTTON (BUTTON_SAVE, wxVtkImageFlip::OnButtonSave) END_EVENT_TABLE() void wxVtkImageFlip::OnButtonFlipFH(wxCommandEvent &event) { if (!this->Image) return; unsigned int direction = this->View1->GetOrthogonalAxis (vtkViewImage::AXIAL_ID); this->AxesFlipped[direction] = !this->AxesFlipped[direction]; this->UpdateReslicer(); this->Synchronize(); } void wxVtkImageFlip::OnButtonFlipRL(wxCommandEvent &event) { if (!this->Image) return; unsigned int direction = this->View1->GetOrthogonalAxis (vtkViewImage::SAGITTAL_ID); this->AxesFlipped[direction] = !this->AxesFlipped[direction]; this->UpdateReslicer(); this->Synchronize(); } void wxVtkImageFlip::OnButtonFlipAP(wxCommandEvent &event) { if (!this->Image) return; unsigned int direction = this->View1->GetOrthogonalAxis (vtkViewImage::CORONAL_ID); this->AxesFlipped[direction] = !this->AxesFlipped[direction]; this->UpdateReslicer(); this->Synchronize(); } void wxVtkImageFlip::SetImage (vtkImageData* image) { if (!image) return; this->Image = image; image->GetDimensions (this->ImageDim); image->GetOrigin (this->ImageOrigin); image->GetCenter (this->ImageCenter); image->GetWholeExtent (this->ImageExtent); image->GetSpacing (this->ImageSpacing); this->Reslicer->SetInput (image); this->Reslicer->SetOutputExtentToDefault(); this->Reslicer->SetOutputSpacingToDefault(); this->Reslicer->SetOutputOriginToDefault(); this->View1->SetImage (this->Reslicer->GetOutput()); this->View2->SetImage (this->Reslicer->GetOutput()); this->View3->SetImage (this->Reslicer->GetOutput()); this->UpdateReslicer(); this->Synchronize(); } void wxVtkImageFlip::OnButtonSave (wxCommandEvent &event) { wxFileDialog* myFileDialog = new wxFileDialog(this, "Save image as", wxT(""), wxT(""), wxT ("Image File (*.hdr;*.inr;*.inr.gz;*.gipl;*.mha;*.jpg;*.tif)|*.hdr;*.inr;*.inr.gz;*.gipl;*.mha;*.jpg;*.tif|") wxT ("Analyze (*.hdr)|*.hdr|") wxT ("Inrimage (*.inr;*.inr.gz)|*.inr;*.inr.gz|") wxT ("Gipl (*.gipl)|*.gipl|") wxT ("Metafile (*.mha)|*.mha|") wxT ("Jpeg (*.jpg;*.jpeg)|*.jpg;*.jpeg|") wxT ("Tiff (*.tif;*.tiff)|*.tif;*.tiff|") wxT ("All (*.*)|*.*"), wxFD_SAVE|wxFD_CHANGE_DIR|wxFD_OVERWRITE_PROMPT, wxDefaultPosition); wxString filename; filename.Empty(); int OK = myFileDialog->ShowModal(); if( OK==wxID_OK ) { filename = myFileDialog->GetPath(); } myFileDialog->Destroy(); if( filename.IsEmpty() ) { return; } std::string s_filename (filename.c_str()); vtksys_stl::string ext = vtksys::SystemTools::GetFilenameLastExtension (s_filename); if( ext=="" ) { wxMessageDialog* myDialog = new wxMessageDialog(this, wxT("Please specify a supported extension."), wxT ("Error"), wxOK|wxICON_WARNING); myDialog->ShowModal(); myDialog->Destroy(); return; } itk::AnalyzeImageIOFactory::RegisterOneFactory(); typedef itk::Image IntegerImageType; itk::VTKImageToImageFilter::Pointer MyConverter = itk::VTKImageToImageFilter::New(); MyConverter->SetInput (this->View1->GetImage()); try { MyConverter->Update(); } catch(itk::ExceptionObject &e) { std::cerr << e << std::endl; wxMessageDialog* myDialog = new wxMessageDialog(this, wxT("Cannot write file !"), wxT ("Error"), wxOK|wxICON_ERROR); myDialog->ShowModal(); myDialog->Destroy(); return; } itk::Matrix cosines; cosines[0][0]= 1; cosines[0][1]= 0; cosines[0][2]= 0; cosines[1][0]= 0; cosines[1][1]=-1; cosines[1][2]= 0; cosines[2][0]= 0; cosines[2][1]= 0; cosines[2][2]= 1; IntegerImageType::Pointer itkimage = const_cast(MyConverter->GetOutput()); itkimage->SetDirection(cosines); itk::ImageFileWriter::Pointer MyWriter; MyWriter = itk::ImageFileWriter::New(); MyWriter->SetFileName (filename.c_str()); MyWriter->SetInput (MyConverter->GetOutput()); IntegerImageType::Pointer image = const_cast(MyConverter->GetOutput()); try { std::cout << "Writing: " << filename.c_str() << std::endl; MyWriter->Write(); } catch(itk::ExceptionObject &e) { std::cerr << e << std::endl; wxMessageDialog* myDialog = new wxMessageDialog(this, wxT("Cannot write file !"), wxT ("Error"), wxOK|wxICON_ERROR); myDialog->ShowModal(); myDialog->Destroy(); return; } } void wxVtkImageFlip::OnButtonCANCEL (wxCommandEvent &event) { EndModal(wxID_CANCEL); } void wxVtkImageFlip::OnButtonOK (wxCommandEvent &event) { EndModal(wxID_OK); } void wxVtkImageFlip::OnComboAcquisition(wxCommandEvent &event) { unsigned int flag = this->ComboAcquisition->GetSelection(); this->AcquisitionFlag = flag; this->UpdateReslicer(); this->Synchronize(); } void wxVtkImageFlip::UpdateReslicer (void) { if (!this->Image) { return; } int newaxes[3] = { 0, 1, 2 }; double I[3][3] = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }; double resliceorigin[3] = { 0, 0, 0 }; switch (this->AcquisitionFlag) { case ACQ_AXIAL: break; case ACQ_SAGITTAL: newaxes[0] = 2; newaxes[1] = 0; newaxes[2] = 1; break; case ACQ_CORONAL: newaxes[0] = 0; newaxes[1] = 2; newaxes[2] = 1; break; } for (unsigned int i=0; i<3; i++) { if (AxesFlipped[i]) { I[newaxes[i]][newaxes[i]]=-1; resliceorigin[newaxes[i]] = 2*this->ImageOrigin[newaxes[i]] + this->ImageSpacing[newaxes[i]]* (this->ImageExtent[2*newaxes[i]] + this->ImageExtent[2*newaxes[i]+1]); } } this->Reslicer->SetResliceAxesDirectionCosines( I[newaxes[0]], I[newaxes[1]], I[newaxes[2]]); this->Reslicer->SetResliceAxesOrigin (resliceorigin); } void wxVtkImageFlip::Synchronize (void) { if (!this->Image) return; this->Reslicer->Modified(); this->Reslicer->UpdateWholeExtent(); //this->Reslicer->GetOutput()->UpdateInformation(); this->View1->Update(); this->View2->Update(); this->View3->Update(); this->View1->SyncResetCurrentPoint(); this->View1->SyncResetWindowLevel(); this->View1->ResetCamera(); this->View2->ResetCamera(); this->View3->ResetCamera(); if( !this->View1->GetRenderWindow()->GetNeverRendered() ) this->View1->Render(); if( !this->View2->GetRenderWindow()->GetNeverRendered() ) this->View2->Render(); if( !this->View1->GetRenderWindow()->GetNeverRendered() ) this->View2->Render(); }