Diff of /prostate_pathomics.m [000000] .. [be1edc]

Switch to unified view

a b/prostate_pathomics.m
1
 function status = prostate_pathomics
2
% Pathomic Feature Calculator
3
4
%% ------------------------------------------------------------------------
5
show_results = 0;
6
7
fid = fopen(sprintf('tile_seg_output1-%s.csv',datestr(now(),'mm_dd_yyyy')),'a');
8
fid2 = fopen(sprintf('tile_seg_output2-%s.csv',datestr(now(),'mm_dd_yyyy')),'a');
9
10
anot = {'Seminal_Vesicles','Atrophy','HGPIN','G3','G4FG','G4CG','G5','Tissue'}; % annotation classes
11
scanner = {'Huron','Olympus'}; % whole slide image scanners
12
13
for s = 1:numel(scanner)
14
    d = dir(sprintf('%s/*/*.tiff',scanner{s}));
15
    date = {d.date}';
16
17
    input_images = {d.name}';
18
    folder = {d.folder}';
19
    
20
    for i = 1:numel(d)
21
        grade_dir = strsplit(folder{i},'/');
22
        grade{i} = grade_dir{end};
23
        grade_number(i) = find(contains(anot,grade{i}));
24
    end
25
    
26
    for i = 1:numel(d)
27
        grade_dir = strsplit(folder{i},'/');
28
        grade{i} = grade_dir{end};
29
        grade_number(i) = find(contains(anot,grade{i}));
30
    end
31
    
32
    for x = 1:numel(input_images)
33
        fprintf('Processing: %s\n',input_images{x});
34
        im = imread(input_images{x});
35
        im_resized = imresize(im,0.4);
36
        
37
        % Image color deconvolution
38
        im_resized = im_resized(:,:,1:3);
39
        I = rgb2gray(im_resized);
40
        
41
        tissue_mask = I<200;
42
        tissue_mask = ~bwareaopen(~tissue_mask,6000); % removes rip noise
43
        tissue_mask = imgaussfilt(uint8(tissue_mask),4);
44
        tissue_mask = uint8(bwareaopen(tissue_mask,50000)); % help flood lumen
45
        tissue_mask_label = bwlabel(tissue_mask);
46
        
47
        [lumen_mask,epithelium_cells,epithelium_mask,stroma_mask] = gimmeSegs_prostate2(im_resized,0,0,0);
48
        
49
        disp('Cleaning up segmentations');
50
        epithelium_mask = epithelium_mask .* tissue_mask;
51
        stroma_mask = stroma_mask .* tissue_mask;
52
        lumen_mask_noise = lumen_mask .* tissue_mask; % masks small lumen and some epithelium
53
        lumen_mask_noise = bwareafilt(logical(lumen_mask_noise),[0 150]);
54
        
55
        % Clean up lumen
56
        if strcmp(scanner{s},'Huron')
57
            lumen_mask = im_resized(:,:,2)>240; % huron lumen more white than oly
58
        end
59
        se = strel('disk',1);
60
        lumen_mask = lumen_mask & ~lumen_mask_noise;
61
        lumen_mask = imclose(lumen_mask,se);
62
        lumen_mask = imfill(lumen_mask,'holes');
63
        lumen_mask = bwareaopen(lumen_mask,100); %100
64
        lumen_mask = imgaussfilt(uint8(lumen_mask),1);
65
% -------------------------------------------------------------------------
66
        % Clean up stroma
67
        stroma_mask = stroma_mask & ~lumen_mask & ~epithelium_cells;
68
        stroma_mask = bwmorph(stroma_mask,'bridge');
69
        stroma_mask = ~bwareaopen(~stroma_mask,200);
70
        stroma_mask = bwareaopen(stroma_mask,20);
71
        stroma_mask = imgaussfilt(uint8(stroma_mask),1);
72
        
73
% -------------------------------------------------------------------------
74
        % Clean up epithelium
75
        epithelium_mask = logical(epithelium_mask) + epithelium_cells;
76
        
77
        if grade_number(x) < 4 | grade_number(x) == 8
78
            se = strel('disk',4);
79
            epithelium_mask = imclose(epithelium_mask,se);
80
        elseif grade_number(x) == 6
81
            se = strel('disk',1);
82
            epithelium_mask = imclose(epithelium_mask,se);
83
        end
84
        
85
        epithelium_mask = logical(epithelium_mask) & ~lumen_mask & ~stroma_mask;
86
        
87
        epithelium_mask = bwmorph(epithelium_mask,'thick',2);
88
        epithelium_mask = bwareaopen(epithelium_mask,250);
89
        epithelium_mask = ~bwareaopen(~epithelium_mask,500);
90
        epithelium_mask = bwareaopen(epithelium_mask,500);
91
        epithelium_mask = imgaussfilt(uint8(epithelium_mask),1);
92
        
93
        epithelium_mask_filled = imfill(epithelium_mask,'holes') & ~lumen_mask & ~stroma_mask;
94
        epithelium_mask_filled = ~bwareaopen(~epithelium_mask_filled,100);
95
        epithelium_mask_filled = bwareaopen(epithelium_mask_filled,500);
96
        
97
        epithelium_mask_filled = imgaussfilt(uint8(epithelium_mask_filled),1);
98
        
99
% -------------------------------------------------------------------------
100
        lumen_mask = bwmorph(lumen_mask,'thick',2);
101
        lumen_mask = uint8(imclearborder(lumen_mask,4)); % removes any lumen touching tile edges
102
        
103
        disp('Segmenting Gland');
104
        SEL_image = stroma_mask + 2*lumen_mask + 3*epithelium_mask_filled;
105
        
106
        %         figure('Position',[100 2000, 1500, 900]);
107
        %         subplot(131); imagesc(im_resized); axis image
108
        %         title(input_images{x});
109
        %         subplot(132); imagesc(SEL_image); axis image
110
        %         title('SEL_image');
111
        %         subplot(133); imagesc(SEL_image_epi); axis image
112
        %         title('SEL_image separate epi');
113
        %         saveas(gcf,sprintf('SEL_%s',input_images{x}),'tif');
114
        
115
        
116
        % Begin epith_wall_thickness_calculation, so re-map the variables into the legacy code
117
        bw_lumen = uint8(lumen_mask);
118
        bw_lumen_label = bwlabel(bw_lumen);
119
        bw_epith_label = bwlabel(epithelium_mask);
120
        bw_stroma = stroma_mask;
121
        bw_epith = uint8(epithelium_mask);
122
        bw_epith_filled = epithelium_mask_filled;
123
        bw_epith_filled_label = bwlabel(bw_epith_filled);
124
        core_mask = tissue_mask;
125
        bw_cells = uint8(epithelium_cells);
126
        
127
        %         figure('Position',[100 2000, 1500, 900]);
128
        %         subplot(2,3,1);
129
        %         imagesc(im_resized); axis image;
130
        %         title('Raw Image')
131
        %         subplot(2,3,2);
132
        %         imagesc(tissue_mask_label); axis image;
133
        %         title('Tissue Mask')
134
        %         subplot(2,3,3);
135
        %         imagesc(bw_epith);axis image;
136
        %         title('Epithelium Mask');
137
        %         subplot(2,3,4);
138
        %         imagesc(bw_epith_label);axis image;
139
        %         title('Epithelium labels');
140
        %         subplot(2,3,5);
141
        %         imagesc(bw_lumen);axis image;
142
        %         title('Lumen Mask')
143
        %         subplot(2,3,6);
144
        %         imagesc(bw_stroma);axis image;
145
        %         title('Stroma Mask')
146
        %         % saveas(gcf,sprintf('seg_%s',input_images{x}),'tif');
147
        
148
% -------------------------------------------------------------------------
149
        % Stroma v epithelium area calculations
150
        stroma_area = bwarea(bw_stroma);
151
        epith_area = bwarea(bw_epith);
152
% -------------------------------------------------------------------------
153
        
154
        [Bl,Ll,Nl,Al] = bwboundaries(bw_lumen_label,'noholes');
155
        statsl = regionprops(Ll,'Area','Centroid','PixelList');
156
        
157
        [Be,Le,Ne,Ae] = bwboundaries(bw_epith_filled_label,'noholes');
158
        statse = regionprops(Le,'Area','Centroid','PixelList');
159
        
160
        colors=['b' 'g' 'r' 'c' 'm' 'y'];
161
        %         colors = ['c' 'c' 'c' 'c' 'c' 'c'];
162
        
163
        ep_lb = [];
164
        
165
%% ------------------------------------------------------------------------
166
        bw_lumen_roundness = bw_lumen_label;
167
        bw_lumen_area = bw_lumen_label;
168
        bw_epith_thickness = bw_epith_filled_label;
169
        bw_cell_frac = bw_epith_filled_label;
170
        bw_epith_size = bw_epith_filled_label;
171
        bw_epith_roundness = bw_epith_filled_label;
172
        lumen_tort = [];
173
        epith_size = [];
174
        cell_frac = [];
175
        wall_thickness = [];
176
        min_lum_index_thick = [];
177
        wall_thick = [];
178
        epith_tort = [];
179
        
180
%         figure('Position',[100 100 1500 1500])
181
%         imagesc(im_resized);axis image; hold on;
182
        
183
        for i = 1:length(Bl)
184
            ep_lb(i) = bw_epith_filled_label(statsl(i).PixelList(1,2),statsl(i).PixelList(1,1)); % this maybe was backwards? 2,1?
185
            if ep_lb(i) == 0 %This indicates that an epithelium didn't get closed, and these are then excluded
186
                disp(sprintf('lumen number %i is connected with an epithelium edge and will be excluded',i));
187
                
188
                j = i; % in next step j is used for loop
189
                boundaryl = Bl{j};
190
                area = statsl(j).Area;
191
                delta_sq = diff(boundaryl).^2;
192
                perimeter = sum(sqrt(sum(delta_sq,2)));
193
                lumen_tort(j) = 4*pi*area/(perimeter^2);
194
                
195
                bw_lumen_roundness(bw_lumen_roundness == j) = lumen_tort(j); % replaces labeled lumen with tortuosity value
196
                bw_lumen_area(bw_lumen_area == j) = area;
197
                
198
                try
199
                    ep_lb(i) = bw_epith_filled_label(statsl(i).PixelList(2,2),statsl(i).PixelList(2,1));
200
                catch
201
                    disp('hey-you');
202
                end
203
            end
204
        end
205
        
206
        j = 0;
207
        inde = 0;
208
        for i = 1:length(Be) % Loop over the epithelium
209
            num_skipped = 0;
210
            if statse(i).Area<100000000 && statse(i).Area>0
211
                % plot the epithelium
212
                inde = inde+1;
213
                output_data.data(x).gland(inde).boundarye = Be{i};
214
                %             output_data.data(x).gland(inde).epith_size = statse(i).Area;
215
                ep_masked_cells_im = uint8(bw_epith_filled_label == i).* bw_cells;
216
                ep_masked_lumen_im = uint8(bw_epith_filled_label == i).* bw_lumen;
217
                output_data.data(x).gland(inde).epith_size = statse(i).Area - numel(find(ep_masked_lumen_im));
218
                output_data.data(x).gland(inde).cell_frac = sum(sum(ep_masked_cells_im)) / (statse(i).Area - sum(sum(ep_masked_lumen_im)));
219
                boundarye = Be{i};
220
                ep_com = [round(mean(boundarye(:,1))) round(mean(boundarye(:,2)))];
221
                %             current_core = tissue_mask_label(ep_com(1),ep_com(2));
222
                skip_pic = 0;
223
                try
224
                    glnd_im_out = im_resized(ep_com(1)-111:ep_com(1)+112,ep_com(2)-111:ep_com(2)+112,:);
225
                catch
226
                    skip_pic = 1;
227
                end
228
                cidx = mod(i,length(colors))+1;
229
                plot(boundarye(:,2), boundarye(:,1),...
230
                    colors(cidx),'LineWidth',2);
231
                
232
                areae = statse(i).Area;
233
                delta_sqe = diff(boundarye).^2;
234
                perimetere = sum(sqrt(sum(delta_sqe,2)));
235
                output_data.data(x).gland(inde).epith_tort = 4*pi*areae/perimetere^2;
236
                
237
                % For plots -----------------------------------------------
238
                epith_size(i) = statse(i).Area - numel(find(ep_masked_lumen_im));
239
                cell_frac(i) = sum(sum(ep_masked_cells_im)) / (statse(i).Area - sum(sum(ep_masked_lumen_im)));
240
                epith_tort(i) = 4*pi*areae/perimetere^2;
241
                %----------------------------------------------------------
242
                
243
                %randomize text position for better visibility
244
                rndRow = ceil(length(boundarye)/(mod(rand*i,7)+1));
245
                col = boundarye(rndRow,2); row = boundarye(rndRow,1);
246
                
247
                % Figure out the lumen within
248
                indl = 0;
249
                if numel(find(ep_lb==i))>0
250
                    % loop over the lumen within:
251
                    for j = find(ep_lb==i)
252
                        try
253
                            
254
                            if statsl(j).Area>1
255
                                indl = indl + 1;
256
                                % plot the lumen boundaries
257
                                boundaryl = Bl{j};
258
                                cidx = mod(i,length(colors))+1;
259
                                plot(boundaryl(:,2), boundaryl(:,1),...
260
                                    colors(cidx),'LineWidth',2);
261
                                %randomize text position for better visibility
262
                                rndRow = ceil(length(boundaryl)/(mod(rand*i,7)+1));
263
                                col = boundaryl(rndRow,2); row = boundaryl(rndRow,1);
264
                                
265
                                area = statsl(j).Area;
266
                                delta_sq = diff(boundaryl).^2;
267
                                perimeter = sum(sqrt(sum(delta_sq,2)));
268
                                output_data.data(x).gland(inde).lumen(indl).lumen_tort = 4*pi*area/perimeter^2;
269
                                output_data.data(x).gland(inde).lumen(indl).wall_thick = 0;
270
                                output_data.data(x).gland(inde).lumen(indl).area = area;
271
                                
272
                                % For plots -------------------------------
273
                                lumen_tort(j) = 4*pi*area/perimeter^2;
274
                                bw_lumen_roundness(bw_lumen_roundness == j) = lumen_tort(j); % replaces labeled lumen with tortuosity value
275
                                bw_lumen_area(bw_lumen_area == j) = area;
276
                                % -----------------------------------------
277
                                
278
                                wall_thickness = [];
279
                                min_lum_index_thick = [];
280
                                for jj = 1:size(Bl{j},1)
281
                                    ind = 1;
282
                                    for k = 1:5:size(Be{i},1)
283
                                        wall_thickness(ind) = sqrt((Bl{j}(jj,1)-Be{i}(k,1))^2 + (Bl{j}(jj,2)-Be{i}(k,2))^2);
284
                                        ind = ind+1;
285
                                    end
286
                                    min_lum_index_thick(jj) = min(wall_thickness);
287
                                    if show_results == 1
288
                                        if rem(jj,30)==0
289
                                            h = text(Bl{j}(jj,2), Bl{j}(jj,1), sprintf('%0.2f',min_lum_index_thick(jj)));
290
                                            set(h,'Color',colors(cidx),...
291
                                                'FontSize',8);
292
                                        end
293
                                    end
294
                                end
295
                                
296
                                output_data.data(x).gland(inde).lumen(indl).wall_thick = mean(min_lum_index_thick);
297
                                wall_thick(i) = mean(min_lum_index_thick);
298
                                
299
                                if show_results == 1
300
                                    h = text(Bl{j}(1,2)+20, Bl{j}(1,1)+10, sprintf('%i\n%i\n%0.2f\n%0.2f',statse(i).Area,statsl(j).Area,output_data.data(x).gland(inde).lumen(indl).lumen_tort,output_data.data(x).gland(inde).lumen(indl).wall_thick))  ;
301
                                    set(h,'Color',colors(cidx),...
302
                                        'FontSize',8);
303
                                end
304
                                
305
                                % output_data.data(x).gland(inde)
306
                                % disp('results shown');
307
                                %
308
%                                 try
309
                                fprintf(fid,'%s,%s,%i,%s,%i,%i,%i,%f,%f,%f,%f,%f,%f,%f,%f\n',...
310
                                    scanner{s},input_images{x},x,grade{x},...
311
                                    grade_number(x),inde,indl,stroma_area,epith_area,...
312
                                    output_data.data(x).gland(inde).epith_size,...
313
                                    output_data.data(x).gland(inde).epith_tort,...
314
                                    output_data.data(x).gland(inde).cell_frac,...
315
                                    output_data.data(x).gland(inde).lumen(indl).area,...
316
                                    output_data.data(x).gland(inde).lumen(indl).wall_thick,...
317
                                    output_data.data(x).gland(inde).lumen(indl).lumen_tort);
318
                            end
319
                        catch
320
                            disp('Debug point')
321
                        end
322
                    end
323
                    
324
                    try
325
                        
326
                        tot_lum_area = [];
327
                        tot_wall_thick = [];
328
                        tot_lum_tort = [];
329
                        
330
                        for mmm = 1:numel(output_data.data(x).gland(inde).lumen(:))
331
                            tot_lum_area = [tot_lum_area output_data.data(x).gland(inde).lumen(mmm).area];
332
                            tot_wall_thick = [tot_wall_thick output_data.data(x).gland(inde).lumen(mmm).wall_thick];
333
                            tot_lum_tort = [tot_lum_tort output_data.data(x).gland(inde).lumen(mmm).lumen_tort];
334
                        end
335
                        fprintf(fid2,'%s,%s,%i,%s,%i,%i,%i,%f,%f,%f,%f,%f,%f,%f,%f\n',...
336
                            scanner{s},input_images{x},x,grade{x},grade_number(x),inde,...
337
                            output_data.data(x).gland(inde).epith_size,...
338
                            output_data.data(x).gland(inde).epith_tort,...
339
                            output_data.data(x).gland(inde).cell_frac,...
340
                            mean(tot_lum_area),...
341
                            mean(tot_wall_thick),...
342
                            mean(tot_lum_tort),...
343
                            sum(sum(bw_lumen))/sum(sum(core_mask)),...
344
                            sum(sum(bw_epith))/sum(sum(core_mask)),...
345
                            sum(sum(bw_stroma))/sum(sum(core_mask)));
346
                        
347
                    catch
348
                        disp('debug point');
349
                    end
350
                    
351
                else
352
                    disp('skipping epith, no lumen');
353
                    
354
                    ep_masked_cells_im = uint8(bw_epith_filled_label == i).* bw_cells;
355
                    ep_masked_lumen_im = uint8(bw_epith_filled_label == i).* bw_lumen;
356
                    epith_size(i) = statse(i).Area - numel(find(ep_masked_lumen_im));
357
                    cell_frac(i) = sum(sum(ep_masked_cells_im)) / (statse(i).Area - sum(sum(ep_masked_lumen_im)));
358
                    
359
                    boundarye = Be{i};
360
                    areae = statse(i).Area;
361
                    delta_sqe = diff(boundarye).^2;
362
                    perimetere = sum(sqrt(sum(delta_sqe,2)));
363
                    epith_tort(i) = 4*pi*areae/perimetere^2;
364
                    
365
                end
366
                
367
            else
368
                disp('skipping epith, too big');
369
                
370
                boundaryl = Bl{j};
371
                area = statsl(j).Area;
372
                delta_sq = diff(boundaryl).^2;
373
                perimeter = sum(sqrt(sum(delta_sq,2)));
374
                lumen_tort(j) = 4*pi*area/(perimeter^2);
375
                
376
                bw_lumen_roundness(bw_lumen_roundness == j) = lumen_tort(j); % replaces labeled lumen with tortuosity value
377
                bw_lumen_area(bw_lumen_area == j) = area;
378
                
379
                ep_masked_cells_im = uint8(bw_epith_filled_label == i).* bw_cells;
380
                ep_masked_lumen_im = uint8(bw_epith_filled_label == i).* bw_lumen;
381
                epith_size(i) = statse(i).Area - numel(find(ep_masked_lumen_im));
382
                cell_frac(i) = sum(sum(ep_masked_cells_im)) / (statse(i).Area - sum(sum(ep_masked_lumen_im)));
383
                
384
                boundarye = Be{i};
385
                areae = statse(i).Area;
386
                delta_sqe = diff(boundarye).^2;
387
                perimetere = sum(sqrt(sum(delta_sqe,2)));
388
                epith_tort(i) = 4*pi*areae/perimetere^2;
389
                
390
            end
391
%% -------------------------------------------------------------
392
            % display epithelium tort, size, and cell frac
393
            bw_epith_roundness(bw_epith_roundness == i) = epith_tort(i);
394
            bw_epith_size(bw_epith_size == i) = epith_size(i);
395
            bw_cell_frac(bw_cell_frac == i) = cell_frac(i);
396
            try
397
                bw_epith_thickness(bw_epith_thickness == i) = wall_thick(i);
398
            catch
399
                bw_epith_thickness(bw_epith_thickness == i) = 0;
400
            end
401
%% -------------------------------------------------------------
402
        end
403
%% ------------------------------------------------------------------------
404
%         % display features
405
%         figure('Position',[100 100 1500 1500])
406
%         imshow(im_resized); axis image; hold on;
407
%         h = imagesc(bw_lumen_roundness); caxis([0 0.7]); % change caxis to see colormap better
408
%         hold off
409
%         
410
%         [M,N] = size(bw_lumen_roundness);
411
%         alpha_data = bw_lumen_roundness > 0;
412
%         alpha_data = alpha_data(1:M, 1:N);
413
%         set(h, 'AlphaData', alpha_data);
414
%         title('lumen tort 2');
415
%         
416
%         figure('Position',[100 100 1500 1500])
417
%         imshow(im_resized); axis image; hold on;
418
%         h = imagesc(bw_lumen_area); caxis([0 3*10^4]); % change caxis to see colormap better
419
%         hold off
420
%         
421
%         [M,N] = size(bw_lumen_area);
422
%         alpha_data = bw_lumen_area > 0;
423
%         alpha_data = alpha_data(1:M, 1:N);
424
%         set(h, 'AlphaData', alpha_data);
425
%         title('lumen area 2');
426
%         
427
%         figure('Position',[100 100 1500 1500])
428
%         imshow(im_resized); axis image; hold on;
429
%         h = imagesc(bw_epith_thickness);
430
%         hold off
431
%         
432
%         [M,N] = size(bw_epith_thickness);
433
%         alpha_data = bw_epith_thickness > 0;
434
%         alpha_data = alpha_data(1:M, 1:N);
435
%         set(h, 'AlphaData', alpha_data);
436
%         title('epith thick 2')
437
%         
438
%         figure('Position',[100 100 1500 1500])
439
%         imshow(im_resized); axis image; hold on;
440
%         h = imagesc(bw_epith_roundness); caxis([0 1]); % change caxis to see colormap better
441
%         hold off
442
%         
443
%         [M,N] = size(bw_epith_roundness);
444
%         alpha_data = bw_epith_roundness > 0;
445
%         alpha_data = alpha_data(1:M, 1:N);
446
%         set(h, 'AlphaData', alpha_data);
447
%         title('epith tort 2')
448
%         
449
%         figure('Position',[100 100 1500 1500])
450
%         imshow(im_resized); axis image; hold on;
451
%         h = imagesc(bw_epith_size); %caxis([0 250]);
452
%         hold off
453
%         
454
%         [M,N] = size(bw_epith_size);
455
%         alpha_data = bw_epith_size > 0;
456
%         alpha_data = alpha_data(1:M, 1:N);
457
%         set(h, 'AlphaData', alpha_data);
458
%         title('epith_size 2');
459
%         
460
%         figure('Position',[100 100 1500 1500])
461
%         imshow(im_resized); axis image; hold on;
462
%         h = imagesc(bw_cell_frac); caxis([0 1]);
463
%         hold off
464
%         
465
%         [M,N] = size(bw_cell_frac);
466
%         alpha_data = bw_cell_frac > 0;
467
%         alpha_data = alpha_data(1:M, 1:N);
468
%         set(h, 'AlphaData', alpha_data);
469
%         title('cell frac 2')
470
%% ------------------------------------------------------------------------
471
        fprintf('%s done\n',input_images{x});
472
        % saveas(gcf,sprintf('outline_seg_%s',input_images{x}),'tif');
473
        close all
474
        
475
    end
476
end
477
fclose(fid);
478
status = 'done';
479
end