-
Notifications
You must be signed in to change notification settings - Fork 2
/
anonymize_dicom.py
executable file
·126 lines (94 loc) · 4.58 KB
/
anonymize_dicom.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
#!/usr/bin/env python
import os, sys, argparse
import dicom
from dicom.errors import InvalidDicomError
from shutil import copyfile
"""
Date: 1/6-2018
Author: Claes Ladefoged ( [email protected] )
###
Anonymize script for DICOM file or folder containing dicom files
Simply removes or replaces patient sensitive information.
-----------------------------------------------------------------
### USAGE OUTSIDE PYTHON ###
usage: anonymize_dicom.py [-h] [--name NAME] original output
Convert DICOM to MINC
positional arguments:
original Folder or file of original dicom files
output Folder or file of anonymized dicom files
optional arguments:
-h, --help show this help message and exit
--name NAME Name instead of patient name
-----------------------------------------------------------------
### USAGE INSIDE PYTHON AFTER ADDING TO PYTHONPATH AND PATH ###
import anonymize_dicom as DCM
DCM.anonymize(dicom_original,dicom_anonymized)
or
DCM.anonymize_folder(dicom_original_folder,dicom_anonymized_folder)
-----------------------------------------------------------------
"""
def anonymize(filename, output_filename, new_person_name="anonymous", remove_private_tags=False, copy_non_dicom=True):
def PN_callback(ds, data_element):
"""Called from the dataset "walk" recursive function for all data elements."""
if data_element.VR == "PN":
data_element.value = new_person_name
def curves_callback(ds, data_element):
"""Called from the dataset "walk" recursive function for all data elements."""
if data_element.tag.group & 0xFF00 == 0x5000:
del ds[data_element.tag]
try:
# Load the current dicom file to 'anonymize'
dataset = dicom.read_file(filename)
# Remove patient name and any other person names
dataset.walk(PN_callback)
# Remove data elements (should only do so if DICOM type 3 optional)
for name in ['OtherPatientIDs', 'OtherPatientIDsSequence']:
if name in dataset:
delattr(dataset, name)
# Same as above but for blanking data elements that are type 2.
for name in ['PatientBirthDate','PatientID','PatientsAddress','PatientsTelephoneNumbers']:
if name in dataset:
dataset.data_element(name).value = ''
if remove_private_tags:
dataset.remove_private_tags()
# write the 'anonymized' DICOM out under the new filename
dataset.save_as(output_filename)
except InvalidDicomError:
# Copy over files that are not DICOM
copyfile(filename,output_filename.replace(os.path.basename(output_filename),os.path.basename(filename)))
# Anonymize all files within a folder.
# If folder contains subfolders, keep their hierachy, and also anonymize their files.
def anonymize_folder(foldername,output_foldername,new_person_name="anonymous",remove_private_tags=False):
def _anonymize_folder(_foldername,_output_foldername,_new_person_name,_remove_private_tags):
if os.path.exists(_output_foldername):
if not os.path.isdir(_output_foldername):
raise IOError("Input is directory; output name exists but is not a directory")
else: # out_dir does not exist; create it.
os.makedirs(_output_foldername)
print("Anonymizing folder: %s" % _foldername)
if len(os.listdir(_foldername)) > 9999:
exit('Too many files in folder for script..')
for fid,filename in enumerate(os.listdir(_foldername)):
extention = '.dcm' if os.path.splitext(filename)[1]=='' else os.path.splitext(filename)[1]
filename_out = "dicom"+str(fid+1).zfill(4)+extention
if not os.path.isdir(os.path.join(_foldername, filename)):
#print filename + " -> " + filename_out + "...",
anonymize(os.path.join(_foldername, filename), os.path.join(_output_foldername, filename_out),_new_person_name)
print("done\r")
# Anonymize all files in current folder
_anonymize_folder(foldername,output_foldername,new_person_name,remove_private_tags)
# Go through all subfolders - anonymize each of them
for root, dirs, files in os.walk(foldername):
for subfolder in dirs:
to_folder = os.path.join(root,subfolder).replace(foldername,output_foldername)
_anonymize_folder(os.path.join(root,subfolder),to_folder,new_person_name,remove_private_tags)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Convert DICOM to MINC')
parser.add_argument('original', type=str, help='Folder or file of original dicom files')
parser.add_argument('output', type=str, help='Folder or file of anonymized dicom files')
parser.add_argument('--name', help='Name instead of patient name', default='anonymous')
args = parser.parse_args()
if os.path.isdir(args.original):
anonymize_folder(args.original,args.output,args.name)
else:
anonymize(args.original,args.output,args.name)