Frame Level Retrieval (DICOM Supplement 119) was written by Dr. David Harvey (1962-2018), founder of Medical Connections, and is fully supported by DicomObjects.

Frame Selection Options

There are 2 (actually 3, with the 3rd one using Content Time values to specify a Time Range) ways to ask for specific frames:

Simple Frame List

Contains a list of frame numbers, each specifying a frame to be included in the returned object.

Calculated Frame List

Calculated Frame List (0008,1162) is a multi-valued attribute containing a list of 3-tuples, each representing a sub-range of frames to be included in the returned object.

  • The first number shall be the frame number of the first frame of the sub-range
  • The second number shall be the upper limit of the sub-range, and shall be greater than or equal to the first number
  • The third number shall be the increment between requested frames of the sub-range

DicomObjects.NET

Below is very simple C# code to show how to perform a simple C-GET/C-MOVE request to retrieve some frames from a multi-frame DICOM image, using DicomObjects.NET version:

DicomQuery q = new DicomQuery ();  
q.Node = ip;  
q.Port = port;  
q.CallingAE = localAET;  
q.CalledAE = serverAET;  
  
q.Root = DicomObjects.Enums.QueryRoot.CompositeInstance;  
q.Level = DicomObjects.Enums.QueryLevel.FRAME;  
  
DicomDataSet queryDataSet = q.QueryDataSet();  
queryDataSet.Add(Keyword.QueryRetrieveLevel, "FRAME");  
queryDataSet.InstanceUID = InstanceUID;

if (simpleFrameList)  
{  
	// Asking for frames 1, 3, 5, 7, 9, 11, 22 and 54 
	int[] frames = new int[] {1, 3, 5, 7, 9, 11, 22, 54 };  
	queryDataSet.Add(Keyword.SimpleFrameList, frames);  
}  
else if (calculatedFrameList)  
{  
	// Asking for frames 1, 5, 9, 11, 16, 22, 24, 26, 28 and 30  
	int[] frames = new int[] {1, 10, 4, 11, 20, 5, 22, 30, 2 };
	queryDataSet.Add(Keyword.CalculatedFrameList, frames);  
}

if (CGET) // C-GET  
{  
    DicomDataSetCollection results = q.Get(queryDataSet);  
}  
else if (CMOVE) // C-MOVE  
{  
      queryDataSet.Add(Keyword.MoveDestination, moveDestination);  
      q.Move(queryDataSet);  
}

DicomObjects.COM

Sample vb6 code below to show you how it can be done in the COM activeX version of DicomObjects.

 
Dim q As New DicomQuery
q.Node = ip
q.port = port
q.CallingAE = localAET
q.CalledAE = serverAET

q.Root = "COMPOSITEINSTANCE"
q.level = "FRAME"

Dim queryDS As DicomDataSet
Set queryDS = q.QueryDataSet
queryDS.Attributes.Add &H8, &H52, "FRAME"
queryDS.InstanceUID = "1.2.840.10008.1.2.3.4.5.6.7" ' the Instance UID of the multi-frame image

Dim frames() As Integer
If simpleFrameList Then
 ReDim frames(7) As Integer ' Asking for frames 1, 3, 5, 7, 9, 11, 22 and 54
 frames(0) = 1
 frames(1) = 3
 frames(2) = 5
 frames(3) = 7
 frames(4) = 9
 frames(5) = 11
 frames(6) = 22
 frames(7) = 54
 q.simpleFrameList = frames
ElseIf calculatedFrameList Then
 ReDim frames(8) As Integer  
' Asking for frames (1, 5, 9) (11, 16) (22, 24, 26, 28, 30)
 frames(0) = 1
 frames(1) = 10
 frames(2) = 4

 frames(3) = 11 
 frames(4) = 20
 frames(5) = 5

 frames(6) = 22
 frames(7) = 30
 frames(8) = 2
 q.calculatedFrameList = frames
End If

If CGET Then
 Dim results As DicomImages
 Set results = q.GetImages
ElseIf CMOVE Then
 queryDS.Attributes.Add &H0, &H600, "MoveDestination A" 
 q.MoveImages
End If