# How to get ComponentMeasurements[] from colorized image?

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:

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[]:

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.stack.imgur.com/9sw8y.png"];
unique = DeleteDuplicates@Flatten[ImageData[origImg], 1];
rules = #[[1]] -> #[[2]] & /@ Transpose[{unique, Range@Length@unique}];

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


(* Recalculating morphological components *)
p = Max@Drop[Values@ComponentMeasurements[img, "Fragmentation"], 1] + 1;
tempComponents =
ParallelSum[(# + p i Unitize[#] #) &@

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


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} *)

• 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) Sep 26, 2021 at 15:15
• 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). Sep 26, 2021 at 15:49

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

im = Import["https://i.stack.imgur.com/9sw8y.png"];

imdata = ImageData[im];

colors = DeleteDuplicates[Join @@ imdata];

lbl = DeveloperToPackedArray[
];


Verify:

Colorize[lbl] - im // MinMax

{0., 0.}

{im, Colorize[lbl]}


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}
`