Saturday, January 8, 2022

Read the Dicom Image metadata using Java

In this tutorial, we are going to learn how we can read Dicom image metadata. 

A Dicom metadata generally contains:

  •  A tag that identifies the attribute, usually in the format (XXXX,XXXX) with hexadecimal numbers.
  • A DICOM Value Representation (VR) that describes the data type and format of the attribute value

We are using SimpleITK library to extract metadata. The library is very handy when used for medical Image analysis. So, please refer SimpleITK library installation from this tutorail.

Once installed and load the library, let's write some Java code that reads metadata. Create a Java file called DicomReader.java

Read the Dicom file using SimpleITK:

import org.itk.simple.ImageFileReader;
public static ImageFileReader getDcmImageFileReader(String imagePath) {
        ImageFileReader imageFileReader = new ImageFileReader();
        imageFileReader.setImageIO("GDCMImageIO");
        imageFileReader.setFileName(imagePath);
        return imageFileReader;
    }
This will read the Dicom file. This example uses the standard SimpleITK native library.

Let's create an actual method that read the metadata from the Dicom Image file

import org.itk.simple.VectorString;
import java.util.LinkedHashMap;
import java.util.Map;
public static Map<String, String> readMetadata(ImageFileReader imageFileReader) {
        Map<String, String> metaData = new LinkedHashMap<>();
        imageFileReader.loadPrivateTagsOn();
        imageFileReader.readImageInformation();
        VectorString metaDataKeys = imageFileReader.getMetaDataKeys(); // get metadata keys
        long metaDataKeySize = metaDataKeys.size();
        System.out.println("Total meta data found: " + metaDataKeySize);
        for (int metaDataKeyIndex = 0; metaDataKeyIndex < metaDataKeySize; metaDataKeyIndex++) {
            String metaDataKey = metaDataKeys.get(metaDataKeyIndex);
            String metaDataValue = imageFileReader.getMetaData(metaDataKey);
            System.out.println("Key: " + metaDataKey + " Value: " + metaDataValue);
            metaData.put(metaDataKey, metaDataValue);
        }
        return metaData;
    }
Here, we are passing the ImageFileReader object, which is obtained from the previous method. And it will extract the metadata and loop through the metadata keys and print key values. pair in the console.

Here is the sample GitHub repo for getting sample test Dicom. Let's add the main method to run the code

 public static void main(String[] args) {
        String imagePath = "path_to_dicom/N2D_0001.dcm";
        try {
            ImageFileReader imageFileReader = getDcmImageFileReader(imagePath);
            Map<String, String> metadata = readMetadata(imageFileReader);
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }

The output of the above example will be similar to like this:

Total meta data found: 53
Key: 0008|0008 Value: DERIVED\SECONDARY 
Key: 0008|0016 Value: 1.2.840.10008.5.1.4.1.1.4
Key: 0008|0018 Value: 1.2.826.0.1.3680043.2.1143.1590429688519720198888333603882344634
Key: 0008|0020 Value: 20130717
Key: 0008|0021 Value: 20130717
Key: 0008|0022 Value: 20130717
Key: 0008|0023 Value: 20130717
Key: 0008|0030 Value: 141500
Key: 0008|0031 Value: 142035.93000
Key: 0008|0032 Value: 132518
Key: 0008|0033 Value: 142035.93 
Key: 0008|0050 Value: 
Key: 0008|0060 Value: MR
Key: 0008|0070 Value: BIOLAB
Key: 0008|0080 Value: 
Key: 0008|0090 Value: 
Key: 0008|1030 Value: Hanke_Stadler^0024_transrep 
Key: 0008|103e Value: anat-T1w
Key: 0008|1090 Value: nifti2dicom 
Key: 0010|0010 Value: Jane_Doe
Key: 0010|0020 Value: 02
Key: 0010|0030 Value: 19660101
Key: 0010|0040 Value: F 
Key: 0010|1000 Value: 
Key: 0010|1010 Value: 42
Key: 0010|1030 Value: 75
Key: 0010|21c0 Value: 4
Key: 0018|0050 Value: 0.666666686534882 
Key: 0018|0088 Value: 0.666666686534882 
Key: 0018|1020 Value: 0.4.11
Key: 0018|1030 Value: anat-T1w
Key: 0020|000d Value: 1.2.826.0.1.3680043.2.1143.2592092611698916978113112155415165916
Key: 0020|000e Value: 1.2.826.0.1.3680043.2.1143.515404396022363061013111326823367652
Key: 0020|0010 Value: 433724515 
Key: 0020|0011 Value: 401 
Key: 0020|0012 Value: 1 
Key: 0020|0013 Value: 1 
Key: 0020|0020 Value: L\R 
Key: 0020|0032 Value: -91.4495864331908\-160.06035870244\-142.505487236053
Key: 0020|0037 Value: 0.999032176441525\-0.0217883751691557\0.0382096472372976\0.026519476938784\0.991413870277297\-0.128043957939
Key: 0020|0052 Value: 1.2.826.0.1.3680043.2.1143.6856184167807409206647724161920598374
Key: 0028|0002 Value: 1
Key: 0028|0004 Value: MONOCHROME2 
Key: 0028|0010 Value: 384
Key: 0028|0011 Value: 274
Key: 0028|0030 Value: 0.666666686534882\0.699987828731537 
Key: 0028|0100 Value: 16
Key: 0028|0101 Value: 16
Key: 0028|0102 Value: 15
Key: 0028|0103 Value: 1
Key: 0028|1052 Value: 0 
Key: 0028|1053 Value: 1 
Key: 0028|1054 Value: US

In the above output, the key is the standard metadata key and the corresponding values are the metadata value of Dicom. 

You can find the standard Dicom tags from DICOM Tags. For e.g metadata key 0008|0008 denotes name as Image Type. Please check the link to get all the information on these keys.

The sample Dicom file used here is:


Convert the Dicom into png or jpg using SimpleITK:

Let's write the method which will convert the Dicom to PNG or JPG

 public static void convert(ImageFileReader imageFileReader, String outputImagePath) {
        Image image = imageFileReader.execute();
        SimpleITK.writeImage(image, outputImagePath);
    }
 public static void main(String[] args) {
        String imagePath = "input_path/N2D_0001.dcm";
        String outputImagePath = "output_path/test.png";
        try {
            ImageFileReader imageFileReader = getDcmImageFileReader(imagePath);
            Map<String, String> metadata = readMetadata(imageFileReader);
            convert(imageFileReader, outputImagePath);
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }

The overall implementation looks as below:

package simpleitk;

import org.itk.simple.Image;
import org.itk.simple.ImageFileReader;
import org.itk.simple.SimpleITK;
import org.itk.simple.VectorString;

import java.util.LinkedHashMap;
import java.util.Map;

public class DicomReader {
    public static void main(String[] args) {
        String imagePath = "input_path/N2D_0001.dcm";
        String outputImagePath = "output_path/test.png";
        try {
            ImageFileReader imageFileReader = getDcmImageFileReader(imagePath);
            Map<String, String> metadata = readMetadata(imageFileReader);
            convert(imageFileReader, outputImagePath);
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }

    public static ImageFileReader getDcmImageFileReader(String imagePath) {
        ImageFileReader imageFileReader = new ImageFileReader();
        imageFileReader.setImageIO("GDCMImageIO");
        imageFileReader.setFileName(imagePath);
        return imageFileReader;
    }

    public static Map<String, String> readMetadata(ImageFileReader imageFileReader) {
        Map<String, String> metaData = new LinkedHashMap<>();
        imageFileReader.loadPrivateTagsOn();
        imageFileReader.readImageInformation();
        VectorString metaDataKeys = imageFileReader.getMetaDataKeys();
        long metaDataKeySize = metaDataKeys.size();
        System.out.println("Total meta data found: " + metaDataKeySize);
        for (int metaDataKeyIndex = 0; metaDataKeyIndex < metaDataKeySize; metaDataKeyIndex++) {
            String metaDataKey = metaDataKeys.get(metaDataKeyIndex);
            String metaDataValue = imageFileReader.getMetaData(metaDataKey);
            System.out.println("Key: " + metaDataKey + " Value: " + metaDataValue);
            metaData.put(metaDataKey, metaDataValue);
        }
        return metaData;
    }

    public static void convert(ImageFileReader imageFileReader, String outputImagePath) {
        Image image = imageFileReader.execute();
        SimpleITK.writeImage(image, outputImagePath);
    }
}

For SimpleITK tutorial, please refer to these docs.

Share:

0 comments:

Blog Archive