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$
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.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

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$ Sep 26 '21 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$
    – Domen
    Sep 26 '21 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.stack.imgur.com/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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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