Retrieve a specific DICOM tag from an image?

 

It is possible to retrieve a specific DICOM tag from an image read in memory.  If the tag's value is not already present in the Tomo_Image's structure, you can access it in 3 steps.

 

In the following example I retrieve the "Frame Of Reference UID" (0020,0052) from the DICOM tags.

 

Step 1: Get the Tomo_Image's pointer for a specific frame. 

 

This pointer is part of the frame's structure, you just have to cast to a "Tomo_Image" pointer.

 

#include "TomoVision_Convert.hpp"

#include "TomoVision_DICOM.hpp"

 

// --- get the frame's header ---

Tomo_Image *header = (Tomo_Image *) frame->m_ima ;

 

 

Step 2: Get a "DICOM_List" pointer to the specific tag

 

All the original DICOM tags are stored inside the "DICOM_org" structure of the "Tomo_Image" header. That structure is a list of all the DICOM tags in the original image's header.  The "DICOM_Attribute_Get" function will parse these and return a pointer to the desired tag if it is found.  If the tag is not found, the function will return NULL.  

 

Because of the recursive nature of the DICOM tags, you first need to prepare a "root" structure that tells the function how to dig in the DICOM tags.

 

// --- make sure we start with a clean slate ---

DICOM_Root local_root ;

DICOM_Attribute_Sequence_Reset( hwnd, &local_root ) ;

 

// --- Get the FoR UID from the image's header ---

DICOM_List *tag_FoR_UID = DICOM_Attribute_Get( hwnd, &local_root, header->DICOM_org, 0x0020, 0x0052 ) ;

if ( ! tag_FoR_UID ) {

          ... // --- The function failed ---

}

 

If you want a DICOM tag extracted from a specific sequence, you need first to get a pointer to the sequence. Once you have the pointer to the sequence, its "item" attribute is a vector of "nb_item" DICOM_List.  Each of these are pointers to the tags of the different items of the sequence.  So if for example you want a specific tag for the second item of the sequence, you call the DICOM_Attribute_Get with "seq->item[2]" as starting DICOM list.

 

For example, I want the position of the second frame in a Enhanced MR file containing multiple images.

 

// --- make sure we start with a clean slate ---

DICOM_Root local_root ;

DICOM_Attribute_Sequence_Reset( hwnd, &local_root ) ;

 

// --- Get the pointer to the desired sequence from the image's header ---

// (5200,9230) = "Per-frame Functional Groups Sequence" ---

DICOM_List *frm_seq = DICOM_Attribute_Get( hwnd, &local_root, header->DICOM_org, 0x5200, 0x9230 ) ;

if ( ! frm_seq ) {

          ... // --- The function failed ---

}

 

// --- Get the pointer to the desired element in the second item of the sequence ---

// (0020,9113) = "Frame Position Sequence" ---

DICOM_List *pos_seq = DICOM_Attribute_Get( hwnd, &local_root, frm_seq->item[1], 0x0020, 0x9113 ) ;

if ( ! pos_seq ) {

          ... // --- The function failed ---

}

 

// --- Get the pointer to the desired element in the first (and only) item of the sequence ---

// (0020,0032) = "Frame Position" ---

DICOM_List *pos = DICOM_Attribute_Get( hwnd, &local_root, pos_seq->item[0], 0x0020, 0x0032 ) ;

if ( ! pos ) {

          ... // --- The function failed ---

}

 

 

Step 3: Extract the value you want from the tag.

 

Now that we have a pointer to the DICOM TAG, we need to extract the tag's value.  Depending on the type of value (character string, integer, floating point...) we will use one of the "NEMA_Value" functions:

·NEMA_Value_Date() for dates (VR=DA and DT)

·NEMA_Value_Time() for times (VR=TM and DT)

·NEMA_Value_Name() for names (VR=PN)

·NEMA_Value_Str() for character strings (VR=AE, CS, LO, SH, UI, AS, LT, ST, UT, OB and UN)

·NEMA_Value_Hex() for hexadecimal values (VR=OB, OW, OX and UN)

·NEMA_Value_Int() for integer values (VR=DS, IS, SS, SL, US, UH, AT, UL and OW)

·NEMA_Value_Float() for floating point values (VR=IS, DS, FL and FD)

 

Since DICOM tags can have multiple values each (VM), these function return vectors of pointers to the contained values.  In our example, VM=1, so the desired value is in the first pointer.

 

 

/ --- The FoR UID is a string (VR=UI) ---

char **str = NEMA_Value_Str( hwnd, tag_FoR_UID ) ;

if ( ! str ) {

          ... // --- The function failed ---

}

// --- str[0] is a pointer to the FoR UID ---

char *FoR_UID = str[0] ;