|
a |
|
b/functions/functions_preProc/segmentStain.m |
|
|
1 |
function [maskACClopeOpen] = segmentStain(im, imColorNorm, filename, dirResults, params, plotta, savefile) |
|
|
2 |
|
|
|
3 |
%------------------------------------ |
|
|
4 |
%otsu (intensity) on E |
|
|
5 |
if size(imColorNorm, 3) == 3 |
|
|
6 |
imColorNorm_gray = rgb2gray(imColorNorm); |
|
|
7 |
end %if size |
|
|
8 |
|
|
|
9 |
th = graythresh(imColorNorm_gray) + params.offsetOtsuIntens; |
|
|
10 |
|
|
|
11 |
%thresh = imColorNorm_gray < th*255; |
|
|
12 |
thresh = imColorNorm_gray < th; |
|
|
13 |
threshOne = connComp2(thresh, 1, 1); |
|
|
14 |
|
|
|
15 |
maskThresh = threshOne; |
|
|
16 |
|
|
|
17 |
% figure |
|
|
18 |
% imshow(maskThresh) |
|
|
19 |
% pause |
|
|
20 |
|
|
|
21 |
|
|
|
22 |
%------------------------------------ |
|
|
23 |
%fuzzy c-means on E |
|
|
24 |
%imAlt = im2uint8(rgb2lab(im)); |
|
|
25 |
imAlt = im2uint8(rgb2hsv(im)); |
|
|
26 |
|
|
|
27 |
[C, U, LUT, H] = FastFCMeans(imAlt, params.nClusters); |
|
|
28 |
%analyze centers, discard greatest one (white background) |
|
|
29 |
% [C_sort, indC] = sort(C, 'ascend'); |
|
|
30 |
[C_sort, indC] = sort(C, 'descend'); %for hsv |
|
|
31 |
C_select = indC(1 : params.classesToConsider); |
|
|
32 |
% %memberships to maps |
|
|
33 |
L = LUT2label(imAlt, LUT); |
|
|
34 |
Umap = FM2map(imAlt, U, H); |
|
|
35 |
|
|
|
36 |
%memberships |
|
|
37 |
if plotta |
|
|
38 |
fh1 = figure; |
|
|
39 |
subplot(1,3,1) |
|
|
40 |
imshow(rgb2gray(Umap(:,:,:,1)),[]); |
|
|
41 |
subplot(1,3,2) |
|
|
42 |
imshow(rgb2gray(Umap(:,:,:,2)),[]); |
|
|
43 |
subplot(1,3,3) |
|
|
44 |
imshow(rgb2gray(Umap(:,:,:,3)),[]); |
|
|
45 |
|
|
|
46 |
str = [filename '; class memberships']; |
|
|
47 |
|
|
|
48 |
mtit(fh1, str, 'Interpreter', 'none', 'fontsize', 14, 'color', [1 0 0], 'xoff', .0, 'yoff', .0); |
|
|
49 |
|
|
|
50 |
if savefile |
|
|
51 |
export_fig(gcf, [dirResults str '.jpg']); |
|
|
52 |
end %if save |
|
|
53 |
|
|
|
54 |
end %if plotta |
|
|
55 |
|
|
|
56 |
%[C, U, LUT, H] = FastFCMeans(im, params.nClusters); |
|
|
57 |
%analyze centers, discard greatest one (white background) |
|
|
58 |
% [C_sort, indC] = sort(C, 'ascend'); |
|
|
59 |
% C_select = indC(1 : params.classesToConsider); |
|
|
60 |
% %memberships to maps |
|
|
61 |
% L = LUT2label(im, LUT); |
|
|
62 |
% Umap = FM2map(im, U, H); |
|
|
63 |
|
|
|
64 |
|
|
|
65 |
%select |
|
|
66 |
maskFuzzy = false([size(L, 1) size(L,2)]); |
|
|
67 |
classThresholded = cell(numel(C_select), 1); |
|
|
68 |
for c = 1 : numel(C_select) |
|
|
69 |
class = rgb2gray(Umap(:,:,:,C_select(c))); |
|
|
70 |
|
|
|
71 |
class = imadjust(class); |
|
|
72 |
|
|
|
73 |
%for one of the classes, modify the threshold |
|
|
74 |
%if c == 2 |
|
|
75 |
threshClass = graythresh(class) + params.offsetOtsuFCM; |
|
|
76 |
%else %if c |
|
|
77 |
%threshClass = graythresh(class); |
|
|
78 |
%end %if c |
|
|
79 |
|
|
|
80 |
classThresholded{c} = class > threshClass; |
|
|
81 |
|
|
|
82 |
%threshClass = multithresh(class, params.numberMultiThresh) - params.offsetOtsuFCM; |
|
|
83 |
%classThresholded{c} = class > threshClass(2); |
|
|
84 |
|
|
|
85 |
maskFuzzy = logical(maskFuzzy + classThresholded{c}); |
|
|
86 |
end %for c |
|
|
87 |
maskFuzzy = connComp2(maskFuzzy, 1, 1); |
|
|
88 |
|
|
|
89 |
%display |
|
|
90 |
if plotta |
|
|
91 |
fh2 = figure; |
|
|
92 |
for c = 1 : numel(C_select) |
|
|
93 |
subplot(1, numel(C_select), c) |
|
|
94 |
imshow(classThresholded{c}) |
|
|
95 |
end %for c |
|
|
96 |
|
|
|
97 |
str = [filename '; class memberships, segmentation']; |
|
|
98 |
|
|
|
99 |
mtit(fh2, str, 'Interpreter', 'none', 'fontsize', 14, 'color', [1 0 0], 'xoff', .0, 'yoff', .0); |
|
|
100 |
|
|
|
101 |
if savefile |
|
|
102 |
export_fig(gcf, [dirResults str '.jpg']); |
|
|
103 |
end %if save |
|
|
104 |
|
|
|
105 |
end %if plotta |
|
|
106 |
|
|
|
107 |
|
|
|
108 |
%------------------------------------ |
|
|
109 |
%combine |
|
|
110 |
% mask = logical(maskThresh .* maskFuzzy); |
|
|
111 |
mask = logical(maskThresh + maskFuzzy); |
|
|
112 |
|
|
|
113 |
%morph |
|
|
114 |
se = strel(params.typeSeSegm, params.sizeSeSegm); |
|
|
115 |
maskFill = imfill(mask, 'holes'); |
|
|
116 |
maskClose = imclose(maskFill, se); |
|
|
117 |
maskCloseOpen = imopen(maskClose, se); |
|
|
118 |
|
|
|
119 |
|
|
|
120 |
%------------------------------------ |
|
|
121 |
%refine with active contour |
|
|
122 |
maskAC = activecontour(im, maskCloseOpen, params.numIterAC, 'Chan-Vese', 'ContractionBias', -0.3); |
|
|
123 |
%morph |
|
|
124 |
maskAC_oneCC = connComp2(maskAC, 1, 1); |
|
|
125 |
maskACFill = imfill(maskAC_oneCC, 'holes'); |
|
|
126 |
maskACClose = imclose(maskACFill, se); |
|
|
127 |
maskACClopeOpen = imopen(maskACClose, se); |
|
|
128 |
|
|
|
129 |
|
|
|
130 |
|
|
|
131 |
%------------------------------------ |
|
|
132 |
if plotta |
|
|
133 |
fh = fsfigure; |
|
|
134 |
|
|
|
135 |
subplot(2,3,1) |
|
|
136 |
imshow(im) |
|
|
137 |
title('Original') |
|
|
138 |
|
|
|
139 |
subplot(2,3,2) |
|
|
140 |
imshow(im2double(im) + edge(maskThresh), []); |
|
|
141 |
title('Mask Otsu'); |
|
|
142 |
|
|
|
143 |
subplot(2,3,3) |
|
|
144 |
imshow(im2double(im) + edge(maskFuzzy), []); |
|
|
145 |
title('Mask Fuzzy C-Means'); |
|
|
146 |
|
|
|
147 |
subplot(2,3,4) |
|
|
148 |
imshow(im2double(im) + edge(maskCloseOpen), []); |
|
|
149 |
title('Mask combined + morph'); |
|
|
150 |
|
|
|
151 |
subplot(2,3,5) |
|
|
152 |
imshow(im2double(im) + edge(maskAC), []); |
|
|
153 |
title('Mask combined + morph + AC'); |
|
|
154 |
|
|
|
155 |
subplot(2,3,6) |
|
|
156 |
imshow(im2double(im) + edge(maskACClopeOpen), []); |
|
|
157 |
title('Mask combined + morph + AC + morph'); |
|
|
158 |
|
|
|
159 |
str = [filename '; segmentation']; |
|
|
160 |
|
|
|
161 |
mtit(fh, str, 'Interpreter', 'none', 'fontsize', 14, 'color', [1 0 0], 'xoff', .0, 'yoff', .04); |
|
|
162 |
|
|
|
163 |
if savefile |
|
|
164 |
export_fig(gcf, [dirResults str '.jpg']); |
|
|
165 |
end %if save |
|
|
166 |
|
|
|
167 |
end %if plotta |
|
|
168 |
|
|
|
169 |
|
|
|
170 |
|
|
|
171 |
|