ITK/Release 4/DICOM/GDCM Tcon Notes: Difference between revisions
No edit summary |
No edit summary |
||
Line 2: | Line 2: | ||
The meeting was on the current and future progress of GDCM/ITK. | The meeting was on the current and future progress of GDCM/ITK. | ||
= | |||
src/gdcm/Utilities/VTK | =src/gdcm/Utilities/VTK= | ||
gvim vtkGDCMPolyDataWriter.h | gvim vtkGDCMPolyDataWriter.h | ||
Line 25: | Line 25: | ||
Example of how to run an RT=-Structure in VTK. | Example of how to run an RT=-Structure in VTK. | ||
GDCM: Failing streaming test | |||
=GDCM: Failing streaming test= | |||
is using a malformed DICOM image. | is using a malformed DICOM image. | ||
Line 40: | Line 40: | ||
Another streaming issue: | =Another streaming issue:= | ||
Line 109: | Line 108: | ||
= | =DICOM files withJPEG= | ||
Line 118: | Line 117: | ||
= | = DICOM Slices= | ||
It is also possible to find DICOM Slices that are composed | It is also possible to find DICOM Slices that are composed | ||
Line 124: | Line 123: | ||
by hand). | by hand). | ||
------- | |||
Line 136: | Line 135: | ||
= | =GDCM StreamingWriting= | ||
The GDCM StreamingWriting is not working at this point. | The GDCM StreamingWriting is not working at this point. | ||
Line 180: | Line 179: | ||
= | =StreamReader in GDCM= | ||
Line 191: | Line 190: | ||
= | =Networking= | ||
Networking | Networking |
Revision as of 14:07, 19 April 2011
Luis Ibanez, Andrew Wasem and Mark Roden were in attendance of this meeting. The meeting was on the current and future progress of GDCM/ITK.
src/gdcm/Utilities/VTK
gvim vtkGDCMPolyDataWriter.h
void vtkGDCMPolyDataWriter::InitializeRTStructSet(vtkStdString inDirectory,
vtkStdString inStructLabel, vtkStdString inStructName, vtkStringArray* inROINames, vtkStringArray*
inROIAlgorithmName,
vtkStringArray* inROIType)
See
/home/ibanez/src/gdcm/Utilities/VTK/Examples/Cxx GenerateRTSTRUCT.cxx
Example of how to run an RT=-Structure in VTK.
GDCM: Failing streaming test
is using a malformed DICOM image.
must change the input image.
replace it with one of the brainsets from the Osirix collection of public data.
Cerebrix.
(apparently this is failing only in an icc build)
Another streaming issue:
~/src/ITK/Modules/ThirdParty/GDCM/src/gdcm/Source/MediaStorageAndFileFormat
gdcmStreamImageReader.h gdcmStreamImageReader.cxx
Limited to uint16:
mXMin = mYMin = mZMin = std::numeric_limits<uint16_t>::max(); mXMax = mYMax = mZMax = std::numeric_limits<uint16_t>::min();
then
uint32_t StreamImageReader::DefineProperBufferLength() const
it is limited uint32_t, in number of bytes.
Then read the actual buffer:
bool StreamImageReader::Read(void* inReadBuffer, const std::size_t& inBufferLength){
(before we call ReadImageInformation)
The class: OffsetTable
ITK/Modules/ThirdParty/GDCM/src/gdcm/Source/DataStructureAndEncodingDefinition
gdcmBasicOffsetTable.h
defines sections (regions) of the image that have been compressed.
The reading code is implemented for RAW files that do not have an offset table.
This could be used to extend GDCM to not have to read a full plane, but instead read a subregion of that plane, and therefore be more compatible with ITK streaming.
bool StreamImageReader::ReadImageSubregionJpegLS(char* inReadBuffer, const std::size_t& inBufferLength) {
This function is used (or was intended for...) to read metadata without reading the pixel data yet.
manages byte swapping:
bool needbyteswap = (ts == TransferSyntax::ImplicitVRBigEndianPrivateGE);
line 244:
theCodec.Decode(de, inReadBuffer, inBufferLength, mXMin, mXMax,
mYMin, mYMax, mZMin, mZMax);
do the decoding by delegates to the JpegLS library.
DICOM files withJPEG
We only have been able to find DICOM files withJPEG, that have a single tile.
(it will be nice to get some with multiple tile).
DICOM Slices
It is also possible to find DICOM Slices that are composed of a group of individual JPEG images. (e.g. like doing tiling by hand).
Tag thePixelDataTag(0x7fe0, 0x0010);//must be LESS than the pixel
information tag, 0x7fe0,0x0010
This is the location where the pixel data buffer.
but in some cases, some images have more tags after this one, and that can confuse the stream reading.
GDCM StreamingWriting
The GDCM StreamingWriting is not working at this point.
(something deep inside of gdcm).
--
gdcmStreamImageWriter.cxx : 346
bool StreamImageWriter::CanWriteFile() const
bool hasTag818 = mFile.GetDataSet().FindDataElement(Tag(0x08,0x18)); if (!hasTag23 && !hasTag818){
When writing a DICOM image, the Tag818 must be different from the one that it was read from. (unless you are an OEM... e.g. the manufacturer of a CT scanner.)
Then, when it gets to
bool StreamImageWriter::WriteImageInformation(){
it fails..
Line 110 describe how to read the tags.
Reading is done in 116.
The problem relates to the offset table...
and how it addresses space inside of the image.
This is mostly a problem when data is compressed. (streaming raw data will be easier, but it is not working now either...the output file is not readable.).
(its MD5 sum for the pixel buffer doesn't match after writing...)
StreamReader in GDCM
The StreamReader in GDCM is intended to be used by the ITK streaming reader.
(apparently the StreamReader is not used outside of ITK).
There is a passing test for stream reading.
Networking
Networking
ITK/Modules/ThirdParty/GDCM/src/gdcm/Source/MessageExchangeDefinition/
gdcmCompositeNetworkFunctions.cxx
static bool CEcho( const char *remote, uint16_t portno, const char
- aetitle = NULL,
const char *call = NULL );
A server will have "titles" (up to 8).
A title is a "computer name", not an IP address. Every title connects to a specific port in the server
CEcho is the basic test function
Then you construct your query:
/// This function will take a list of strings and tags and fill in a
query that
/// can be used for either CFind or CMove (depending on the input boolean /// \param inMove). /// Note that the caller is responsible for deleting the constructed query. /// This function is used to build both a move and a find query /// (true for inMove if it's move, false if it's find) static BaseRootQuery* ConstructQuery(ERootType inRootType,
EQueryLevel inQueryLevel,
const DataSet& queryds, bool inMove = false );
/// \deprecated static BaseRootQuery* ConstructQuery(ERootType inRootType,
EQueryLevel inQueryLevel,
const KeyValuePairArrayType& keys, bool inMove = false );
(it requires a fully form dataset).
BaseRootQuery = abstract class
2 types of queries : find & move
"find" can be using a very generic expression. (can have wildcards).
ITK/Modules/ThirdParty/GDCM/src/gdcm/Source/MessageExchangeDefinition
gdcmFindPatientRootQuery.h
First figure out what tags are available:
std::vector<Tag> GetTagListByLevel(const EQueryLevel& inQueryLevel);
this ties up to the "image interpretation layer" to the point where
a juser can get this list of Tags and then select values from them
to put them in a query and using to get actual data.
"move" queries are more strict than "find" ones
(can't have wildcards).
This search will fail if it is not fully specified.
gdcmCompositeNetworkFunctions.cxx
bool CompositeNetworkFunctions::CStore( const char *remote, uint16_t portno,
const Directory::FilenamesType& filenames, const char *aetitle, const char *call)
267
CStore command will move images to a server.
gdcmServiceClassUser.h
bool SendMove(const BaseRootQuery* query, const char *outputdir); bool SendMove(const BaseRootQuery* query, std::vector<DataSet> &retDatasets);
allows to put data directly into memory.
(pending a refactoring in which the concept of
a DICOM file was planned to be abstracted...)
ITK application, creating an itk::Image using data from a remote server.
(list of use cases in another email from Mark...)
In order to define ITK functionalities, we
should specify a list of clear use cases....
(Review emails from DICOM Taskforce February 23-24)
(post the use cases in a Wiki page).
We should get a tcon with the group interested in DICOM, flesh out use cases, come up with a design for an ITK API (and a support GDCM API).