Monday, January 17, 2022

Read Dicom Image metadata using PixelMed in Java

In this tutorial, we are going to learn how to get Dicom image metadata using PixelMed toolkit using Java.

DICOM (Digital Imaging and Communications in Medicine) is the ubiquitous standard in the radiology and cardiology imaging industry for the exchange and management of images and image-related information.

DICOM is also used in other images related medical fields, such as pathology, endoscopy, dentistry, ophthalmology, and dermatology.

PixelMed Java DICOM Toolkit is a stand-alone DICOM toolkit that implements code for reading and creating DICOM data, DICOM network and file support, a database of DICOM objects, support for display of directories, images, reports, and spectra, and DICOM object validation.

The toolkit is an implementation, which does not depend on any other DICOM tools. This is the freely available pure Java tools for compression and XML and database support.

Download the .jar file from PixelMed Jar. Create a folder called libs inside the project directory and add the jar file and load it from the Ide.

Loading Jar file in Maven Project:

Add the following system dependency inside pom.xml file.

<dependency>
           <groupId>com.pixelmed</groupId>
           <artifactId>pixelmed</artifactId>
           <version>20220117</version>
           <scope>system</scope>
           <systemPath>${basedir}/libs/pixelmed.jar</systemPath>
       </dependency>

Note: use the downloaded jar file name.

Loading Jar in Gradle Project:

Add the following inside dependencies in build.gradle file.

dependencies {
//other dependencies
 
compile fileTree(dir: 'libs', include: '*.jar')
}

Now, let's create a sample java class called ReadMetaDataPixelMed.java and create the main method to execute the code.

    private static AttributeList attributeList = new AttributeList();
public static void main(String[] args) {
        String dcmFilePath = "/path_to_dicom_image/N2D_0001.dcm";
        try {
            readAttributes(dcmFilePath);
            Map<String, String> metaData = readMetadata();
            for (Map.Entry<String, String> entry :metaData.entrySet()) {
                System.out.println(entry.getKey()+" : "+entry.getValue());
            }
        }catch (Exception e) {
            System.out.println("Error due to: "+e.getMessage());
        }
    }

Create the methods used inside it.

private static void readAttributes(String dcmFilePath) throws DicomException, IOException {
        attributeList.read(new File(dcmFilePath));
    }

readAttributes method read the attributes or tag of the Dicom image. For Dicom library Tags and their description please visit Dicom Library.

 private static Map<String, String> readMetadata() throws DicomException {
        Map<String, String> metaData = new LinkedHashMap<>();
        metaData.put("Patient Name", getTagInformation(TagFromName.PatientName));
        metaData.put("Patient ID", getTagInformation(TagFromName.PatientID));
        metaData.put("Transfer Syntax", getTagInformation(TagFromName.TransferSyntaxUID));
        metaData.put("SOP Class", getTagInformation(TagFromName.SOPClassUID));
        metaData.put("Modality", getTagInformation(TagFromName.Modality));
        metaData.put("Samples Per Pixel", getTagInformation(TagFromName.SamplesPerPixel));
        metaData.put("Photometric Interpretation", getTagInformation(TagFromName.PhotometricInterpretation));
        metaData.put("Pixel Spacing", getTagInformation(TagFromName.PixelSpacing));
        metaData.put("Bits Allocated", getTagInformation(TagFromName.BitsAllocated));
        metaData.put("Bits Stored", getTagInformation(TagFromName.BitsStored));
        metaData.put("High Bit", getTagInformation(TagFromName.HighBit));
        SourceImage img = new com.pixelmed.display.SourceImage(attributeList);
        metaData.put("Number of frames", String.valueOf(img.getNumberOfFrames()));
        metaData.put("Width", String.valueOf(img.getWidth()));
        metaData.put("Height", String.valueOf(img.getHeight()));
        metaData.put("Is Grayscale", String.valueOf(img.isGrayscale()));
        metaData.put("Pixel Data present", String.valueOf(!getTagInformation(TagFromName.PixelData).isEmpty()));
        return metaData;
    }

Here, we are reading some sample metadata. For more metadata lists please visit TagFromName.java class and use the desired one.

private static String getTagInformation(AttributeTag tag) {
        return Attribute.getDelimitedStringValuesOrDefault(attributeList, tag, "NOT FOUND");
    }

If the attribute is found then this method returns the value of that attribute if not found then return NOT FOUND text.

Output:

Patient Name : Jane_Doe
Patient ID : 02
Transfer Syntax : 1.2.840.10008.1.2
SOP Class : 1.2.840.10008.5.1.4.1.1.4
Modality : MR
Samples Per Pixel : 1
Photometric Interpretation : MONOCHROME2
Pixel Spacing : 0.666666686534882\0.699987828731537
Bits Allocated : 16
Bits Stored : 16
High Bit : 15
Number of frames : 1
Width : 274
Height : 384
Is Grayscale : true
Pixel Data present : true

The overall code implementation looks like below:

package dicom;

import com.pixelmed.dicom.*;
import com.pixelmed.display.SourceImage;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

public class ReadMetaDataPixelMed {

    private static AttributeList attributeList = new AttributeList();

    public static void main(String[] args) {
        String dcmFilePath = "/path_to_dicom_image/N2D_0001.dcm";
        try {
            readAttributes(dcmFilePath);
            Map<String, String> metaData = readMetadata();
            for (Map.Entry<String, String> entry :metaData.entrySet()) {
                System.out.println(entry.getKey()+" : "+entry.getValue());
            }
        }catch (Exception e) {
            System.out.println("Error due to: "+e.getMessage());
        }
    }

    private static void readAttributes(String dcmFilePath) throws DicomException, IOException {
        attributeList.read(new File(dcmFilePath));
    }

    private static Map<String, String> readMetadata() throws DicomException {
        Map<String, String> metaData = new LinkedHashMap<>();
        metaData.put("Patient Name", getTagInformation(TagFromName.PatientName));
        metaData.put("Patient ID", getTagInformation(TagFromName.PatientID));
        metaData.put("Transfer Syntax", getTagInformation(TagFromName.TransferSyntaxUID));
        metaData.put("SOP Class", getTagInformation(TagFromName.SOPClassUID));
        metaData.put("Modality", getTagInformation(TagFromName.Modality));
        metaData.put("Samples Per Pixel", getTagInformation(TagFromName.SamplesPerPixel));
        metaData.put("Photometric Interpretation", getTagInformation(TagFromName.PhotometricInterpretation));
        metaData.put("Pixel Spacing", getTagInformation(TagFromName.PixelSpacing));
        metaData.put("Bits Allocated", getTagInformation(TagFromName.BitsAllocated));
        metaData.put("Bits Stored", getTagInformation(TagFromName.BitsStored));
        metaData.put("High Bit", getTagInformation(TagFromName.HighBit));
        SourceImage img = new com.pixelmed.display.SourceImage(attributeList);
        metaData.put("Number of frames", String.valueOf(img.getNumberOfFrames()));
        metaData.put("Width", String.valueOf(img.getWidth()));
        metaData.put("Height", String.valueOf(img.getHeight()));
        metaData.put("Is Grayscale", String.valueOf(img.isGrayscale()));
        metaData.put("Pixel Data present", String.valueOf(!getTagInformation(TagFromName.PixelData).isEmpty()));
        return metaData;
    }

    private static String getTagInformation(AttributeTag tag) {
        return Attribute.getDelimitedStringValuesOrDefault(attributeList, tag, "NOT FOUND");
    }
}
Share:

0 comments:

Blog Archive