-
Notifications
You must be signed in to change notification settings - Fork 0
/
dxaconv.py
executable file
·136 lines (107 loc) · 4.66 KB
/
dxaconv.py
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/python
# before you run, pip install pydicom, pip install pillow # optional
import sys
import pydicom as dicom
import PIL # optional
import pandas as pd
import matplotlib.pyplot as plt
import os
from os import listdir
import cv2
import csv
from pathlib import Path
## returns a list of files that have the .dcm extension
def ext_only(directory, extension='dcm'):
return([f for f in listdir(directory) if f.endswith('.' + extension)])
## returns the absolute path of a directory
def abs_dir(directory:str):
absdir = os.path.abspath(directory)
return absdir
# This function shows you a preview of the dicom image by plotting the image's pixel array with matplotlib
# Just for an individual preview, but can write additional code to preview a whole folder
def dcm_preview(img_path:str):
ds = dicom.dcmread(img_path)
plt.imshow(ds.pixel_array)
plt.show()
# This function parses a dcm file's metadata
# Set the absolute file path if not in the same directory as the images, otherwise, default is the current directory
def metadata_parser(dcm_file:str, output_destination):
#dcm_file_path = abs_directory_path + dcm_file
ds = dicom.read_file(dcm_file)
f = Path(dcm_file).name
f = f[:-4]
y = "_metadata.txt"
fname = f + y
metadata = print(ds, file=open(os.path.join(output_destination, fname), "w"))
return metadata
# This function converts individual dcm files to jpg format
def dxaconv_single(dcm_file:str, output_destination):
ds = dicom.dcmread(dcm_file)
pixel_array_np = ds.pixel_array
f = Path(dcm_file).name
img = f.replace('.dcm', '.jpg')
cv2.imwrite(os.path.join(output_destination, img), pixel_array_np)
print("File ", img, "converted to JPG")
# This function converts dcm by directory, specified in "img_type" parameter (jpg or png)
# takes the path to the directory with images, path to output destination, and the image file type as parameters
# Use only if you have a directory with only .dcm files, or pass the files through the ext_only function first to check
def dxaconv_dir(dcm_folder_path, img_output_path, img_type='.jpg'):
images_path = os.listdir(dcm_folder_path)
#images_path = ext_only(dcm_folder_path) # uncomment this if you want to make sure you're only listing DICOM files from a directory
for n, image in enumerate(images_path):
ds = dicom.dcmread(os.path.join(dcm_folder_path, image))
pixel_array_numpy = ds.pixel_array
image = image.replace('.dcm', img_type)
cv2.imwrite(os.path.join(img_output_path, image), pixel_array_numpy)
# given a list of directories, convert contents output to destination
def dxaconv_dirlist(directory_list:list, output_destination:str):
files = []
for d in directory_list:
fnames = ext_only(d)
for f in fnames:
files.append(os.path.join(abs_dir(d), f))
for f in files:
dxaconv_single(f, output_destination)
# take dcm file and convert most useful metadata information into a nested dictionary
# nested dict includes information on the type of image, the
def advanced_metadata_tools(full_path_dcm):
ds = dicom.read_file(full_path_dcm)
# Image Info
exam_type = ds.StudyDescription
img_type = ds.SeriesDescription
# dictionary of image info
img_dict = {"Exam_Type": exam_type, "Image_Type": img_type}
# Patient Info
age = ds.PatientAge
ID = ds.PatientID
orientation = ds.PatientOrientation
sex = ds.PatientSex
size = ds.PatientSize
weight = ds.PatientWeight
protocol = ds.ProtocolName
acquisition = ds.AcquisitionDate
ethnicity = ds.EthnicGroup
# dictionary of patient info
patient_dict = {'Patient_Age': age, 'Patient_Protocol': protocol, 'Patient_Sex': sex, 'Ethnic_Group': ethnicity, 'Patient_Orientation': orientation, 'Patient_Size': size, 'Patient_Weight': weight, 'PatientID': ID, 'Acquisition_Date': acquisition}
# Pixel Info
pixdata = ds.PixelData ## pixel data is not human readable, can use to plot image in other functions
represent = ds.PixelRepresentation
samp = ds.SamplesPerPixel
rows = ds.Rows
columns = ds.Columns
phot = ds.PhotometricInterpretation
# dictionary of pixel info
pixel_dict = {'Samples_per_Pixel': samp, 'Pixel_Rows': rows, 'Pixel_Columns': columns, 'Photomeric_Interpretation': phot, 'Pixel_Representation': represent}
# Bit Info
allocated = ds.BitsAllocated
stored = ds.BitsStored
highbit = ds.HighBit
# dictionary of bit info
bit_dict = {'Bits_Allocated': allocated, 'Bits_Stored': stored, 'High_Bit': highbit}
# Nested Dict with all Information
dicom_super = {'Image':img_dict, 'Patient':patient_dict, 'Pixel':pixel_dict, 'Bit':bit_dict}
return dicom_super
try:
dxaconv_dir(sys.argv[1], sys.argv[2])
except BaseException as error:
print('An exception occurred and a dcm file of this directory did not successfully convert: {}'.format(error))