Skip to content

Commit

Permalink
added clist gneration counters and progenitor fields. Added segment d…
Browse files Browse the repository at this point in the history
…eletion and creation features to Edit Segments.
  • Loading branch information
Paul Wiggins committed Jul 24, 2018
1 parent cc261ee commit 182925d
Show file tree
Hide file tree
Showing 9 changed files with 490 additions and 92 deletions.
17 changes: 17 additions & 0 deletions Internal/intFixPos.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
function x = intFixPos( x, ss )


if x(1) < 1
x(1) = 1;
elseif x(1) > ss(2)
x(1) = ss(2);
end

if x(2) < 1
x(2) = 1;
elseif x(2) > ss(1)
x(2) = ss(1);
end


end
57 changes: 57 additions & 0 deletions cell/trackOptiClist.m
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@
index_dlminOld = strcmp(tmpFields,'dlmin');
index_ehist = find(strcmp(tmpFields,'error_frame'));


prog = [];
prog0 = [];
% loop through all the images (*err.mat files)
for i = 1:num_im
data_c = loaderInternal([dirname,contents(i).name]);
Expand Down Expand Up @@ -182,6 +185,57 @@

daughter1_id = drill(data_c.regs.daughterID,'(1)');
daughter2_id = drill(data_c.regs.daughterID,'(2)');
mother_id = data_c.regs.motherID;

% get lineage stuff done here

if i == 1
prog = ID;
gen0 = 0*ID;
gen = 0*ID;

else
% copy info from previous IDs
prog = nan( size( ID ) );
gen0 = nan( size( ID ) );
gen = nan( size( ID ) );

prog(~birthID_flag) = prog_(ID(~birthID_flag));
gen0(~birthID_flag) = gen0_(ID(~birthID_flag));
gen(~birthID_flag) = gen_(ID(~birthID_flag));

% now take care of new cells
mother_list = mother_id(birthID_flag);

prog_tmp = nan( size( mother_list ));
gen0_tmp = nan( size( mother_list ));
gen_tmp = nan( size( mother_list ));

prog_tmp(mother_list>0) = prog_(mother_list(mother_list>0));
gen0_tmp(mother_list>0) = gen0_(mother_list(mother_list>0))+1;
gen_tmp(mother_list>0) = gen_(mother_list(mother_list>0))+1;

ID_ml = ID(birthID_flag);
prog_tmp(mother_list==0) = ID_ml(mother_list==0);
gen0_tmp(mother_list==0) = nan;
gen_tmp(mother_list==0) = 0;

prog(birthID_flag) = prog_tmp;
gen0(birthID_flag) = gen0_tmp;
gen(birthID_flag) = gen_tmp;
end

IDmax = max(ID);

gen0_ = nan( [1,IDmax] );
gen0_(ID) = gen0;

gen_ = nan( [1,IDmax] );
gen_(ID) = gen;

prog_ = nan( [1,IDmax] );
prog_(ID) = prog;
% done lineage stuff.

length1 = drill(data_c.CellA,'.length(1)');
length2 = drill(data_c.CellA,'.length(2)');
Expand Down Expand Up @@ -421,6 +475,9 @@
{'Neck width'},{'neckWidth'},0,0;
{'Maximum width'},{'maxWidth'},0,0;
{'Cell dist to edge'},{'cell_dist'},1,0;
{'Generation'},{'gen'},0,0;
{'Generation0'},{'gen0'},0,0;
{'Progenitor'},{'prog'},0,0;
];


Expand Down
13 changes: 8 additions & 5 deletions segmentation/defineGoodSegs.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
function [data] = defineGoodSegs(data, ws, phaseNorm, C2phaseThresh, ...
mask_bg, A, CONST, calcScores)
function [data] = defineGoodSegs(data, ws, CONST, calcScores)
% defineGoodSegs sets the segments to good, bad and 3n set by the watershed algorithm
% "Good" segments (segs_good) are the ones that lie along a real cellular
% boundary, "bad" segments, lie along spurious boundaries
Expand All @@ -11,9 +10,6 @@
% INPUT :
% data : data segmentation frame file
% ws : watersehd image
% phaseNorm : normalized phase image
% C2phaseThresh : c2 (curvature) calculated image
% mask_bg : background mask
% A : scoring coefficients
% CONST : segmentation parameters
% caclScores : boolean to calculate scores
Expand All @@ -39,6 +35,13 @@
% along with SuperSegger. If not, see <http://www.gnu.org/licenses/>.


% phaseNorm : normalized phase image
% C2phaseThresh : c2 (curvature) calculated image
% mask_bg : background mask
mask_bg = data.mask_bg;
phaseNorm = data.phaseNorm;
C2phaseThresh = data.C2phaseThresh;
A = CONST.superSeggerOpti.A;

sim = size( phaseNorm );

Expand Down
63 changes: 63 additions & 0 deletions segmentation/intRemovePillars.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
function mask = intRemovePillars(phase, CONST)



if exist( 'CONST' ) && ~isempty( CONST ) && ...
isfield( CONST.superSeggerOpti, 'remove_pillars' )
radius = CONST.superSeggerOpti.remove_pillars.radius;
cut = CONST.superSeggerOpti.remove_pillars.cut;
Area_Cut = CONST.superSeggerOpti.remove_pillars.Area_Cut;
debug = CONST.superSeggerOpti.remove_pillars.debug;

else
radius = 2;
cut = 0.05;
Area_Cut = 700;
debug = false;
end


[~,~,~,D] = curveFilter( double(phase), radius );

D = D/max(D(:));


D(D<cut) = cut;

ws = logical(watershed(D));

lab = bwlabel(ws);

props = regionprops( lab, {'Area'} );

A = [props.Area];



mask = ismember( lab, find(A<Area_Cut) );

se = strel('disk',1);
mask = imdilate(mask,se);


if debug
figure( 'name', ['intRemovePillars: Area cut: A = ',num2str(Area_Cut)] );
clf;
comp( {phase}, {lab,'label',A} );
drawnow;



figure( 'name', ['intRemovePillars: Masked region' ] );
clf;
comp( {phase}, {mask,'r',.5} );
drawnow;
end






end

32 changes: 29 additions & 3 deletions segmentation/superSeggerOpti.m
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@

% Load the constants from the package settings file

%% Handles inputs here
MIN_BG_AREA = CONST.superSeggerOpti.MIN_BG_AREA;
MAGIC_RADIUS = CONST.superSeggerOpti.MAGIC_RADIUS;
MAGIC_THRESHOLD = CONST.superSeggerOpti.MAGIC_THRESHOLD;
CUT_INT = CONST.superSeggerOpti.CUT_INT;
SMOOTH_WIDTH = CONST.superSeggerOpti.SMOOTH_WIDTH;
MAX_WIDTH = CONST.superSeggerOpti.MAX_WIDTH;
A = CONST.superSeggerOpti.A;
verbose = CONST.parallel.verbose;


Expand Down Expand Up @@ -134,6 +134,8 @@
data.phase = phaseOrig;
end

%% Start segementation process here

% Initial image smoothing to reduce the camera and read noise in the raw
% phase image. Without it, the watershed algorithm will over-segment the
% image.
Expand All @@ -150,6 +152,17 @@
phaseNorm(phaseNorm > (mult_max*mean_phase)) = mult_max*mean_phase;
phaseNorm(phaseNorm < (mult_min*mean_phase)) = mult_min*mean_phase;

% Filter to remove internal structure from phase image ofcells here
% (and little pieces of debris from the background
if isfield( CONST.superSeggerOpti, 'remove_int_struct' ) && ...
CONST.superSeggerOpti.remove_int_struct.flag
tmp_im = imclose( phaseNorm, strel('disk',...
CONST.superSeggerOpti.remove_int_struct.radius ));
W = CONST.superSeggerOpti.remove_int_struct.weight;
phaseNorm = (1-W)*phaseNorm + W*tmp_im;
end


% if the size of the matrix is even, we get a half pixel shift in the
% position of the mask which turns out to be a problem later.

Expand Down Expand Up @@ -212,6 +225,14 @@
adapt_flag=1;
end


% Remove CellASIC pillars here
if isfield( CONST.superSeggerOpti, 'remove_pillars' ) && ...
CONST.superSeggerOpti.remove_pillars.flag
mask_to_remove = ~intRemovePillars(phaseOrig,CONST);
mask_bg(mask_to_remove) = false;
end

%% Split up the micro colonies into watershed regions to assemble cells
% if data exists, reconstruct ws
if dataFlag
Expand Down Expand Up @@ -287,7 +308,12 @@
%% Remake the data structure

% Determine the "good" and "bad" segments
data = defineGoodSegs(data,ws,phaseNormUnfilt,C2phaseThresh,mask_bg, A,CONST, ~dataFlag );
data.mask_bg = mask_bg;
data.phaseNorm = phaseNormUnfilt;
data.C2phaseThresh = C2phaseThresh;

data = defineGoodSegs(data, ws, CONST, ~dataFlag );

data.mask_colonies = mask_colonies;

% copy the existing score into the data structure
Expand Down Expand Up @@ -315,7 +341,7 @@


if disp_flag
figure(1)
figure( 'name', 'SuperSegger frame segmentation' )
clf;
showSegDataPhase(data);
drawnow;
Expand Down
Loading

4 comments on commit 182925d

@Fouga
Copy link

@Fouga Fouga commented on 182925d Aug 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Paul, Thanks for the code to Remove CellASIC pillars. Could also provide default values for CONST:
CONST.superSeggerOpti.remove_pillars.flag = 1;
CONST.superSeggerOpti.remove_pillars.radius = ?;
CONST.superSeggerOpti.remove_pillars.cut = ?;
CONST.superSeggerOpti.remove_pillars.Area_Cut = ?;
CONST.superSeggerOpti.remove_pillars.debug = ?;

Natalia

@pawiggins
Copy link
Collaborator

@pawiggins pawiggins commented on 182925d Aug 8, 2018 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pawiggins
Copy link
Collaborator

@pawiggins pawiggins commented on 182925d Aug 8, 2018 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Fouga
Copy link

@Fouga Fouga commented on 182925d Aug 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Paul,
Thanks a lot. It works for our images.

Please sign in to comment.