-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathCropSave.py
120 lines (102 loc) · 3.94 KB
/
CropSave.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
import io
import cv2
import pydicom
import datetime
import numpy as np
import os, glob
from pydicom.dataset import FileDataset, FileMetaDataset
from skimage import io
from pydicom.encaps import decode_data_sequence
from pydicom.encaps import encapsulate
from PIL import Image
from multiprocessing import Pool
path = '/guoqing/project/covid/'
def SaveCompressedResults(frames, dstFile, PatientID):
frame_data = []
for frame in frames:
image = Image.fromarray(frame.astype(np.ushort))
with io.BytesIO() as output:
image.save(output, format="PNG")
frame_data.append(output.getvalue())
encapsulated_data = encapsulate(frame_data)
file_meta = FileMetaDataset()
file_meta.MediaStorageSOPClassUID = '1.2.840.10008.1.2.4.51'
file_meta.MediaStorageSOPInstanceUID = "1.2.3"
file_meta.ImplementationClassUID = "1.2.3.4"
ds = FileDataset(dstFile, {},
file_meta=file_meta, preamble=b"\0" * 128)
ds.PatientName = "Patient " + str(PatientID)
ds.PatientID = str(PatientID)
# Set creation date/time
dt = datetime.datetime.now()
ds.ContentDate = dt.strftime('%Y%m%d')
timeStr = dt.strftime('%H%M%S.%f')
ds.ContentTime = timeStr
ds.PixelData = encapsulated_data
from pydicom.uid import RLELossless
ds.file_meta.TransferSyntaxUID = RLELossless
print("Writing: " + dstFile)
ds.save_as(dstFile)
def GetData(pid, dtm=True):
if dtm:
srcFile = path + 'DTM/Patient-'+str(pid)+'.dtm'
else:
srcFile = path + 'DMM/Patient-'+str(pid)+'.dmm'
dataset = pydicom.dcmread(srcFile)
dataset.file_meta.TransferSyntaxUID
dataset.BitsAllocated = 16
frames = decode_data_sequence(dataset.PixelData)
restored = []
for f in frames:
buf = io.BytesIO(f)
img = cv2.imdecode(np.frombuffer(buf.getbuffer(), np.ushort), -1)
restored.append(img)
restored = np.array(restored)
return restored
def CropSave(pid):
try:
to=(340, 390, 390)
restored = GetData(pid)
start0 = int(abs(restored.shape[0]-to[0])/2)
start1 = int(abs(restored.shape[1]-to[1])/2)
start2 = int(abs(restored.shape[2]-to[2])/2)
if restored.shape[0] >= to[0] and restored.shape[1]>=to[1] and restored.shape[2]>=to[2]:
cropped = restored[start0:start0+to[0], start1:start1+to[1], start2:start2+to[2]]
else:
cropped = np.empty(to)
if restored.shape[0] >= to[0]:
cropped[:, start1:start1+restored.shape[1], start2:start2+restored.shape[2]] = restored[start0:start0+to[0], :, :]
elif restored.shape[1]>=to[1]:
cropped[start0:start0 + restored.shape[0], :, :] = restored[:, start1:start1+to[1], start2:start2+to[2]]
else:
cropped[start0:start0 + restored.shape[0], start1:start1+restored.shape[1], start2:start2 + restored.shape[2]] = restored
dstFile = path + 'DCM/Patient-'+str(pid)+'.dcm'
SaveCompressedResults(cropped, dstFile, pid)
except:
print("Bad input ", pid)
def CropVolumesParallel():
files = [os.path.basename(file) for file in glob.glob(path +"DTM/*.dtm")]
files.sort(key=lambda x: int(x[8:-4]))
pids = [int(f[8:-4]) for f in files]
files = [os.path.basename(file) for file in glob.glob(path +"DCM/*.dcm")]
files.sort(key=lambda x: int(x[8:-4]))
pids_processed = [int(f[8:-4]) for f in files]
pidds = []
for pid in pids:
if not pid in pids_processed:
pidds.append(pid)
while len(pidds) > 0:
if len(pidds) < 20:
tasks = pidds[0:]
pidds = []
else:
tasks = pidds[:20]
pidds = pidds[20:]
print("Processing Patients {0}".format(tasks))
with Pool(15) as p:
p.map(CropSave, tasks)
p.close()
p.join()
# %%
# Convert segmented lung volumes to same size (with cropped)
# CropVolumesParallel()