File size: 2,433 Bytes
a3290d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import os
from pathlib import Path

import numpy as np
import pydicom
from PIL import Image
from pydicom.dataset import Dataset, FileMetaDataset
from pydicom.uid import ExplicitVRLittleEndian


def to_dicom(input, output_path, plane="axial"):
    """Converts a png image to a dicom image.  Written with assistance from ChatGPT."""
    if isinstance(input, str) or isinstance(input, Path):
        png_path = input
        dicom_path = os.path.join(
            output_path, os.path.basename(png_path).replace(".png", ".dcm")
        )
        image = Image.open(png_path)
        image_array = np.array(image)
        image_array = image_array[:, :, :3]
    else:
        image_array = input
        dicom_path = output_path

    meta = FileMetaDataset()
    meta.MediaStorageSOPClassUID = "1.2.840.10008.5.1.4.1.1.7"
    meta.MediaStorageSOPInstanceUID = pydicom.uid.generate_uid()
    meta.TransferSyntaxUID = ExplicitVRLittleEndian
    meta.ImplementationClassUID = pydicom.uid.PYDICOM_IMPLEMENTATION_UID

    ds = Dataset()
    ds.file_meta = meta
    ds.is_little_endian = True
    ds.is_implicit_VR = False
    ds.SOPClassUID = "1.2.840.10008.5.1.4.1.1.7"
    ds.SOPInstanceUID = pydicom.uid.generate_uid()
    ds.PatientName = "John Doe"
    ds.PatientID = "123456"
    ds.Modality = "OT"
    ds.SeriesInstanceUID = pydicom.uid.generate_uid()
    ds.StudyInstanceUID = pydicom.uid.generate_uid()
    ds.FrameOfReferenceUID = pydicom.uid.generate_uid()
    ds.BitsAllocated = 8
    ds.BitsStored = 8
    ds.HighBit = 7
    ds.PhotometricInterpretation = "RGB"
    ds.PixelRepresentation = 0
    ds.Rows = image_array.shape[0]
    ds.Columns = image_array.shape[1]
    ds.SamplesPerPixel = 3
    ds.PlanarConfiguration = 0

    if plane.lower() == "axial":
        ds.ImageOrientationPatient = [1, 0, 0, 0, 1, 0]
    elif plane.lower() == "sagittal":
        ds.ImageOrientationPatient = [0, 1, 0, 0, 0, -1]
    elif plane.lower() == "coronal":
        ds.ImageOrientationPatient = [1, 0, 0, 0, 0, -1]
    else:
        raise ValueError(
            "Invalid plane value. Must be 'axial', 'sagittal', or 'coronal'."
        )

    ds.PixelData = image_array.tobytes()
    pydicom.filewriter.write_file(dicom_path, ds, write_like_original=False)


# Example usage
if __name__ == "__main__":
    png_path = "../../figures/spine_example.png"
    output_path = "./"
    plane = "sagittal"
    to_dicom(png_path, output_path, plane)