10
$\begingroup$

I'll start by saying that I don't know anything about image processing. I have an image and I need to extract its outermost shape for use in a WordCloud. The image only has two colours and the outermost shape is a boundary between the two colours. A representative image follows (but the colours are not black and white in the actual image).

enter image description here

With this image I would expect the region calculated to be the union of the disk and rounded corner rectangle. Again, this only representative and the actual image is not made of an union of basic shapes.

I believe that if I call the image processing equivalent of DiscretizeGraphics and get many points then I could take the convex hull of this set of points and use this region in a WordCloud. DiscretizeGraphics doesn't work on JPEG and EdgeDetect does not return an object compatible with DiscretizeGraphics.

May someone point me in the correct direct to do this on an image? If this is not the best approach please offer alternatives.

$\endgroup$
  • $\begingroup$ The intersection? Are you sure? It will be very difficult to calculate the intersection of two shapes that aren't completely specified (in the general case, I mean) $\endgroup$ – Dr. belisarius Nov 27 '15 at 1:03
  • $\begingroup$ @belisariushassettled Sorry, the union. Late night in the office. I'll update. $\endgroup$ – Edmund Nov 27 '15 at 1:08
4
$\begingroup$

You only want the interior black areas filled? Then you just need a FillingTransform:

img = Import["http://i.stack.imgur.com/qUfE7.jpg"];
FillingTransform[img]

enter image description here

Or, if you want a binary result for a color image: FillingTransform[Binarize[img]] (which looks the same in this case, because the source image already is black and white)

$\endgroup$
12
$\begingroup$
i  = Binarize@Import["http://i.stack.imgur.com/qUfE7.jpg"];
m  = SelectComponents[i, "EmbeddedComponents", Length[#] === 0 &];
i1 = FillingTransform[i, Dilation[m, 1]];
m1 = SelectComponents[ColorNegate@i1, "EmbeddedComponents", Length[#] === 0 &];
i2 = FillingTransform[i1, Dilation[m1, 1]];
{{i, m, i1, m1, i2}} // Grid

Mathematica graphics


Edit

The following supports more general images:

f[x_Image] := FixedPoint[Module[{m, i1, m1},
    m = SelectComponents[#, "EmbeddedComponents", Length[#] === 0 &];
    i1 = FillingTransform[#, Dilation[m, 1]];
    m1 = SelectComponents[ColorNegate@i1, "EmbeddedComponents", Length[#] === 0 &];
    FillingTransform[i1, Dilation[m1, 1]]
    ] &, Binarize@x]

i = Import["http://i.stack.imgur.com/eu7yt.png"];
{{i, f@i}} // Grid

Mathematica graphics


Edit

Here is another non-recursive way:

i = Import["http://i.stack.imgur.com/eu7yt.png"];
i1 = ImageMultiply[i, ColorNegate@
       Image[Plus @@ (ComponentMeasurements[i, {"EnclosingComponents", "Mask"}, 
                                            # != {} &][[All, 2, 2]])]];
m = SelectComponents[i1, "EmbeddedComponents", Length[#] === 0 &];
i1 = FillingTransform[i1, Dilation[m, 1]];

{{i, f@i}} // Grid

Mathematica graphics

$\endgroup$
  • $\begingroup$ There are some very informative approaches presented. (+1) However, @nikie one-liner is easier to explain to others and manage. $\endgroup$ – Edmund Nov 27 '15 at 14:01
  • $\begingroup$ @Edmund Of course. I made up that because I found corner cases where FilliTransform wasn't enough. Trying to remember what were those :) $\endgroup$ – Dr. belisarius Nov 27 '15 at 14:17

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.