4
$\begingroup$

I'm using a software to segment images. Long story short, the output given is an array of integers (range 0-255), which I show here colorized:

enter image description here

I'm supposing that the software avoids representing two adjacent regions with the same integer, but the integers may repeat in another non-adjacent region. Anyways, the question is, from this image, how can I get ComponentMeasurements[]? I've found this tricky because a binarization gets rid of the boundaries represented in this colorized form.

Thanks!

Edit: I don't know if this makes a difference, but I colorized the same image with a gradient, because I don't know what is the default choice of colors for Colorize[]: enter image description here

$\endgroup$

2 Answers 2

7
$\begingroup$

We can recalculate MorphologicalComponents on each of the component and introduce new indexing: the $j$-th subcomponent of the $i$-th component temporarily becomes the $(i\cdot p+j)$-th component (where $p$ is the maximal number of subcomponents in one component), and the background component remains the zeroth component. Finally, we reindex the components.

(* Reconstructing your segmentized image *)
origImg = Import["https://i.sstatic.net/9sw8y.png"];
unique = DeleteDuplicates@Flatten[ImageData[origImg], 1];
rules = #[[1]] -> #[[2]] & /@ Transpose[{unique, Range@Length@unique}];

img = ImageData[origImg] /. Dispatch@rules;
img // Colorize

Mathematica graphics

(* Recalculating morphological components *)
masks = ComponentMeasurements[img, "Mask"];
p = Max@Drop[Values@ComponentMeasurements[img, "Fragmentation"], 1] + 1;
tempComponents = 
  ParallelSum[(# + p i Unitize[#] #) &@
    MorphologicalComponents[i /. masks], {i, 2, Length@masks}];

tempComponents // MinMax
(* {0, 2262} *)

(* Reindexing components *)
uniqueNew = DeleteDuplicates@Flatten[tempComponents, 1];
rulesNew = #[[1]] -> #[[2]] & /@ 
   Transpose[{uniqueNew, Range@Length@uniqueNew}];
newComponents = tempComponents /. Dispatch@rulesNew;

newComponents // MinMax
(* {1, 562} *)

newComponents // Colorize

Mathematica graphics

We can now easily get all the measures by ComponentMeasurements[]:

ComponentMeasurements[newComponents, "Area"]

(* {1->493734., 2->348.5, 3->693.125, 4->661.75, 
<<554>>, 559->449.5, 560->421.375, 561->341.125, 562->332.875} *)
$\endgroup$
2
  • $\begingroup$ This is great, thanks! Could you comment on why is this used: ParallelSum[(# + 1000 i Unitize[#] #). I imagine the 1000 is a guess of up to how many unique regions would be? Is this necessary? Say, I have a much bigger image, would this part change, or all should still work? (Don't have a bigger image to test right now, but might in the future) $\endgroup$ Commented Sep 26, 2021 at 15:15
  • 1
    $\begingroup$ Yes, it is just a number that is greater than the maximal number of subcomponents. It can actually be much smaller than 1000. I made some edits to include this (and added Dispatch for better performance). $\endgroup$ Commented Sep 26, 2021 at 15:49
4
$\begingroup$

We can reconstruct the label matrix by replacing each unique color with a unique integer label:

im = Import["https://i.sstatic.net/9sw8y.png"];

imdata = ImageData[im];

colors = DeleteDuplicates[Join @@ imdata];

lbl = Developer`ToPackedArray[
  imdata /. Dispatch[Thread[colors -> Range[Length[colors]]]]
];

Verify:

Colorize[lbl] - im // MinMax
{0., 0.}
{im, Colorize[lbl]}

enter image description here

ComponentMeasurements[lbl, "Area"]
{1 -> 493734., 2 -> 1041.63, 3 -> 1976.13, 4 -> 2650.5, 5 -> 1768.88, <<246>>, 
  252 -> 1669.38, 253 -> 1627.5, 254 -> 1431.5, 255 -> 754.25, 256 -> 341.125}
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.