Skip to content

Commit 182925d

Browse files
author
Paul Wiggins
committed
added clist gneration counters and progenitor fields. Added segment deletion and creation features to Edit Segments.
1 parent cc261ee commit 182925d

File tree

9 files changed

+490
-92
lines changed

9 files changed

+490
-92
lines changed

Internal/intFixPos.m

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function x = intFixPos( x, ss )
2+
3+
4+
if x(1) < 1
5+
x(1) = 1;
6+
elseif x(1) > ss(2)
7+
x(1) = ss(2);
8+
end
9+
10+
if x(2) < 1
11+
x(2) = 1;
12+
elseif x(2) > ss(1)
13+
x(2) = ss(1);
14+
end
15+
16+
17+
end

cell/trackOptiClist.m

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@
8989
index_dlminOld = strcmp(tmpFields,'dlmin');
9090
index_ehist = find(strcmp(tmpFields,'error_frame'));
9191

92+
93+
prog = [];
94+
prog0 = [];
9295
% loop through all the images (*err.mat files)
9396
for i = 1:num_im
9497
data_c = loaderInternal([dirname,contents(i).name]);
@@ -182,6 +185,57 @@
182185

183186
daughter1_id = drill(data_c.regs.daughterID,'(1)');
184187
daughter2_id = drill(data_c.regs.daughterID,'(2)');
188+
mother_id = data_c.regs.motherID;
189+
190+
% get lineage stuff done here
191+
192+
if i == 1
193+
prog = ID;
194+
gen0 = 0*ID;
195+
gen = 0*ID;
196+
197+
else
198+
% copy info from previous IDs
199+
prog = nan( size( ID ) );
200+
gen0 = nan( size( ID ) );
201+
gen = nan( size( ID ) );
202+
203+
prog(~birthID_flag) = prog_(ID(~birthID_flag));
204+
gen0(~birthID_flag) = gen0_(ID(~birthID_flag));
205+
gen(~birthID_flag) = gen_(ID(~birthID_flag));
206+
207+
% now take care of new cells
208+
mother_list = mother_id(birthID_flag);
209+
210+
prog_tmp = nan( size( mother_list ));
211+
gen0_tmp = nan( size( mother_list ));
212+
gen_tmp = nan( size( mother_list ));
213+
214+
prog_tmp(mother_list>0) = prog_(mother_list(mother_list>0));
215+
gen0_tmp(mother_list>0) = gen0_(mother_list(mother_list>0))+1;
216+
gen_tmp(mother_list>0) = gen_(mother_list(mother_list>0))+1;
217+
218+
ID_ml = ID(birthID_flag);
219+
prog_tmp(mother_list==0) = ID_ml(mother_list==0);
220+
gen0_tmp(mother_list==0) = nan;
221+
gen_tmp(mother_list==0) = 0;
222+
223+
prog(birthID_flag) = prog_tmp;
224+
gen0(birthID_flag) = gen0_tmp;
225+
gen(birthID_flag) = gen_tmp;
226+
end
227+
228+
IDmax = max(ID);
229+
230+
gen0_ = nan( [1,IDmax] );
231+
gen0_(ID) = gen0;
232+
233+
gen_ = nan( [1,IDmax] );
234+
gen_(ID) = gen;
235+
236+
prog_ = nan( [1,IDmax] );
237+
prog_(ID) = prog;
238+
% done lineage stuff.
185239

186240
length1 = drill(data_c.CellA,'.length(1)');
187241
length2 = drill(data_c.CellA,'.length(2)');
@@ -421,6 +475,9 @@
421475
{'Neck width'},{'neckWidth'},0,0;
422476
{'Maximum width'},{'maxWidth'},0,0;
423477
{'Cell dist to edge'},{'cell_dist'},1,0;
478+
{'Generation'},{'gen'},0,0;
479+
{'Generation0'},{'gen0'},0,0;
480+
{'Progenitor'},{'prog'},0,0;
424481
];
425482

426483

segmentation/defineGoodSegs.m

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
function [data] = defineGoodSegs(data, ws, phaseNorm, C2phaseThresh, ...
2-
mask_bg, A, CONST, calcScores)
1+
function [data] = defineGoodSegs(data, ws, CONST, calcScores)
32
% defineGoodSegs sets the segments to good, bad and 3n set by the watershed algorithm
43
% "Good" segments (segs_good) are the ones that lie along a real cellular
54
% boundary, "bad" segments, lie along spurious boundaries
@@ -11,9 +10,6 @@
1110
% INPUT :
1211
% data : data segmentation frame file
1312
% ws : watersehd image
14-
% phaseNorm : normalized phase image
15-
% C2phaseThresh : c2 (curvature) calculated image
16-
% mask_bg : background mask
1713
% A : scoring coefficients
1814
% CONST : segmentation parameters
1915
% caclScores : boolean to calculate scores
@@ -39,6 +35,13 @@
3935
% along with SuperSegger. If not, see <http://www.gnu.org/licenses/>.
4036

4137

38+
% phaseNorm : normalized phase image
39+
% C2phaseThresh : c2 (curvature) calculated image
40+
% mask_bg : background mask
41+
mask_bg = data.mask_bg;
42+
phaseNorm = data.phaseNorm;
43+
C2phaseThresh = data.C2phaseThresh;
44+
A = CONST.superSeggerOpti.A;
4245

4346
sim = size( phaseNorm );
4447

segmentation/intRemovePillars.m

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
function mask = intRemovePillars(phase, CONST)
2+
3+
4+
5+
if exist( 'CONST' ) && ~isempty( CONST ) && ...
6+
isfield( CONST.superSeggerOpti, 'remove_pillars' )
7+
radius = CONST.superSeggerOpti.remove_pillars.radius;
8+
cut = CONST.superSeggerOpti.remove_pillars.cut;
9+
Area_Cut = CONST.superSeggerOpti.remove_pillars.Area_Cut;
10+
debug = CONST.superSeggerOpti.remove_pillars.debug;
11+
12+
else
13+
radius = 2;
14+
cut = 0.05;
15+
Area_Cut = 700;
16+
debug = false;
17+
end
18+
19+
20+
[~,~,~,D] = curveFilter( double(phase), radius );
21+
22+
D = D/max(D(:));
23+
24+
25+
D(D<cut) = cut;
26+
27+
ws = logical(watershed(D));
28+
29+
lab = bwlabel(ws);
30+
31+
props = regionprops( lab, {'Area'} );
32+
33+
A = [props.Area];
34+
35+
36+
37+
mask = ismember( lab, find(A<Area_Cut) );
38+
39+
se = strel('disk',1);
40+
mask = imdilate(mask,se);
41+
42+
43+
if debug
44+
figure( 'name', ['intRemovePillars: Area cut: A = ',num2str(Area_Cut)] );
45+
clf;
46+
comp( {phase}, {lab,'label',A} );
47+
drawnow;
48+
49+
50+
51+
figure( 'name', ['intRemovePillars: Masked region' ] );
52+
clf;
53+
comp( {phase}, {mask,'r',.5} );
54+
drawnow;
55+
end
56+
57+
58+
59+
60+
61+
62+
end
63+

segmentation/superSeggerOpti.m

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@
8484

8585
% Load the constants from the package settings file
8686

87+
%% Handles inputs here
8788
MIN_BG_AREA = CONST.superSeggerOpti.MIN_BG_AREA;
8889
MAGIC_RADIUS = CONST.superSeggerOpti.MAGIC_RADIUS;
8990
MAGIC_THRESHOLD = CONST.superSeggerOpti.MAGIC_THRESHOLD;
9091
CUT_INT = CONST.superSeggerOpti.CUT_INT;
9192
SMOOTH_WIDTH = CONST.superSeggerOpti.SMOOTH_WIDTH;
9293
MAX_WIDTH = CONST.superSeggerOpti.MAX_WIDTH;
93-
A = CONST.superSeggerOpti.A;
9494
verbose = CONST.parallel.verbose;
9595

9696

@@ -134,6 +134,8 @@
134134
data.phase = phaseOrig;
135135
end
136136

137+
%% Start segementation process here
138+
137139
% Initial image smoothing to reduce the camera and read noise in the raw
138140
% phase image. Without it, the watershed algorithm will over-segment the
139141
% image.
@@ -150,6 +152,17 @@
150152
phaseNorm(phaseNorm > (mult_max*mean_phase)) = mult_max*mean_phase;
151153
phaseNorm(phaseNorm < (mult_min*mean_phase)) = mult_min*mean_phase;
152154

155+
% Filter to remove internal structure from phase image ofcells here
156+
% (and little pieces of debris from the background
157+
if isfield( CONST.superSeggerOpti, 'remove_int_struct' ) && ...
158+
CONST.superSeggerOpti.remove_int_struct.flag
159+
tmp_im = imclose( phaseNorm, strel('disk',...
160+
CONST.superSeggerOpti.remove_int_struct.radius ));
161+
W = CONST.superSeggerOpti.remove_int_struct.weight;
162+
phaseNorm = (1-W)*phaseNorm + W*tmp_im;
163+
end
164+
165+
153166
% if the size of the matrix is even, we get a half pixel shift in the
154167
% position of the mask which turns out to be a problem later.
155168

@@ -212,6 +225,14 @@
212225
adapt_flag=1;
213226
end
214227

228+
229+
% Remove CellASIC pillars here
230+
if isfield( CONST.superSeggerOpti, 'remove_pillars' ) && ...
231+
CONST.superSeggerOpti.remove_pillars.flag
232+
mask_to_remove = ~intRemovePillars(phaseOrig,CONST);
233+
mask_bg(mask_to_remove) = false;
234+
end
235+
215236
%% Split up the micro colonies into watershed regions to assemble cells
216237
% if data exists, reconstruct ws
217238
if dataFlag
@@ -287,7 +308,12 @@
287308
%% Remake the data structure
288309

289310
% Determine the "good" and "bad" segments
290-
data = defineGoodSegs(data,ws,phaseNormUnfilt,C2phaseThresh,mask_bg, A,CONST, ~dataFlag );
311+
data.mask_bg = mask_bg;
312+
data.phaseNorm = phaseNormUnfilt;
313+
data.C2phaseThresh = C2phaseThresh;
314+
315+
data = defineGoodSegs(data, ws, CONST, ~dataFlag );
316+
291317
data.mask_colonies = mask_colonies;
292318

293319
% copy the existing score into the data structure
@@ -315,7 +341,7 @@
315341

316342

317343
if disp_flag
318-
figure(1)
344+
figure( 'name', 'SuperSegger frame segmentation' )
319345
clf;
320346
showSegDataPhase(data);
321347
drawnow;

0 commit comments

Comments
 (0)