|
a |
|
b/scripts/ConvertDICOMToAVI.ipynb |
|
|
1 |
{ |
|
|
2 |
"cells": [ |
|
|
3 |
{ |
|
|
4 |
"cell_type": "code", |
|
|
5 |
"execution_count": 12, |
|
|
6 |
"metadata": {}, |
|
|
7 |
"outputs": [], |
|
|
8 |
"source": [ |
|
|
9 |
"# David Ouyang 10/2/2019\n", |
|
|
10 |
"\n", |
|
|
11 |
"# Notebook which iterates through a folder, including subfolders, \n", |
|
|
12 |
"# and convert DICOM files to AVI files of a defined size (natively 112 x 112)\n", |
|
|
13 |
"\n", |
|
|
14 |
"import re\n", |
|
|
15 |
"import os, os.path\n", |
|
|
16 |
"from os.path import splitext\n", |
|
|
17 |
"import pydicom as dicom\n", |
|
|
18 |
"import numpy as np\n", |
|
|
19 |
"from pydicom.uid import UID, generate_uid\n", |
|
|
20 |
"import shutil\n", |
|
|
21 |
"from multiprocessing import dummy as multiprocessing\n", |
|
|
22 |
"import time\n", |
|
|
23 |
"import subprocess\n", |
|
|
24 |
"import datetime\n", |
|
|
25 |
"from datetime import date\n", |
|
|
26 |
"import sys\n", |
|
|
27 |
"import cv2\n", |
|
|
28 |
"#from scipy.misc import imread\n", |
|
|
29 |
"import matplotlib.pyplot as plt\n", |
|
|
30 |
"import sys\n", |
|
|
31 |
"from shutil import copy\n", |
|
|
32 |
"import math\n", |
|
|
33 |
"\n", |
|
|
34 |
"destinationFolder = \"Output Folder Name\"\n" |
|
|
35 |
] |
|
|
36 |
}, |
|
|
37 |
{ |
|
|
38 |
"cell_type": "code", |
|
|
39 |
"execution_count": 10, |
|
|
40 |
"metadata": {}, |
|
|
41 |
"outputs": [ |
|
|
42 |
{ |
|
|
43 |
"name": "stdout", |
|
|
44 |
"output_type": "stream", |
|
|
45 |
"text": [ |
|
|
46 |
"Requirement already satisfied: pillow in c:\\programdata\\anaconda3\\lib\\site-packages (6.2.0)\n", |
|
|
47 |
"Requirement already satisfied: scipy in c:\\programdata\\anaconda3\\lib\\site-packages (1.3.1)\n" |
|
|
48 |
] |
|
|
49 |
} |
|
|
50 |
], |
|
|
51 |
"source": [ |
|
|
52 |
"# Dependencies you might need to run code\n", |
|
|
53 |
"# Commonly missing\n", |
|
|
54 |
"\n", |
|
|
55 |
"#!pip install pydicom\n", |
|
|
56 |
"#!pip install opencv-python\n" |
|
|
57 |
] |
|
|
58 |
}, |
|
|
59 |
{ |
|
|
60 |
"cell_type": "code", |
|
|
61 |
"execution_count": 2, |
|
|
62 |
"metadata": {}, |
|
|
63 |
"outputs": [], |
|
|
64 |
"source": [ |
|
|
65 |
"def mask(output):\n", |
|
|
66 |
" dimension = output.shape[0]\n", |
|
|
67 |
" \n", |
|
|
68 |
" # Mask pixels outside of scanning sector\n", |
|
|
69 |
" m1, m2 = np.meshgrid(np.arange(dimension), np.arange(dimension))\n", |
|
|
70 |
" \n", |
|
|
71 |
"\n", |
|
|
72 |
" mask = ((m1+m2)>int(dimension/2) + int(dimension/10)) \n", |
|
|
73 |
" mask *= ((m1-m2)<int(dimension/2) + int(dimension/10))\n", |
|
|
74 |
" mask = np.reshape(mask, (dimension, dimension)).astype(np.int8)\n", |
|
|
75 |
" maskedImage = cv2.bitwise_and(output, output, mask = mask)\n", |
|
|
76 |
" \n", |
|
|
77 |
" #print(maskedImage.shape)\n", |
|
|
78 |
" \n", |
|
|
79 |
" return maskedImage\n", |
|
|
80 |
"\n" |
|
|
81 |
] |
|
|
82 |
}, |
|
|
83 |
{ |
|
|
84 |
"cell_type": "code", |
|
|
85 |
"execution_count": 3, |
|
|
86 |
"metadata": {}, |
|
|
87 |
"outputs": [], |
|
|
88 |
"source": [ |
|
|
89 |
"def makeVideo(fileToProcess, destinationFolder):\n", |
|
|
90 |
" try:\n", |
|
|
91 |
" fileName = fileToProcess.split('\\\\')[-1] #\\\\ if windows, / if on mac or sherlock\n", |
|
|
92 |
" #hex(abs(hash(fileToProcess.split('/')[-1]))).upper()\n", |
|
|
93 |
"\n", |
|
|
94 |
" if not os.path.isdir(os.path.join(destinationFolder,fileName)):\n", |
|
|
95 |
"\n", |
|
|
96 |
" dataset = dicom.dcmread(fileToProcess, force=True)\n", |
|
|
97 |
" testarray = dataset.pixel_array\n", |
|
|
98 |
"\n", |
|
|
99 |
" frame0 = testarray[0]\n", |
|
|
100 |
" mean = np.mean(frame0, axis=1)\n", |
|
|
101 |
" mean = np.mean(mean, axis=1)\n", |
|
|
102 |
" yCrop = np.where(mean<1)[0][0]\n", |
|
|
103 |
" testarray = testarray[:, yCrop:, :, :]\n", |
|
|
104 |
"\n", |
|
|
105 |
" bias = int(np.abs(testarray.shape[2] - testarray.shape[1])/2)\n", |
|
|
106 |
" if bias>0:\n", |
|
|
107 |
" if testarray.shape[1] < testarray.shape[2]:\n", |
|
|
108 |
" testarray = testarray[:, :, bias:-bias, :]\n", |
|
|
109 |
" else:\n", |
|
|
110 |
" testarray = testarray[:, bias:-bias, :, :]\n", |
|
|
111 |
"\n", |
|
|
112 |
"\n", |
|
|
113 |
" print(testarray.shape)\n", |
|
|
114 |
" frames,height,width,channels = testarray.shape\n", |
|
|
115 |
"\n", |
|
|
116 |
" fps = 30\n", |
|
|
117 |
"\n", |
|
|
118 |
" try:\n", |
|
|
119 |
" fps = dataset[(0x18, 0x40)].value\n", |
|
|
120 |
" except:\n", |
|
|
121 |
" print(\"couldn't find frame rate, default to 30\")\n", |
|
|
122 |
"\n", |
|
|
123 |
" fourcc = cv2.VideoWriter_fourcc('M','J','P','G')\n", |
|
|
124 |
" video_filename = os.path.join(destinationFolder, fileName + '.avi')\n", |
|
|
125 |
" out = cv2.VideoWriter(video_filename, fourcc, fps, cropSize)\n", |
|
|
126 |
"\n", |
|
|
127 |
"\n", |
|
|
128 |
" for i in range(frames):\n", |
|
|
129 |
"\n", |
|
|
130 |
" outputA = testarray[i,:,:,0]\n", |
|
|
131 |
" smallOutput = outputA[int(height/10):(height - int(height/10)), int(height/10):(height - int(height/10))]\n", |
|
|
132 |
"\n", |
|
|
133 |
" # Resize image\n", |
|
|
134 |
" output = cv2.resize(smallOutput, cropSize, interpolation = cv2.INTER_CUBIC)\n", |
|
|
135 |
"\n", |
|
|
136 |
" finaloutput = mask(output)\n", |
|
|
137 |
"\n", |
|
|
138 |
"\n", |
|
|
139 |
" finaloutput = cv2.merge([finaloutput,finaloutput,finaloutput])\n", |
|
|
140 |
" out.write(finaloutput)\n", |
|
|
141 |
"\n", |
|
|
142 |
" out.release()\n", |
|
|
143 |
"\n", |
|
|
144 |
" else:\n", |
|
|
145 |
" print(fileName,\"hasAlreadyBeenProcessed\")\n", |
|
|
146 |
" except:\n", |
|
|
147 |
" print(\"something filed, not sure what, have to debug\", fileName)\n", |
|
|
148 |
" return 0" |
|
|
149 |
] |
|
|
150 |
}, |
|
|
151 |
{ |
|
|
152 |
"cell_type": "code", |
|
|
153 |
"execution_count": null, |
|
|
154 |
"metadata": {}, |
|
|
155 |
"outputs": [], |
|
|
156 |
"source": [ |
|
|
157 |
"AllA4cNames = \"Input Folder Name\"\n", |
|
|
158 |
"\n", |
|
|
159 |
"count = 0\n", |
|
|
160 |
" \n", |
|
|
161 |
"cropSize = (112,112)\n", |
|
|
162 |
"subfolders = os.listdir(AllA4cNames)\n", |
|
|
163 |
"\n", |
|
|
164 |
"\n", |
|
|
165 |
"for folder in subfolders:\n", |
|
|
166 |
" print(folder)\n", |
|
|
167 |
"\n", |
|
|
168 |
" for content in os.listdir(os.path.join(AllA4cNames, folder)):\n", |
|
|
169 |
" for subcontent in os.listdir(os.path.join(AllA4cNames, folder, content)):\n", |
|
|
170 |
" count += 1\n", |
|
|
171 |
" \n", |
|
|
172 |
"\n", |
|
|
173 |
" VideoPath = os.path.join(AllA4cNames, folder, content, subcontent)\n", |
|
|
174 |
"\n", |
|
|
175 |
" print(count, folder, content, subcontent)\n", |
|
|
176 |
"\n", |
|
|
177 |
" if not os.path.exists(os.path.join(destinationFolder,subcontent + \".avi\")):\n", |
|
|
178 |
" makeVideo(VideoPath, destinationFolder)\n", |
|
|
179 |
" else:\n", |
|
|
180 |
" print(\"Already did this file\", VideoPath)\n", |
|
|
181 |
"\n", |
|
|
182 |
"\n", |
|
|
183 |
"print(len(AllA4cFilenames))" |
|
|
184 |
] |
|
|
185 |
}, |
|
|
186 |
{ |
|
|
187 |
"cell_type": "code", |
|
|
188 |
"execution_count": null, |
|
|
189 |
"metadata": {}, |
|
|
190 |
"outputs": [], |
|
|
191 |
"source": [] |
|
|
192 |
} |
|
|
193 |
], |
|
|
194 |
"metadata": { |
|
|
195 |
"kernelspec": { |
|
|
196 |
"display_name": "Python 3", |
|
|
197 |
"language": "python", |
|
|
198 |
"name": "python3" |
|
|
199 |
}, |
|
|
200 |
"language_info": { |
|
|
201 |
"codemirror_mode": { |
|
|
202 |
"name": "ipython", |
|
|
203 |
"version": 3 |
|
|
204 |
}, |
|
|
205 |
"file_extension": ".py", |
|
|
206 |
"mimetype": "text/x-python", |
|
|
207 |
"name": "python", |
|
|
208 |
"nbconvert_exporter": "python", |
|
|
209 |
"pygments_lexer": "ipython3", |
|
|
210 |
"version": "3.7.4" |
|
|
211 |
} |
|
|
212 |
}, |
|
|
213 |
"nbformat": 4, |
|
|
214 |
"nbformat_minor": 2 |
|
|
215 |
} |