Home > SuperSegger > segmentation > defineGoodSegs.m

defineGoodSegs

PURPOSE ^

defineGoodSegs sets the segments to good, bad and 3n set by the watershed algorithm

SYNOPSIS ^

function [data] = defineGoodSegs(data, ws, phaseNorm, C2phaseThresh,mask_bg, A, CONST, calcScores)

DESCRIPTION ^

 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
 within single cells. 3n_segs are the fixed segments.
 Note that we assume (safely) that the watershed always over-rather
 than under-segment the image. That is, the set of all real segments is
 contained with the set of all segments produced by the watershed algorithm.

 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
 OUTPUT :
   data : updated data segmentation frame file.

 Copyright (C) 2016 Wiggins Lab
 Written by Paul Wiggins & Stella Stylianidou.
 University of Washington, 2016
 This file is part of SuperSegger.

 SuperSegger is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 SuperSegger is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with SuperSegger.  If not, see <http://www.gnu.org/licenses/>.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [data] = defineGoodSegs(data, ws, phaseNorm, C2phaseThresh, ...
0002     mask_bg, A, CONST, calcScores)
0003 % defineGoodSegs sets the segments to good, bad and 3n set by the watershed algorithm
0004 % "Good" segments (segs_good) are the ones that lie along a real cellular
0005 % boundary, "bad" segments, lie along spurious boundaries
0006 % within single cells. 3n_segs are the fixed segments.
0007 % Note that we assume (safely) that the watershed always over-rather
0008 % than under-segment the image. That is, the set of all real segments is
0009 % contained with the set of all segments produced by the watershed algorithm.
0010 %
0011 % INPUT :
0012 %   data : data segmentation frame file
0013 %   ws : watersehd image
0014 %   phaseNorm : normalized phase image
0015 %   C2phaseThresh : c2 (curvature) calculated image
0016 %   mask_bg : background mask
0017 %   A : scoring coefficients
0018 %   CONST : segmentation parameters
0019 %   caclScores : boolean to calculate scores
0020 % OUTPUT :
0021 %   data : updated data segmentation frame file.
0022 %
0023 % Copyright (C) 2016 Wiggins Lab
0024 % Written by Paul Wiggins & Stella Stylianidou.
0025 % University of Washington, 2016
0026 % This file is part of SuperSegger.
0027 %
0028 % SuperSegger is free software: you can redistribute it and/or modify
0029 % it under the terms of the GNU General Public License as published by
0030 % the Free Software Foundation, either version 3 of the License, or
0031 % (at your option) any later version.
0032 %
0033 % SuperSegger is distributed in the hope that it will be useful,
0034 % but WITHOUT ANY WARRANTY; without even the implied warranty of
0035 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0036 % GNU General Public License for more details.
0037 %
0038 % You should have received a copy of the GNU General Public License
0039 % along with SuperSegger.  If not, see <http://www.gnu.org/licenses/>.
0040 
0041 
0042 
0043 sim = size( phaseNorm );
0044 
0045 % Create labeled image of the segments
0046 %here we obtain the cell-background boundary, which we know is correct.
0047 disk1 = strel('disk',1);
0048 outer_bound = xor(bwmorph(mask_bg,'dilate'),mask_bg);
0049 
0050 % label the connected regions in the mask with an id
0051 % and calculate the properties
0052 regs_label = bwlabel( ~ws, 8);
0053 regs_prop = regionprops( regs_label,...
0054     {'BoundingBox','MinorAxisLength','MajorAxisLength','Area'});
0055 
0056 % calculate the connectivity of each pixel in the segments
0057 ws = double(ws.*mask_bg);
0058 ws_cc = compConn( ws+outer_bound, 4 );
0059 
0060 % segs_3n are the non-negotiable segments. They are on no matter what.
0061 % this includes the outer boundary of the clumps (outer_bound), as well as the
0062 % intersections between seg lines (pixels with connectivity_4 > 2).
0063 segs_3n = double(((ws_cc > 2)+outer_bound)>0);
0064 
0065 % segs are the guys that divide cells in the clumps that may or may not be
0066 % on. Since we have removed all the intersections, we can label these and
0067 % calculate their properties.
0068 segs    = ws-segs_3n.*ws;
0069 
0070 %turn on all the segs smaller than MIN_SEGS_SIZE
0071 MIN_SEGS_SIZE = 2;
0072 cc = bwconncomp( segs, 4 );
0073 segs_props = regionprops(cc, 'Area');
0074 logmask = [segs_props.Area] < MIN_SEGS_SIZE;
0075 
0076 idx = find(logmask);
0077 segs_3n = segs_3n + ismember(labelmatrix(cc), idx);
0078 idx = find(~logmask);
0079 segs = ismember(labelmatrix(cc), idx);
0080 
0081 % redefine segs after eliminating the small segs and calculate all the
0082 % region properties we will need.
0083 % here we create coordinates to crop around each segment. This decreases the time
0084 % required to process each segment
0085 segs_label = bwlabel( segs,4);
0086 numSegs    = max( segs_label(:) );
0087 segs_props = regionprops(segs_label,  {'Area', 'BoundingBox','MinorAxisLength',...
0088     'MajorAxisLength', 'Orientation', 'Centroid' } );
0089 
0090 [~, ~, ~, ~, ~, G, C1, C2, f_xx, f_yy, f_xy] = curveFilter (double(phaseNorm),1.5);
0091 G_ = G;
0092 G_(G_>0) = 0;
0093 
0094 
0095 segs_props_tmp = regionprops(segs_label, G, 'MeanIntensity' );
0096 
0097 [segs_props(:).G] = deal (segs_props_tmp.MeanIntensity);
0098 
0099 segs_props_tmp = regionprops(segs_label, G_, 'MeanIntensity' );
0100 [segs_props(:).G_] = deal (segs_props_tmp.MeanIntensity);
0101 
0102 segs_props_tmp = regionprops(segs_label, C1, 'MeanIntensity' );
0103 [segs_props(:).C1] = deal (segs_props_tmp.MeanIntensity);
0104 
0105 segs_props_tmp = regionprops(segs_label, C2, 'MeanIntensity' );
0106 [segs_props(:).C2] = deal (segs_props_tmp.MeanIntensity);
0107 
0108 segs_props_tmp = regionprops(segs_label, f_xx, 'MeanIntensity' );
0109 [segs_props(:).f_xx] = deal (segs_props_tmp.MeanIntensity);
0110 
0111 segs_props_tmp = regionprops(segs_label, f_yy, 'MeanIntensity' );
0112 [segs_props(:).f_yy] = deal (segs_props_tmp.MeanIntensity);
0113 
0114 segs_props_tmp = regionprops(segs_label, f_xy, 'MeanIntensity' );
0115 [segs_props(:).f_xy] = deal (segs_props_tmp.MeanIntensity);
0116 
0117 
0118 % segs_good is the im created by the segments that will be on
0119 % segs_bad  is the im created by the rejected segs
0120 segs_good  = false(sim);
0121 segs_bad   = false(sim);
0122 
0123 % these define the size of the image for use in crop sub regions in the
0124 % loop--basically used to reduced the computation time.
0125 xmin = 1;
0126 ymin = 1;
0127 xmax = sim(2);
0128 ymax = sim(1);
0129 
0130 % Make the segs_info:
0131 num_info = CONST.superSeggerOpti.NUM_INFO;
0132 seg_info = nan(numSegs,num_info);
0133 
0134 % score is a binary include (1)/exclude (0) flag generated
0135 % by a vector multiplcation of A with seg_info.
0136 score    = zeros(numSegs,1);
0137 scoreRaw = zeros(numSegs,1);
0138 
0139 % Loop through all segments to decide which are good and which are
0140 % bad.
0141 for ii = 1:numSegs
0142     
0143     % Crop around each segment with two pixels of padding in x and y
0144     [xx,yy] = getBBpad( segs_props(ii).BoundingBox, sim, 2 );
0145     
0146  
0147     % here we get the cropped segment mask and corresponding phase image
0148     segs_props_tmp = [];
0149     
0150     segs_props_tmp.mask = logical(segs_label(yy, xx) == ii);
0151     segs_props_tmp.phase = phaseNorm(yy, xx);
0152     segs_props_tmp.phaseC2 = C2phaseThresh(yy,xx);
0153     segs_props_tmp.regs_label = regs_label(yy,xx);
0154     segs_props_tmp.sim = sim;
0155     
0156     seg_info(ii,:) = CONST.seg.segScoreInfo( segs_props(ii),segs_props_tmp,...
0157         regs_prop,regs_label,disk1);
0158     
0159     if calcScores    
0160         % Calculate the score to determine if the seg will be included.
0161         % if score is less than 0 set the segment off
0162         [scoreRaw(ii)] = CONST.seg.segmentScoreFun( seg_info(ii,:), A );
0163         score(ii) = double( 0 < scoreRaw (ii));
0164 
0165         % update the good and bad segs images.
0166 
0167         if score(ii)
0168             segs_good(yy,xx) = or(segs_good(yy, xx),  segs_props_tmp.mask);
0169         else
0170             segs_bad(yy,xx) = or(segs_bad(yy, xx),  segs_props_tmp.mask);
0171         end
0172     end
0173     
0174 end
0175 data.segs.phaseC2     = C2phaseThresh;
0176 data.segs.phaseNorm   = phaseNorm;
0177 data.mask_bg          = mask_bg;
0178 data.segs.segs_good   = segs_good;
0179 data.segs.segs_bad    = segs_bad;
0180 data.segs.segs_3n     = segs_3n;
0181 data.segs.info        = seg_info;
0182 data.segs.segs_label  = segs_label;
0183 data.segs.score       = score;
0184 data.segs.scoreRaw    = scoreRaw;
0185 data.segs.props       = segs_props;
0186 
0187 %intShowSegScore( data, reshape([drill(segs_props,'.Centroid(1)'),...
0188 %   drill(segs_props,'.Centroid(2)')],[numel(segs_props),2]) , 21 );
0189 
0190 end
0191 
0192 
0193 %% Debugging tool not called for visualizing scores
0194 function intShowSegScore( data, cen, ind )
0195 
0196 figure(101);
0197 clf;
0198 
0199 nseg = numel( data.segs.score);
0200 
0201 backer = 0.8*ag(data.phase);
0202 
0203 segs_good = 0.4*ag(data.segs.segs_good);
0204 segs_bad  = 0.4*ag(data.segs.segs_bad);
0205 segs_3n   = 0.4*ag(data.segs.segs_3n);
0206 
0207 imshow(cat(3,segs_good+backer+segs_3n,...
0208              0.5*segs_good+backer,...
0209              segs_bad+backer));
0210 
0211 hold on;
0212 
0213 for ii = 1:nseg
0214     
0215    text( cen(ii,1), cen(ii,2), num2str( data.segs2.info(ii,ind),'%1.2g' ),'Color', 'w');
0216 end
0217 
0218 
0219 end

Generated on Thu 19-Jan-2017 13:55:21 by m2html © 2005