Skip to content

Commit f6783f6

Browse files
committed
ENH: codes for nodule characterization
1 parent e7514b2 commit f6783f6

File tree

4 files changed

+842
-7
lines changed

4 files changed

+842
-7
lines changed

main_dicom_to_blocks.m

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
%% main function
2+
clc;
3+
clear;
4+
5+
%% toolbox
6+
addpath(genpath([pwd '/toolbox']))
7+
8+
%% module path values
9+
util_path=[pwd '/util'];
10+
input_path=[pwd '/io'];
11+
12+
%% module addpath
13+
addpath(genpath(util_path));
14+
addpath(genpath(input_path));
15+
16+
17+
%% set global values
18+
global path_nodule;
19+
global path_data;
20+
21+
path_nodule = [pwd '/DATA']; %pwd : returns the current directory
22+
path_data = [pwd '/DATA/LIDC-IDRI/']; %dcm files directory
23+
24+
%% set values
25+
iso_px_size=1; % a standard unit ('mm-unit')
26+
l_offset = [0, 0, 0;
27+
1, 0, 0;
28+
-1, 0, 0;
29+
0, 1, 0;
30+
0, -1, 0;
31+
0, 0, 1;
32+
0, 0, -1;
33+
1, 1, 0;
34+
-1, 1, 0;
35+
-1, -1, 0;
36+
1, -1, 0;
37+
1, 0, 1;
38+
-1, 0, 1;
39+
-1, 0, -1;
40+
1, 0, -1;
41+
0, 1, 1;
42+
0, -1, 1;
43+
0, -1, -1;
44+
0, 1, -1;
45+
1, 1, 1
46+
-1, 1, 1
47+
-1, -1, 1
48+
-1, 1, -1
49+
-1, -1, -1
50+
1, -1, 1
51+
1, -1, -1
52+
1, 1, -1];
53+
54+
55+
%% directory paths
56+
nrrd_img_path=[path_nodule '/nodule_radiomics/'];
57+
58+
%% make directory
59+
if ~isdir(nrrd_img_path); mkdir(nrrd_img_path); end
60+
61+
62+
%% saved data load or not
63+
load_input = true;
64+
65+
%% get pids
66+
filename_pid_list = [path_nodule '/dicom_pid_list.mat'];
67+
if(fn_check_load_data(filename_pid_list, load_input))
68+
[dicom_path_list,pid_list]=fn_scan_pid(path_data);
69+
70+
save(filename_pid_list, 'dicom_path_list', 'pid_list');
71+
else
72+
load(filename_pid_list);
73+
end
74+
75+
is_pass = 0;
76+
77+
%% main process
78+
%for idx = randperm(numel(pid_list))
79+
for idx = 1:numel(pid_list)
80+
pid = pid_list{idx};
81+
82+
if strfind(pid, '0405') > 0
83+
is_pass = 0;
84+
else
85+
is_pass = 1;
86+
end
87+
88+
if is_pass > 0 || sum(strfind(pid,'.')) > 0
89+
continue
90+
end
91+
92+
tic % tic starts a stopwatch timer
93+
fprintf('%d %s\n', idx, pid);
94+
%% input part
95+
96+
dicom_path = dicom_path_list{idx};
97+
[lung_img_3d, nodule_img_3d, dicom_tags, thick, pixelsize, nodule_info] = fn_dicom_read(dicom_path,pid);
98+
99+
if numel(nodule_info) == 0
100+
continue
101+
end
102+
103+
[nodule_img_3d, nodule_info] = fn_nodule_info_update(lung_img_3d,nodule_img_3d,nodule_info,thick,pixelsize);
104+
105+
106+
%% nrrd
107+
if ~isdir([nrrd_img_path '/' pid]); mkdir([nrrd_img_path '/' pid]); end
108+
writetable([nodule_info(:,[1:3 5:6 end 10:12 15:17]) nodule_info.Characteristics], [nrrd_img_path pid '/' pid '.csv'])
109+
110+
meta = struct();
111+
meta.type = 'int16';
112+
meta.encoding = 'gzip';
113+
meta.spaceorigin = dicom_tags{1}.ImagePositionPatient';
114+
meta.spacedirections = [reshape(dicom_tags{1}.ImageOrientationPatient,3,2),[0;0;1]]*diag([pixelsize; thick]);
115+
meta.endian = 'little';
116+
117+
fn_nrrdwrite([nrrd_img_path '/' pid '/' pid '_CT.nrrd'], int16(lung_img_3d(:,:,end:-1:1)), meta);
118+
119+
meta.type = 'uint8';
120+
fn_nrrdwrite([nrrd_img_path '/' pid '/' pid '_CT_all-label.nrrd'], uint8(nodule_img_3d(:,:,end:-1:1)>0), meta);
121+
% for sid = 1:4
122+
% str_sid = num2str(sid);
123+
% sid_nodule_image_3d = uint8(bitand(uint8(nodule_img_3d),2^(sid-1))>0);
124+
% sid_nodules = strcmp(nodule_info.sid, str_sid);
125+
% if sum(sid_nodules) > 0
126+
% fn_nrrdwrite([nrrd_img_path '/' pid '/' pid '_CT_Phy' str_sid '-label.nrrd'], sid_nodule_image_3d(:,:,end:-1:1), meta)
127+
% end
128+
% end
129+
130+
%% nrrd 1mm
131+
[interpol_lung_img_3d,interpol_nodule_img_3d]=fn_interpol3d(lung_img_3d,nodule_img_3d,thick,pixelsize,iso_px_size);
132+
133+
meta.type = 'int16';
134+
meta.spacedirections = [reshape(dicom_tags{1}.ImageOrientationPatient,3,2),[0;0;1]];
135+
fn_nrrdwrite([nrrd_img_path '/' pid '/' pid '_CT-1mm.nrrd'], int16(interpol_lung_img_3d(:,:,end:-1:1)), meta);
136+
meta.type = 'uint8';
137+
fn_nrrdwrite([nrrd_img_path '/' pid '/' pid '_CT_all-1mm-label.nrrd'], uint8(interpol_nodule_img_3d(:,:,end:-1:1)>0), meta);
138+
139+
140+
141+
fprintf('dicom images and annotations converted ... \t\t\t %6.2f sec\n', toc);
142+
143+
144+
%% blocks
145+
lung_img_3d = interpol_lung_img_3d;
146+
nodule_img_3d = interpol_nodule_img_3d;
147+
meta_lung_img_3d = meta;
148+
sz_img_3d = size(lung_img_3d);
149+
150+
lung_img_3d(lung_img_3d<-1000) = -1000;
151+
lung_img_3d(lung_img_3d>400) = 400;
152+
153+
lung_img_3d = (double(lung_img_3d)+1000)/1400;
154+
155+
meta.type = 'float';
156+
meta.encoding = 'gzip';
157+
meta.endian = 'little';
158+
159+
if ~isdir(['output/' pid]); mkdir(['output/' pid]); end
160+
non_nodule_count = 0;
161+
for nid = 1:size(nodule_info,1)
162+
o_volume = table2array(nodule_info(nid,5));
163+
o_centroid = round(table2array(nodule_info(nid,8)));
164+
if sum(isnan(o_centroid)) > 0; continue; end
165+
166+
% nodules
167+
for oid = 1:size(l_offset,1)
168+
offset = l_offset(oid,:);
169+
centroid = o_centroid + offset;% one voxel offset
170+
bbox = [centroid-16+1,centroid+16];
171+
172+
if sum(bbox(1:3) < 1) > 0 || sum(bbox(4:6) > sz_img_3d) > 0
173+
continue
174+
end
175+
176+
lung_blk_3d = lung_img_3d(bbox(2):bbox(5),bbox(1):bbox(4),bbox(3):bbox(6));
177+
nodule_blk_3d = nodule_img_3d(bbox(2):bbox(5),bbox(1):bbox(4),bbox(3):bbox(6));
178+
179+
180+
if sum(nodule_blk_3d(:))/o_volume < 0.5
181+
continue
182+
end
183+
184+
%display(mean(lung_blk_3d(:)))
185+
186+
meta.spaceorigin = meta_lung_img_3d.spaceorigin+bbox(1:3)-1;
187+
fn_nrrdwrite(['output/' pid '/' pid sprintf('_%03d_%03d_%03d',centroid([3 1 2])) '_32_N_' num2str(mean(lung_blk_3d(:)),2) '_' num2str(oid-1, '%02d') '.nrrd'], double(lung_blk_3d), meta);
188+
% if oid == 1
189+
% for rot = 1:3
190+
% fn_nrrdwrite(['output/' pid '/' pid sprintf('_%03d_%03d_%03d',centroid([3 1 2])) '_32_N_' num2str(mean(lung_blk_3d(:)),2) '_r' num2str(rot*90, '%03d') '.nrrd'], double(rot90(lung_blk_3d,rot)), meta);
191+
% end
192+
% end
193+
end
194+
195+
% non nodules
196+
for a = randn(3,round(rand()*500))
197+
offset = round(a'*32);
198+
centroid = o_centroid + offset;% background sample
199+
bbox = [centroid-16+1,centroid+16];
200+
if sum(bbox(1:3) < 1) > 0 || sum(bbox(4:6) > sz_img_3d) > 0
201+
continue
202+
end
203+
lung_blk_3d = lung_img_3d(bbox(2):bbox(5),bbox(1):bbox(4),bbox(3):bbox(6));
204+
nodule_blk_3d = nodule_img_3d(bbox(2):bbox(5),bbox(1):bbox(4),bbox(3):bbox(6));
205+
if mean(nodule_blk_3d(:)) == 0 && std(lung_blk_3d(:)) ~= 0
206+
%display(mean(lung_blk_3d(:)))
207+
meta.spaceorigin = meta_lung_img_3d.spaceorigin+bbox(1:3)-1;
208+
fn_nrrdwrite(['output/' pid '/' pid sprintf('_%03d_%03d_%03d',centroid([3 1 2])) '_32_B_' num2str(mean(lung_blk_3d(:)),2) '.nrrd'], double(lung_blk_3d), meta);
209+
non_nodule_count = non_nodule_count + 1;
210+
end
211+
if non_nodule_count > 1000
212+
break
213+
end
214+
end
215+
end
216+
217+
fprintf('block images saved ... \t\t\t %6.2f sec\n', toc);
218+
219+
220+
fclose all;
221+
end
222+
223+
224+
% module rmpath
225+
% rmpath('./io');
226+
% rmpath('./interpolation');
227+
% rmpath('./segmentation');
228+
% rmpath('./nodule_candidate_detection');

0 commit comments

Comments
 (0)