DICOM file reader. More...
#include <VolumeViz/readers/SoVRDicomFileReader.h>
Public Member Functions | |
virtual SoType | getTypeId () const |
SoVRDicomFileReader () | |
virtual int | setFilename (const SbString &filename) |
int | setFilenamePattern (const SbString &pattern) |
int | setFilenameList (const SbStringList &filenameList) |
SbBool | setFilenameList (const SbString &format, const int startIndex=0, const int endIndex=INT_MAX, const int indexStep=1) |
bool | setFilenameListFromSeries (const SbString &base) |
void | loadInMemory () |
SbBool | setDirectory (const SbString &folder) |
virtual ReadError | getDataChar (SbBox3f &size, SoDataSet::DataType &type, SbVec3i32 &dim) |
virtual SbBool | setOutputDataType (SbBool doChange, SoDataSet::DataType type) |
virtual void | getSubSlice (const SbBox2i32 &subSlice, int sliceNumber, void *data) |
int | getNumSignificantBits () |
virtual SoVolumeReader::ReaderType | getReaderType () |
const SoVRDicomData & | getDicomData () const |
const SiDicomDataSet * | getDicomDataSet (const size_t sliceIdx) const |
void | loadSliceDicomData (int slice, SoVRDicomData &dicomData) const |
virtual SbBool | isThreadSafe () const |
virtual void | closeAllHandles () |
virtual void | restoreAllHandles () |
Static Public Member Functions | |
static SoType | getClassTypeId () |
Volume reader for the DICOM file format. VolumeViz automatically selects this reader if a filename is given and the file extension is ".dc3", ".dic", ".dcm", or ".dicom".
DICOM is a widely used format for storing medical image data (CT, MRI, etc), defined by the National Electrical Manufacturers Association (NEMA) (http://medical.nema.org).
SoVRDicomFileReader can load a volume from a single DICOM file or from a list of DICOM files (stack of images). Loading a volume from a single DICOM file is the same as loading any other format supported by VolumeViz (see setFilename(const SbString& filename)). Loading a volume from a list of DICOM files can be done by:
Unlike a raster stack, the position of each slice in a DICOM volume is determined by the location value in its file header and not by the order of the file name in the list. Also unlike a raster stack consisting of (for example) JPEG or PNG images, a DICOM file in the list may contain more than one slice of the volume. The reader handles this automatically. The first file in the list is considered the "reference" for the volume and all slices must be compatible with this one. Specifically this means that subsequent files must have the same width, height, data type and so on.
Note when using a list file: If the file extension is not ".dc3", ".dic" or ".dicom" VolumeViz will not automatically select the DICOM volume reader. You can either give the list file one of the DICOM file extensions or force VolumeViz to use the DICOM reader by explicitly creating an instance of SoVRDicomFileReader and calling the SoVolumeData method setReader().
The volume reader will automatically get the volume dimensions, data type, extent (voxel size/spacing) and number of significant bits from the DICOM file header. The reader will also apply the data adjustment (if any) specified by the RescaleSlope and RescaleIntercept tags in the DICOM file header, i.e.: actualValue = slope * storedValue + intercept. As part of this process the reader will automatically convert unsigned data to the corresponding signed data type if necessary (in other words if the rescale calculation produces negative values). The application can also explicitly specify the volume data type. This allows, for example, converting float data values to more compact integer values.
Note: The DICOM reader only uses the rescale slope and intercept values from the first file in the list. It does not currently handle the (less common) case where each file contains different rescale values.
Photometric Interpretation:
Volume extent:
The volume reader will compute the volume's width in X and height in Y from the volume dimensions and the voxel size. For example, if the volume dimension in X is 512 (voxels) and the voxel size in X is 0.408 mm, then the volume width is (approximately) 209 mm. The reader will compute the volume's depth in Z from the min and max slice locations specified in the file header(s). Note that for a DICOM data set, the volume 'position' is considered to be the center of the first voxel, however VolumeViz considers the volume extent (SoVolumeData::extent) to include all of the first and last voxels. Therefore the extent 'min' is alwaya the outside corner of the first voxel.
Data Range:
Use an SoDataRange node to specify the actual (or desired) range of data values to be mapped. For example, a typical initial data range for DICOM data calibrated in Hounsfield units might be -1000 to 3000.
Coordinate Systems:
In a medical imaging application there are at least three related coordinate systems.
In other words, the default camera view is looking at the top of the head with the body "face down".
When viewing a slice, also remember that the volume is always a 3D object to Open Inventor and you must also set the 'axis' field on the SoOrthoSlice node. See the dicomImageViewer example in the examples/source/Medical/Input directory.
DICOM Attributes
All DICOM attributes, including hierarchical data like Structured Reports, can be traversed and queried using SiDicomDataSet (see getDicomDataSet()). See the DicomSimpleViewer example in the examples/source/VolumeViz/examples directory.
MedicalDicomReader, MedicalDTIViewer, MedicalFreeHandCutting
SoVRDicomFileReader::SoVRDicomFileReader | ( | ) |
Constructor.
virtual void SoVRDicomFileReader::closeAllHandles | ( | ) | [virtual] |
Close all file handles currently opened by the reader.
Reimplemented from SoVolumeReader.
static SoType SoVRDicomFileReader::getClassTypeId | ( | ) | [static] |
Returns the type identifier for this class.
Reimplemented from SoVolumeReader.
virtual ReadError SoVRDicomFileReader::getDataChar | ( | SbBox3f & | size, | |
SoDataSet::DataType & | type, | |||
SbVec3i32 & | dim | |||
) | [virtual] |
Gets the characteristics (file header) of the data volume.
See SoVolumeData. size is the size of the actual volume. type is the type of the data. dim is the dimension of the data.
Implements SoVolumeReader.
const SoVRDicomData& SoVRDicomFileReader::getDicomData | ( | ) | const |
Returns an instance of SoVRDicomData for the first image of this volume.
Note that the first image of the volume does not necessarily correspond to first file of file list. Images are automatically sorted using the Image Postion Patient attribute.
This object can be queried for DICOM specific info, using for example the SoVRDicomData::getDicomInfo() method.
To conveniently access the DICOM attributes, see getDicomDataSet() method.
const SiDicomDataSet* SoVRDicomFileReader::getDicomDataSet | ( | const size_t | sliceIdx | ) | const |
Returns a DICOM data object for the specified slice containing all the DICOM attributes.
sliceIdx | The index of the slice to extract the dataset from. |
int SoVRDicomFileReader::getNumSignificantBits | ( | ) | [virtual] |
This method is optional.
It returns the number of significant bits of the volume data.
If it is not implemented, the default return value is 0, meaning the number of bits depends on the data type. See the last parameter of SoVolumeData::setVolumeData(). This method is called immediately after getDataChar().
Reimplemented from SoVolumeReader.
virtual SoVolumeReader::ReaderType SoVRDicomFileReader::getReaderType | ( | ) | [inline, virtual] |
Returns the reader type.
Reimplemented from SoVolumeReader.
virtual void SoVRDicomFileReader::getSubSlice | ( | const SbBox2i32 & | subSlice, | |
int | sliceNumber, | |||
void * | data | |||
) | [virtual] |
New method required by VolumeViz 3.0 when using large volume support.
Must copy a rectangular part of an XY slice to the memory specified by data. Slices will not always be read sequentially.
Implements SoVolumeReader.
virtual SoType SoVRDicomFileReader::getTypeId | ( | ) | const [virtual] |
Returns the type identifier for this specific instance.
Reimplemented from SoVolumeReader.
virtual SbBool SoVRDicomFileReader::isThreadSafe | ( | ) | const [virtual] |
SoVRDicomFileReader is thread safe.
Reimplemented from SoVolumeReader.
void SoVRDicomFileReader::loadInMemory | ( | ) |
Load the DICOM data into contiguous memory if possible.
Once the data is loaded, no additional file I/O is necessary and data access calls to the reader, e.g. getSubSlice(), will be fast.
Example:
SoVRDicomFileReader* volReader = new SoVRDicomFileReader(); volReader->setFilename( VOLUME_FILENAME ); volReader->loadInMemory(); SoVolumeData* volData = new SoVolumeData(); volData->setReader( *volReader ); MedicalHelper::dicomAdjustVolume( volData );
Notes:
void SoVRDicomFileReader::loadSliceDicomData | ( | int | slice, | |
SoVRDicomData & | dicomData | |||
) | const |
Loads the Dicom data of the given slice.
To conveniently access the DICOM attributes, see getDicomDataSet method.
virtual void SoVRDicomFileReader::restoreAllHandles | ( | ) | [virtual] |
Restore all file handles closed by closeAllHandles method.
Reimplemented from SoVolumeReader.
Specify a directory containing DICOM files to load.
Each file in this folder that has a supported extension (currently ".dc3", ".dic", ".dcm", or ".dicom") will be loaded. If the DICOM files have an unsupported extension, use the setFilenameList function instead.
All the DICOM files in the specified directory should be part of the same volume data set. If not, the results are undefined.
folder | The folder from which to load files. |
virtual int SoVRDicomFileReader::setFilename | ( | const SbString & | filename | ) | [virtual] |
Specify the name of a DICOM file or a file containing a list of DICOM files to load.
Using a list file is the same as loading a stack of images using the SoVRRasterStackReader except the list file should not contain any header. Each line in the list file may be a full path containing directory names or a simple file name. Simple file names are assumed to be in the same directory as the list file. The application can also specify a list of file paths using the setFilenameList() method. This is useful, for example, if the application user is allowed to select a list of files in a file selection dialog. All the specified files should be part of the same volume data set.
Returns 0 if successful.
Reimplemented from SoVolumeReader.
SbBool SoVRDicomFileReader::setFilenameList | ( | const SbString & | format, | |
const int | startIndex = 0 , |
|||
const int | endIndex = INT_MAX , |
|||
const int | indexStep = 1 | |||
) |
Specify a list of DICOM files to load, using a sprintf-like format.
This will iterate from startIndex to endIndex (included) with increment of indexStep. For each step, this will add a file of name f, where f is format sprintf-ed with the current iteration index. All the specified files should be part of the same volume data set.
format | The format of the file name, which must be an absolute file path. e.g. "c:/testData/Brain.%04d.dcm", where "%04d" will be replaced by the current index, producing "c:/testData/Brain.0000.dcm" and so on. | |
startIndex | The index of the first file to add | |
endIndex | The index of the last file to add | |
indexStep | the stride to use (e.g. 2 will skip one out of two files, by generating indices 0, 2, 4, ...) |
int SoVRDicomFileReader::setFilenameList | ( | const SbStringList & | filenameList | ) |
Specify a list of DICOM files to load.
All the specified files should be part of the same volume data set. Returns 0 if successful.
Note: SbStringList is a list of pointers, not a list of objects, so the destructor for this class does not free the memory associated with the SbString objects. The application is responsible for deleting each object in the list.
Since Open Inventor 9.0bool SoVRDicomFileReader::setFilenameListFromSeries | ( | const SbString & | base | ) |
Specify a DICOM file and load all image files in the same directory that are part of the same "series" based on the series UID (0x0020,0x000E).
base | The path to a DICOM image file. |
int SoVRDicomFileReader::setFilenamePattern | ( | const SbString & | pattern | ) |
Specify a pattern of DICOM files to load.
pattern | e.g. "data_directory/image_file*.dcm" |
virtual SbBool SoVRDicomFileReader::setOutputDataType | ( | SbBool | doChange, | |
SoDataSet::DataType | type | |||
) | [virtual] |
Requests that the input be converted (if necessary) to the specified data type.
This allows, for instance, conversion of float data to unsigned byte. By default no conversion is done. If doChange is FALSE no type conversion is done. Always returns TRUE.
Reimplemented from SoVolumeReader.