Lets say I have this binary picture (an array with 1's and 0's):
start = {{0, 1, 1, 1}, {1, 1, 0, 0}, {1, 1, 0, 1}, {1, 1, 0, 0}};
i = ArrayPlot[CellularAutomaton[<|"OuterTotalisticCode"->224,"Dimension"->2,"Neighborhood"->9|>,{start,0},{{{200}}}],Frame->False,ColorRules->{1->White,0->Black}]
Then I can extract the subimages e.g. by using:
subimages = ComponentMeasurements[i, "Image", All, "PropertyAssociation"]["Image"]
This gives me 13 subimages which have one black pixel in between. (Note, that the blank entries above are white pixels and thus the result is correct.)
But now I would like to count subimages with two black pixels in between as one subimage. More precisely I would like to obtain only a result with 9 subimages as grouped as this:
Is there any obvious way to do it in Mathematica?
Edit:
The answers by @MarcoB and @kglr work for the specified example. Especially if one uses additionally an Erosion
on the mask to trim down the boundaries.
But the solution is not generally applicable, another example:
start = {{0, 1, 1, 1}, {1, 1, 0, 0}, {1, 1, 0, 1}, {1, 1, 0, 0}, {1, 1, 1, 1}};
i = ArrayPlot[CellularAutomaton[<|"OuterTotalisticCode" -> 224, "Dimension" -> 2,"Neighborhood" -> 9|>, {start, 0}, {{{400}}}], Frame -> False,ColorRules -> {1 -> White, 0 -> Black}];
The resulting image should be, as before, divided into subimages with 2 black cells in between, as this (the critical location where the suggested solutions fail is indicated with the arrow):
This was the proposed solution (with an added Erosion
):
dilated = Dilation[i, DiskMatrix[1]];
mask = Erosion[MorphologicalComponents@dilated, 1];
subimages = ComponentMeasurements[{i, mask}, "Image"]
Image 4 was captured incorrectly. To me it seems that ComponentMeasurements
applies a bounding box which is not desired. Any modification of the proposed solution that fixes this issue is appreciated!
start
in your code? $\endgroup$