Dicom tags for multiframe data

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
gzhang
Posts: 50
Joined: Wed, 2015-09-02, 09:24

Dicom tags for multiframe data

#1 Post by gzhang »

Hi,
For multiframe dicom file, we often see groups of repeating tags, which are meant for individual frames:
0018,0060 KVP: 27
0018,1405 Relative X-Ray Exposure: 2738
0018,1510 Positioner Primary Angle: 10.850034
0018,1511 Positioner Secondary Angle: 0
0018,9328 Exposure Time in ms: 88.0
0018,9330 X-Ray Tube Current in mA: 133.0
0018,9332 Exposure in mAs: 11.82
0040,0316 Organ Dose: 0.00135
0040,8302 Entrance Dose in mGy: 0.407
0018,0060 KVP: 27
0018,1405 Relative X-Ray Exposure: 2638
0018,1510 Positioner Primary Angle: 13.624145
0018,1511 Positioner Secondary Angle: 0
0018,9328 Exposure Time in ms: 87.0
0018,9330 X-Ray Tube Current in mA: 133.0
0018,9332 Exposure in mAs: 11.75
0040,0316 Organ Dose: 0.00134
0040,8302 Entrance Dose in mGy: 0.405
0018,0060 KVP: 27
0018,1405 ...
Even worse, for many cases, we find all of these tags appearing in every single file if the original multiframe file is expanded at the time of export (from the system).

I wonder what would be the best way to read such information? Does DCMTK has an interface that aligns such data in an array or a list? I wouldn't mind making one but it seems only one (first) value is returned by e.g. DcmItem::findAndGetOFString(). Can the 'searchIntoSub' flag help in such cases? Thanks!

Michael Onken
DCMTK Developer
Posts: 2048
Joined: Fri, 2004-11-05, 13:47
Location: Oldenburg, Germany
Contact:

Re: Dicom tags for multiframe data

#2 Post by Michael Onken »

Hi,

just to be sure...all thee attributes actually appear on the same level, i.e. not in different items of a Sequence?

Best,
Michael

gzhang
Posts: 50
Joined: Wed, 2015-09-02, 09:24

Re: Dicom tags for multiframe data

#3 Post by gzhang »

Hi Michael,
Sorry for the confusion. They can be nested in a sequence, enclosed with (fffe,e000) and (fffe,e00d). Does it make a difference? Instead of iterating over all items, is there an interface to read and organize them directly?
Thanks!

Michael Onken
DCMTK Developer
Posts: 2048
Joined: Fri, 2004-11-05, 13:47
Location: Oldenburg, Germany
Contact:

Re: Dicom tags for multiframe data

#4 Post by Michael Onken »

Hi,

kind of. There is a module called dcmfg which permits you to access each of these items (called Functional Groups in DICOM, hence the name dcmfg) by frame number, using a dedicated API. However, not all functional groups (i.e. attribute collections) are supported. But some common ones are there.

The main interface is in the class FGInterface.

Best regards,
Michael

gzhang
Posts: 50
Joined: Wed, 2015-09-02, 09:24

Re: Dicom tags for multiframe data

#5 Post by gzhang »

Thanks for the hint!
Suppose the functional groups are supported, I should first use

Code: Select all

FGInterface::read(DcmItem &dataset)
to create the list and next

Code: Select all

FGBase * FGInterface::get(const Uint32 frameNo, const DcmFGTypes::E_FGType fgType)
to obtain the per-frame information, right? Then, how do I go from each group to individual tags? Do I rewrite by

Code: Select all

FGBase::write(DcmItem & item)
to a new DcmItem?

Michael Onken
DCMTK Developer
Posts: 2048
Joined: Fri, 2004-11-05, 13:47
Location: Oldenburg, Germany
Contact:

Re: Dicom tags for multiframe data

#6 Post by Michael Onken »

Yes, that's how it works. For FGInterface::read() you should provide the main dataset. FGInterface will extract the data from the Per-Frame and Shared Functional Group Sequence which are part of the main dataset level. Thus the whole dcmfg library is meant for working with these two sequences (for the general purpose approach see my notes about dcmdata below).

After FGInterface read the data, you do not need to write the attributes into another item to access them (this is functionality needed if you want to create functional groups from scratch and to write them into a new image dataset, for example). For reading, it's the idea of the dcmfg module to have a more explicit API to access each "well-known" tags in that functional group.

All Functional Group classes allow you to call getType() (via base class FGBase) which returns an enum. Based on that enum you can cast the FGBase pointer to the related FGBase-derived class. E.g. the DcmSegmentation class does that in segdoc.cc (removed extra cast for count):

Code: Select all

FGSegmentation* fg = OFstatic_cast(FGSegmentation*, m_FGInterface.get(count, DcmFGTypes::EFG_SEGMENTATION)); // count is the frame number
Look at fgfact.cc for the mapping of FG enum types to class names.

General Purpose dcmdata API:

If you know exactly, what you need, i.e. you dont want to handle every attribute in the item(s) but only selected ones you know beforehand, look at the general dcmdata API demonstrated here and here for the sequence part. The most important class is DcmItem.

If you actually want to iterate over the sequences/items and all of their attributes then you can see different approaches here.

Last but not least DCMTK allows you to specify your attribute search as a string "path" to the target attribute (e.g. "PerFrameFunctionalGroupsSequence[5].PixelMeasuresSequence[0].PixelSpacing", or use tag numbers if you want), you can use DcmPathProcessor. Look at the findOrCreatePath() methods. Note that this is slower than navigating through the dataset via pointers yourself since the path string has to interpreted and some extra data structures are created.

Best,
Michael

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 1 guest