Sorting Images

DicomImages and DicomDataSets collection objects have a move method which can be used to swap the indices of 2 images or datasets within the collection.

Important Note Do not confuse the Move method with C-Move.

So if for example you wish to order the images within your DicomViewer control by instance number(00020,0013) you could use the move method combined with a classic bubble sort.


Dim i As Integer
Dim sw As Boolean
Dim im1 As DicomImage, im2 As DicomImage, p1 As Single, p2 As Single

Do 'for each series
  sw = False
  For i = 1 To Viewer.Images.Count - 1  
    set im1 = Viewer.Images(i)
    set im2 = Viewer.Images(i + 1)
      'you should trap errors here i.e. check that the attribute 
      'exists before reading the value.
    p1 = im1.Attributes(&H20, &H13).Value
    p2 = im2.Attributes(&H20, &H13).Value
    If (p2 > p1) Then
      sw = True
      Viewer.Images.Move i, i + 1
    End If
Loop While sw

The result is that the images will be re-indexed according to Instance number. You could of course use this method to sort by alternative Dicom attributes.

Position Sorting

In fact, sorting by image number is a very bad idea (see my contributions to a thread on the UK radiologists discussion forum at, as different manufacturers may produce images in different orders, and it is better to sort by position, but this raises the question of how to know which of the position variables to use (there are 3 values in Image Position (patient) which is 0020,0032), so this short guide may help.

Look at first at the SIX values in 0020,0037 which are 2 x 3-element vectors defining the plane of the image (look in part 3 for the full definition) - they should be the same for all the images in a parallel set. You sort on the element from 0020,0032 which either 0 or closest to zero in each of those 2 vectors from 0020,0037.

So for instance (this is real MR data):

(0020,0032)  3   Image Position (Patient)    
    -80.587417980677 : -112.25763605359 : -37.861883640289

(0020,0037)  6   Image Orientation (Patient)
    1 : -2.0510349e-010 : 0 : 2.051034897e-010 : 1 : 0

So the orientation vectors are

  1. 1 : -2.0510349e-010 : 0 (i.e. 1,0,0)
  2. 2.051034897e-010 : 1 : 0 (i.e. 0,1,0)

So the value which is 0 in both is the third one (Z), so you sort on the third value of 0020,0032, and as it is always defined in the same direction relative to the patient, you can use it for consistent sorting. Note that you may still need to consider the values of the vectors in 0020,0037 to make sure that your volume set is not a "mirror-image".

Following is VB code demonstrating how to get the correct value on which to sort:

 Dim im As DicomImage
 Set im = DicomViewer1.CurrentImage 
 Dim x1, y1, z1, x2, y2, z2 As Double
 x1 = CDbl(im.Attributes(&H20, &H37).ValueByIndex(1))
 y1 = CDbl(im.Attributes(&H20, &H37).ValueByIndex(2))
 z1 = CDbl(im.Attributes(&H20, &H37).ValueByIndex(3))
 x2 = CDbl(im.Attributes(&H20, &H37).ValueByIndex(4))
 y2 = CDbl(im.Attributes(&H20, &H37).ValueByIndex(5))
 z2 = CDbl(im.Attributes(&H20, &H37).ValueByIndex(6)) 

 Dim v1, v2, v3 As Double
 v1 = x1 * x1 + x2 * x2
 v2 = y1 * y1 + y2 * y2
 v3 = z1 * z1 + z2 * z2

 Dim SortIndex As Integer ' determine which dimension to sort
 If (v1 <= v2) And (v1 <= v3) Then
       SortIndex = 1 ' Sort on X dimension
 End If
 If (v2 <= v1) And (v2 <= v3) Then
       SortIndex = 2 ' Sort on Y dimension
 End If

 If (v3 <= v1) And (v3 <= v2) Then
       SortIndex = 3 ' Sort on Z dimension
 End If

Then use that value to determine the sort method as above, but replace two lines setting p1 & p2 in the original by these two:

    p1 = im1.Attributes(&H20, &H32).ValueByIndex(SortIndex)
    p2 = im2.Attributes(&H20, &H32).ValueByIndex(SortIndex)

Follow the link for more information about Sorting_Images_in_DO.NET.