Search code examples
dicomitkgdcm

How do I read a DICOM tag within another tag with ITK?


I'm using ITK to read a DICOM file, calling

dicomIO->GetValueFromTag(...)

to read a tag value. This works fine for tags like "300a|011e" (gantry angle). The problem comes trying to read tag "0018|0060" which is embedded inside "3002|0030".

If I use GetValueFromTag for "3002|0030" I read back an empty string as "3002|0030" is exposure sequence and has no value. How do I read tags within tags with ITK? Looking through the ITK documentation I can't see any way to do this?


Solution

  • Apparently you can't use ImageIOType to read sequences from DICOM, instead you have to use GDCM.

    #include "gdcmReader.h"
    #include "gdcmImage.h"
    #include "gdcmDataElement.h"
    #include "gdcmTag.h"
    
    using namespace gdcm;
    
    bool readGDCMTags(std::string filename, float &kvp)
    {
        Reader reader;
        reader.SetFileName(filename.c_str());
        reader.Read();
    
        File &file = reader.GetFile();
        DataSet &ds = file.GetDataSet();
    
        const Tag tag(0x3002, 0x0030);
        const Tag subTag(0x0018, 0x0060);
    
        const DataElement &seq = ds.GetDataElement(tag);
    
        SmartPointer<SequenceOfItems> sqi = seq.GetValueAsSQ();
    
        assert(sqi->GetNumberOfItems() == 1);
    
        Item &item = sqi->GetItem(1);
    
        DataSet &subds = item.GetNestedDataSet();
    
        if (!subds.FindDataElement(subTag))
        {
            return false;
        }
    
        const DataElement &de = item.GetDataElement(subTag);
    
        const ByteValue *value = de.GetByteValue();
    
        char *buffer;
    
        VL vl = value->GetLength();
        uint32_t length = (uint32_t)vl;
    
        buffer = new char[length + 1];
    
        value->GetBuffer(buffer, length);
    
        buffer[length] = 0;
    
        kvp = (float)atof(buffer);
    
        delete buffer;
    
        return true;
    }