1
$\begingroup$

I have a 2d binary array of 0s and 1s. I select an element and would like to know how many 1s are in the contiguous cluster that includes the selected point. If the selected element is 0, the answer is 0. If the selected element is 1, then one should do a recursive search to find all nearest neighbors whose value = 1, and then their nearest neighbors with value =1, etc. Here, a nearest neighbor is by row- or column- but not both (no diagonal relations). There are 4 nearest neighbors to each interior point.

Logically, there would be binary image-processing operations that might help, especially ones on cluster analysis, but I don't see anything relevant and don't see how to do a recursive algorithm.

$\endgroup$
1
  • $\begingroup$ A small example would really help. Anyway, have you tried anything on your own? Regarding recursion, of course you can write a recursive function in MMA in the obvious way (e.g. g[x_] := 2 g[x-1], together with appropriate starting values). You may also use Nest, Fold, etc. $\endgroup$
    – MarcoB
    Jun 18, 2018 at 1:36

2 Answers 2

2
$\begingroup$

Using MorphologicalComponents with ComponentMeasurements:

ClearAll[counts]
counts[m_] := # /. ComponentMeasurements[#, "Count"] & @
  MorphologicalComponents[m, CornerNeighbors -> False]

Using Carl's example array:

SeedRandom[0]
m = RandomInteger[1, {10, 10}];
m // MatrixForm // TeXForm

$\left( \begin{array}{cccccccccc} 1 & 0 & 1 & 0 & 0 & 1 & 1 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 & 0 & 1 & 0 & 1 & 1 & 0 \\ 0 & 0 & 1 & 1 & 1 & 1 & 0 & 0 & 0 & 0 \\ 1 & 1 & 1 & 1 & 0 & 1 & 1 & 0 & 0 & 1 \\ 1 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 1 \\ 1 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 \\ 1 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 \\ 1 & 0 & 1 & 0 & 1 & 0 & 1 & 1 & 0 & 0 \\ \end{array} \right)$

counts[m][[3, 4]]

15

counts[m][[3, 2]]

0

counts @ m // MatrixForm // TeXForm

$ \left( \begin{array}{cccccccccc} 1 & 0 & 2 & 0 & 0 & 3 & 3 & 3 & 0 & 0 \\ 0 & 0 & 2 & 0 & 0 & 0 & 0 & 0 & 3 & 0 \\ 0 & 0 & 0 & 15 & 0 & 15 & 0 & 3 & 3 & 0 \\ 0 & 0 & 15 & 15 & 15 & 15 & 0 & 0 & 0 & 0 \\ 15 & 15 & 15 & 15 & 0 & 15 & 15 & 0 & 0 & 1 \\ 15 & 15 & 15 & 0 & 1 & 0 & 0 & 0 & 4 & 0 \\ 0 & 0 & 0 & 3 & 0 & 0 & 0 & 0 & 4 & 4 \\ 4 & 0 & 0 & 3 & 3 & 0 & 0 & 0 & 0 & 4 \\ 4 & 4 & 0 & 0 & 0 & 0 & 3 & 0 & 1 & 0 \\ 4 & 0 & 1 & 0 & 1 & 0 & 3 & 3 & 0 & 0 \\ \end{array} \right)$

cnts = Union[Join @@ counts[m]];

Row[{MatrixPlot[m, ImageSize -> 250,   
   ColorFunction  -> "Rainbow", ColorFunctionScaling -> False,
   PlotLegends -> SwatchLegend["Rainbow", {0, 1}] ], 
 MatrixPlot[counts @ m,  ImageSize -> 250, 
   ColorFunction -> ColorData[{"Rainbow", {0, Max[cnts]}}], 
   ColorFunctionScaling -> False, 
   PlotLegends -> SwatchLegend[ColorData["Rainbow"]/@Rescale[cnts], cnts] ]}, 
 Spacer[10]]

enter image description here

$\endgroup$
1
  • $\begingroup$ These are great suggestions. Thanks so much to you both. (I had looked at MorphologicalComponents but could not quite see how to get it all to work.) $\endgroup$ Jun 19, 2018 at 1:53
3
$\begingroup$

You could use MorphologicalComponents:

size[m_, pos_] := With[{comp = MorphologicalComponents[m, CornerNeighbors->False]},
    c = Extract[comp, pos];
    Replace[c, Except[0] :> Count[comp, c, 2]]
]

An example matrix:

SeedRandom[0]
m = RandomInteger[1, {10,10}];
MatrixPlot[m]

enter image description here

And the size of the blob containing row 5, column 1:

size[m, {5,1}]

15

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.