1. 程式人生 > >VTK實現Dicom檔案的讀取及顯示

VTK實現Dicom檔案的讀取及顯示

VTK提供了vtkDICOMImageReader類來讀取DICOM檔案,但沒有提供DICOM影象的寫操作,即沒有提供vtkDICOMImageWriter類,ITK提供了對DICOM檔案的完整操作,我們可以結合ITK來實現DICOM檔案完整的讀寫操作。

vtkDICOMImageReader類使用也比較簡單,讀取單幀DICOM影象和其他影象讀取類的使用方法類似,我們這裡重點關注一下多幀DICOM影象的讀取,即讀取一個資料夾中所有的DICOM檔案進行顯示。

#include <vtkSmartPointer.h>
#include <vtkObjectFactory.h>
#include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkRenderer.h> #include <vtkActor.h> #include <vtkImageViewer2.h> #include <vtkDICOMImageReader.h> #include <vtkInteractorStyleImage.h> #include <vtkActor2D.h> #include <vtkTextProperty.h>
#include <vtkTextMapper.h> #include <sstream> #include <iostream> using namespace std; class StatusMessage { public: static std::string Format(int slice, int maxSlice) { std::stringstream tmp; tmp << "Slice Number " << slice + 1 << "/" << maxSlice + 1
; return tmp.str(); } }; class myvtkInteractorStyleImage: public vtkInteractorStyleImage { public: static myvtkInteractorStyleImage* New(); vtkTypeMacro(myvtkInteractorStyleImage, vtkInteractorStyleImage); protected: vtkImageViewer2* _ImageViewer; vtkTextMapper* _StatusMapper; int _Slice; int _MinSlice; int _MaxSlice; public: void SetImageViewer(vtkImageViewer2* imageViewer) { _ImageViewer = imageViewer; _MinSlice = imageViewer->GetSliceMin(); _MaxSlice = imageViewer->GetSliceMax(); _Slice = _MinSlice; cout << "Slice: Min = " << _MinSlice << ", Max = " << _MaxSlice << endl; } void SetStatusMapper(vtkTextMapper* statusMapper) { _StatusMapper = statusMapper; } protected: void MoveSliceForward() { if (_Slice < _MaxSlice) { _Slice += 1; cout << "MoveSliceForward::Slice = " << _Slice << endl; _ImageViewer->SetSlice(_Slice); std::string msg = StatusMessage::Format(_Slice, _MaxSlice); _StatusMapper->SetInput(msg.c_str()); _ImageViewer->Render(); } } void MoveSliceBackward() { if (_Slice > _MinSlice) { _Slice -= 1; cout << "MoveSliceBackward::Slice = " << _Slice << endl; _ImageViewer->SetSlice(_Slice); std::string msg = StatusMessage::Format(_Slice, _MaxSlice); _StatusMapper->SetInput(msg.c_str()); _ImageViewer->Render(); } } virtual void OnKeyDown() { std::string key = this->GetInteractor()->GetKeySym(); if (key.compare("Up") == 0) MoveSliceForward(); else if (key.compare("Down")==0) { MoveSliceBackward(); } vtkInteractorStyleImage::OnKeyDown(); } virtual void OnMouseWheelForward() { MoveSliceForward(); } virtual void OnMouseWheelBackward() { if (_Slice > _MinSlice) MoveSliceBackward(); } }; vtkStandardNewMacro(myvtkInteractorStyleImage); int main(int argc, char* argv[]) { std::string folder = "G:\\Dicom\\Dicom File\\dcmFile"; vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New(); reader->SetDirectoryName(folder.c_str()); reader->Update(); vtkSmartPointer<vtkImageViewer2> imageViewer = vtkSmartPointer<vtkImageViewer2>::New(); imageViewer->SetInputConnection(reader->GetOutputPort()); vtkSmartPointer<vtkTextProperty> sliceTextProp = vtkSmartPointer<vtkTextProperty>::New(); sliceTextProp->SetFontFamilyToCourier(); sliceTextProp->SetFontSize(20); sliceTextProp->SetVerticalJustificationToBottom(); sliceTextProp->SetJustificationToLeft(); vtkSmartPointer<vtkTextMapper> sliceTextMapper = vtkSmartPointer<vtkTextMapper>::New(); std::string msg = StatusMessage::Format(imageViewer->GetSliceMin(), imageViewer->GetSliceMax()); sliceTextMapper->SetInput(msg.c_str()); sliceTextMapper->SetTextProperty(sliceTextProp); vtkSmartPointer<vtkActor2D> sliceTextActor = vtkSmartPointer<vtkActor2D>::New(); sliceTextActor->SetMapper(sliceTextMapper); sliceTextActor->SetPosition(15, 10); vtkSmartPointer<vtkTextProperty> usageTextProp = vtkSmartPointer<vtkTextProperty>::New(); usageTextProp->SetFontFamilyToCourier(); usageTextProp->SetFontSize(14); usageTextProp->SetVerticalJustificationToTop(); usageTextProp->SetJustificationToLeft(); vtkSmartPointer<vtkTextMapper> usageTextMapper = vtkSmartPointer<vtkTextMapper>::New(); usageTextMapper->SetInput("- Slice with mouse wheel\n or Up/Down-Key\n- Zoom with pressed right\n mouse button while dragging"); usageTextMapper->SetTextProperty(usageTextProp); vtkSmartPointer<vtkActor2D> usageTextActor = vtkSmartPointer<vtkActor2D>::New(); usageTextActor->SetMapper(usageTextMapper); usageTextActor->GetPositionCoordinate()->SetCoordinateSystemToNormalizedDisplay(); usageTextActor->GetPositionCoordinate()->SetValue(0.05, 0.95); vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<myvtkInteractorStyleImage> myInteractorStyle = vtkSmartPointer<myvtkInteractorStyleImage>::New(); myInteractorStyle->SetImageViewer(imageViewer); myInteractorStyle->SetStatusMapper(sliceTextMapper); imageViewer->SetupInteractor(renderWindowInteractor); renderWindowInteractor->SetInteractorStyle(myInteractorStyle); imageViewer->GetRenderer()->AddActor2D(sliceTextActor); imageViewer->GetRenderer()->AddActor2D(usageTextActor); imageViewer->GetRenderWindow()->SetSize(800, 600); imageViewer->SetColorLevel(100); imageViewer->SetColorWindow(2000); imageViewer->Render(); imageViewer->GetRenderer()->ResetCamera(); renderWindowInteractor->Start(); return EXIT_SUCCESS; }