Message Boards Message Boards

3
|
3242 Views
|
0 Replies
|
3 Total Likes
View groups...
Share
Share this post:

Segmentation Correction Scheme is not working

I have three images image1, image2 and image3 from a time-lapse video obtained from an optical microscope. The cells move a little from their positions and new cells can enter and old cells can leave the Field of View. The binarized masks of the cell contours are posted below

The images are posted below: image1 enter image description here

image2

enter image description here

image3 is below:

enter image description here

We can segment the images using the function

 segmentImage[binarizedMask_?ImageQ, threshCellsize_: 20000] := 
 Module[{seg, areas, indexMaxarea, maxArea},
 seg = MorphologicalComponents@*ColorNegate@
 Dilation[binarizedMask, 1];
 areas = ComponentMeasurements[seg, "Area"];
 {indexMaxarea, maxArea} = 
 First@MaximalBy[areas, Last] /. Rule -> List;
 If[maxArea > threshCellsize, 
 ArrayComponents[seg, Length@areas, indexMaxarea -> 0], seg] ~
 Dilation~1];

If you closely look at the first image and the second image one can see that some cells have been incorrectly merged together when they should have been separate.

enter image description here

I wanted to construct a scheme to use image1 to correct for any incorrect merging in image2 and the corrected image (the result of correcting image2) to be used for correcting any merging in image3.

For this purpose i first compute an overlapMatrix (this matrix tells us how much area overlap exists between the different cells in two images). I am using the function proposed here by @kglr:

https://mathematica.stackexchange.com/questions/146558

Clear@overlapMatrix;
overlapMatrix[segPrev_, segCurr_] := Module[{labelPrev, maxLabelCurr},
labelPrev = Values@ComponentMeasurements[segPrev, "Label"];
maxLabelCurr = 
MaximalBy[ComponentMeasurements[segCurr, "Label"], Value] /. 
HoldPattern[_ -> x_] :> x;
Normal[SparseArray[SparseArray[#, maxLabelCurr] &@
   DeleteCases[
    Normal@*Counts@Flatten[(1 - Unitize[segPrev - #]) segCurr],
    0 -> _] & /@ labelPrev]]
];

using the segmented images and the overlap matrix i can identify where merging is taking place using identifyFusions

Clear@identifyFusions;
identifyFusions[currSeg_, prevSeg_, overlapMat_, 
overlapThresh_: 1200] :=
With[{dim = First@*Dimensions@prevSeg},
Module[{pos, candidates, isFusion},
isFusion[currInd_, prevInd_List] := 
 Module[{mask, candCentroid, trueList},
  mask = ComponentMeasurements[currSeg, "Mask"][[currInd, 2]];
  candCentroid = 
   ComponentMeasurements[prevSeg, "Centroid"][[prevInd, 2]];
  candCentroid = 
   Map[{dim - #[[1]], #[[2]]} &@*Round@*Reverse, candCentroid];
  And @@ (MemberQ[ArrayRules@mask, # -> 1] & /@ candCentroid)
  ];

pos = Position[overlapMat, x_ /; x > overlapThresh];
candidates = Cases[Normal@GroupBy[pos, Last -> First],
  HoldPattern[_ -> {Repeated[_, {2, \[Infinity]}]}]];
Pick[candidates, KeyValueMap[isFusion, <|candidates|>], True]
]
]; 

once i have identified incorrect fusions/merging of cells i can use a function breakFusion to separate the incorrectly fused cells

Clear@breakingFusion;
breakingFusion[currSeg_, prevSeg_][rule_] :=
Module[{maxLabelCurr, maxlabel, blobind, cluster, tempSeg, 
unassignedpos, t, i = 1, nf, replaceExtraneous, blobpos, indpos, masks},
maxLabelCurr = maxlabel = Max@Values@ComponentMeasurements[currSeg, "Label"];
{blobind, cluster} = rule /. Rule -> List;
blobpos = Position[currSeg, blobind];
tempSeg = Fold[ReplacePart[#, (t[i++] = (blobpos \[Intersection] 
        Position[prevSeg, #2])) -> ++maxLabelCurr] &, currSeg, cluster];
unassignedpos = Position[tempSeg, blobind];
nf = Nearest@Flatten[MapThread[Thread[#1 -> #2] &, {Array[t, i - 1], 
    Range[maxlabel + 1, maxLabelCurr]}]];
replaceExtraneous = Replace[Map[# -> nf[#, 1] &, unassignedpos],HoldPattern[
p : {_, _} -> {x_}] :> p -> x, {1}];
ReplacePart[tempSeg, replaceExtraneous]
];

Now combining everything below in stackCorrection

stackCorrection[segmentPrev_, imageCurr_] := 
Module[{overlaps, segmentCurr, fusions},
segmentCurr = segmentImage[imageCurr]; (* segmentation *)
overlaps = 
overlapMatrix[segmentPrev, segmentCurr]; (*compute overlaps*)
fusions = identifyFusions[segmentCurr, segmentPrev, overlaps]; (* 
identify fusions *)

If[fusions != {},
segmentCurr = ArrayComponents@Fold[breakingFusion[#, segmentPrev][#2] &, segmentCurr,
fusions]] (* replace the fusions by breaking the cluster *)
];

The scheme mentioned above can be called:

correction = FoldList[stackCorrection, segmentImage@image1, {image2}];

correction[[2]] (* the corrected version of `image2` using `image1` *)

enter image description here

As we can see this works fine !

The Problem

when i instead use the corrected mask (obtained from image1 and image2) for further correcting image3 in the FoldList implementation:

correction = FoldList[stackCorrection, segmentImage@image1, {image2, image3}] 

i get errors.

I should not be getting errors because two of the three cells (circled in image1) are incorrectly merged in image3.

However, the combinations below work e.g.

correction = FoldList[stackCorrection, segmentImage@image1, {image3}]
correction = FoldList[stackCorrection, segmentImage@image2, {image3}]

It is only when i give multiple images as the second argument that i encounter problem. Any help will be very much appreciated.

POSTED BY: Ali Hashmi
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract