180 likes | 369 Views
Slicer and ITK generic image reader module . Alex Yarmarkovich. Goal. Use extensive ITK IO library in Slicer . Supported image file formats: Meta PNG VTK Gipl Analyze Stimulate JPEG TIFF Nrrd BMP DICOM2 . ITK -> VTK -> Slicer . Architecture:.
E N D
Slicer and ITK generic image reader module Alex Yarmarkovich
Goal • Use extensive ITK IO library in Slicer. • Supported image file formats: • Meta • PNG • VTK • Gipl • Analyze • Stimulate • JPEG • TIFF • Nrrd • BMP • DICOM2
ITK -> VTK -> Slicer Architecture: Generic Reader Module TCL / TK Slicer vtkITKArchetypeImageSeriesReader VTK itk::ImageSeriesReader itk::ImageFileReader ITK
ITK image readers • Itk::ImageFileReader • uses itk::ImageIOFactory to create specific file format reader • Itk::ImageFileSeriesReader • internally uses itk::imageFileReader for reading single images • given one file name generates names for the series
vtkITKArchetypeImageSeriesReader • Encapsulates ITK pipeline • Outputs VTK image: vtkImageData • Extends vtkImageSource • Sets filename template: vtkSetStringMacro(Archetype); vtkGetStringMacro(Archetype); • Sets image data type (float, char, etc.) • Uses itk::ImageFileSeriesReader or itk::ImageFileReader
vtkITKArchetypeImageSeriesReader • ExecuteInformation() methods reads one image and outputs image metadata: origin, spacing, etc. • ExecuteData(vtkDataObject *output) method reads in image data
vtkITKArchetypeImageSeriesReader • if (this->FileNames.size() == 1) • { • switch (this->OutputScalarType) • { • vtkITKExecuteDataFromFile(VTK_DOUBLE, double); • vtkITKExecuteDataFromFile(VTK_FLOAT, float); • vtkITKExecuteDataFromFile(VTK_LONG, long); • vtkITKExecuteDataFromFile(VTK_UNSIGNED_LONG, unsigned long); • vtkITKExecuteDataFromFile(VTK_INT, int); • vtkITKExecuteDataFromFile(VTK_UNSIGNED_INT, unsigned int); • vtkITKExecuteDataFromFile(VTK_SHORT, short); • vtkITKExecuteDataFromFile(VTK_UNSIGNED_SHORT, unsigned short); • vtkITKExecuteDataFromFile(VTK_CHAR, char); • vtkITKExecuteDataFromFile(VTK_UNSIGNED_CHAR, unsigned char); • default: • vtkErrorMacro(<< "UpdateFromFile: Unknown data type"); • } • }
vtkITKArchetypeImageSeriesReader • #define vtkITKExecuteDataFromFile(typeN, type) \ • case typeN: \ • {\ • typedef itk::Image<type,3> image2##typeN;\ • itk::ImageFileReader<image2##typeN>::Pointer reader2##typeN = \ • itk::ImageFileReader<image2##typeN>::New(); \ • reader2##typeN->SetFileName(this->FileNames[0].c_str()); \ • reader2##typeN->UpdateLargestPossibleRegion();\ • itk::ImportImageContainer<unsigned long, type>::Pointer PixelContainer2##typeN;\ • PixelContainer2##typeN = reader2##typeN->GetOutput()->GetPixelContainer();\ • void *ptr = static_cast<void *> (PixelContainer2##typeN->GetBufferPointer());\ • (dynamic_cast<vtkImageData *>( output))->GetPointData()->GetScalars()->SetVoidArray(ptr, PixelContainer2##typeN->Size(), 0);\ • PixelContainer2##typeN->ContainerManageMemoryOff();\ • }\ • break
vtkITKArchetypeImageSeriesReader • Expended and beatified macro : • case VTK_INT: • { • typedef itk::Image<int,3> imageType; • itk::ImageFileReader<imageType>::Pointer reader = • itk::ImageFileReader< imageType>::New(); • reader->SetFileName(this->FileNames[0].c_str()); • reader->UpdateLargestPossibleRegion(); itk::ImportImageContainer<unsigned long, int>::Pointer pixelContainer; pixelContainer = reader->GetOutput()->GetPixelContainer(); • void *ptr = static_cast<void *> (pixelContainer->GetBufferPointer()); • (dynamic_cast<vtkImageData *>( output))->GetPointData()-> GetScalars()->SetVoidArray(ptr, pixelContainer->Size(), 0);\ • pixelContainer->ContainerManageMemoryOff();\ • } • break
Generic Reader Module • Tcl procedures: • VolGenericInit – sets callbacks and defaults in Volume(readerModules, volGeneric, xxx) • VolGenericBuildGUI – creates UI menus • VolGenericApply – populates Volume MRML node with metadata: Volume(1,node) • VolGenericReaderProc – populates Volume with data: Volume(1,vol). Called both from the reader and the Scene Loader.
VolGenericInit proc VolGenericInit {} { global Gui VolGeneric Volume Slice Module if {$Module(verbose) == 1} {puts "VolGenericInit starting"} set e VolGeneric set Volume(readerModules,$e,name) "Generic Readers" set Volume(readerModules,$e,tooltip) "This tab lets you read in Generic volumes" set Volume(readerModules,$e,procGUI) ${e}BuildGUI ;#called in MainBoot set Volume(readerModules,$e,procEnter) ${e}Enter ;# called when module UI is exposed set Volume(readerModules,$e,procExit) ${e}Exit ;# called when module UI is hidden set Volume(VolGeneric,idList) "" # for closing out a scene set Module($e,procMainFileCloseUpdateEntered) VolGenericMainFileCloseUpdate # register the procedures in this file that will read in volumes set Module(Volumes,readerProc,Generic) VolGenericReaderProc }
VolGenericBuildGUI proc VolGenericBuildGUI {parentFrame} { global Gui Volume Module set f $parentFrame.fVolume DevAddFileBrowse $f Volume firstFile "First Image File:" "VolumesSetFirst" "" "\$Volume(DefaultDir)" "Open" "Browse for the first Image file" "Browse to the first file in the volume" "Absolute" frame $f.fLabelMap -bg $Gui(activeWorkspace) frame $f.fDesc -bg $Gui(activeWorkspace) frame $f.fName -bg $Gui(activeWorkspace) frame $f.fscalarType -bg $Gui(activeWorkspace) pack $f.fLabelMap -side top -padx $Gui(pad) -pady $Gui(pad) -fill x pack $f.fDesc -side top -padx $Gui(pad) -pady $Gui(pad) -fill x pack $f.fName -side top -padx $Gui(pad) -pady $Gui(pad) -fill x pack $f.fscalarType -side top -padx $Gui(pad) -pady $Gui(pad) -fill x
VolGenericBuildGUI # Name row set f $parentFrame.fVolume.fName eval {label $f.lName -text "Name:"} $Gui(WLA) eval {entry $f.eName -textvariable Volume(name) -width 13} $Gui(WEA) pack $f.lName -side left -padx $Gui(pad) pack $f.eName -side left -padx $Gui(pad) -expand 1 -fill x pack $f.lName -side left -padx $Gui(pad)
VolGenericBuildGUI #------------------------------------------- # Apply frame #------------------------------------------- set f $parentFrame.fApply DevAddButton $f.bApply "Apply" "set Volume(fileType) Generic; VolGenericApply; VolumesSetPropertyType VolHeader" 8 DevAddButton $f.bCancel "Cancel" "VolumesPropsCancel" 8 grid $f.bApply $f.bCancel -padx $Gui(pad)
VolGenericApply # add a mrml node set n [MainMrmlAddNode Volume] set i [$n GetID] # read image metadata vtkITKArchetypeImageSeriesReader genreader genreader SetArchetype $Volume(VolGeneric,FileName) genreader SetOutputScalarTypeTo$Volume(scalarType) # flip the image data going from ITK to VTK vtkImageFlip Volume($i,vol,rw) Volume($i,vol,rw) SetFilteredAxis 1 Volume($i,vol,rw) SetInput [genreader GetOutput]
VolGenericReaderProc • proc VolGenericReaderProc {v} { • global Volume catch "genreader Delete" • vtkITKArchetypeImageSeriesReader genreader • genreader SetArchetype [Volume($v,node) GetFullPrefix] • genreader SetOutputScalarType [Volume($v,node) GetScalarType] • catch "flip Delete" • vtkImageFlip flip • flip SetFilteredAxis 1 • flip SetInput [genreader GetOutput] • flip Update • Volume($v,vol) SetImageData [flip GetOutput] • flip Delete • genreader Delete }