# Detect each polygons in an image

Considering this image:

Is there a way to colorize each tiles independently? My problem is that

img = Import["https://i.sstatic.net/KPg28.jpg"];
Colorize@img


gives

where polygons with very light colours are merged.

Note that EdgeDetect[img, 1, .05] produces:

if it can help.

Ideally, the idea would be to colour the tiles independently (Colorize colours them in terms of their "blackness"). That would imply that one detects the polygons and recreate them, which is harder than "only" colouring them in terms of their pre-existing colours.

Please note I have absolutely no knowledge in .

• In case you don't realize the fuzziness at the edges is an artifact of jpeg compression. If you have the original to work with you'll have an easier time of it. Commented Jul 17, 2014 at 18:46
• @george2079 I don't have the original work for the real case. I guess that I could try to vectorize it with InkScape though.
– Öskå
Commented Jul 17, 2014 at 19:08

As requested:

i = Import["http://i.imgur.com/Y87duSz.jpg"]
n = TotalVariationFilter[i, 0.02]
e = EdgeDetect[n, 1, 0.02]
m = MaxDetect[d, 2]
(w = WatershedComponents[ColorNegate[d], m]) // Colorize


Kind of ugly with the rough edges, but there you go.

This is too long for a comment.

The difficulty with the example image is that it is not "clean" in the sense that it contains pixel gradients. There are 256 colors present despite the fact that there are only 50 triangles. This is why you get the imperfect output from EdgeDetect, and it is going to make any image processing more difficult.

We can see this problem if we try a naïve conversion with ColorRules:

img = Import["http://i.imgur.com/Y87duSz.jpg"];
colors = DeleteDuplicates[Flatten[ImageData[img], 1]];
Colorize[img, ColorRules -> MapThread[Rule, {colors, newColors}]]


In this case, sorting the source colors (because the replacement colors are sequential) makes this less obvious:

colors2 = Sort@DeleteDuplicates[Flatten[ImageData[img], 1]];
Colorize[img, ColorRules -> MapThread[Rule, {colors2, newColors}]]


You can use ColorRules to control how shapes get colored, but that will require some manual input or some other logic based on the particular image. The rules can involve patterns.

By way of comparison, look at this "clean" image:

Flatten[Table[{x, y}, {x, 0, 5}, {y, 0, 5}], 1];
MeshPrimitives[DelaunayMesh[%], 2];
Riffle[%, ColorData["AvocadoColors"] /@ Rescale[Range@Length@%]] // Graphics;
Image[%]


EdgeDetect[%, 1, .05]


Colorize[%%]


• "Too long for a comment" you sure? :P
– Öskå
Commented Jul 17, 2014 at 15:17
• When I saw the last image I thought you came up with it based on my image, but you produced a "clean" one :P You tricked me! :D
– Öskå
Commented Jul 17, 2014 at 15:21
• @Öskå Beware, Mathematica SE can be an emotional roller coaster :P Commented Jul 17, 2014 at 15:25
• Unfortunately ColorRules is an option for Colorize since v9 apparently :)
– Öskå
Commented Jul 17, 2014 at 17:34
• Bah. I only started using MMA in v9 so I have no idea what didn't exist before then :( You could implement the same strategy with a custom ColorFunction though. Commented Jul 17, 2014 at 17:35

Update:

Here's what I came up with trying to color every triangle independently regardless of its brightness.

Create a marker for ImageForestingComponents:

dim = 5;(* number of rectangles *)
marker =
Rasterize[
Graphics[{White,
Point /@
Table[Sequence @@ {{x, y + .05}, {x, y - .05}}, {x, .5/dim,
1 - .5/(dim), 1/dim}, {y, .5/dim, 1 - .5/dim, 1/dim}]},
PlotRange -> {{0, 1}, {0, 1}}, Background -> Black],
ImageSize -> ImageDimensions[img]]


Colorize independently:

Colorize[ImageForestingComponents[img, marker, 1]]


For different arrangement of triangles you will have to generate a different marker image.

You can choose a different ColorFunction:

img = Import["http://i.imgur.com/Y87duSz.jpg"];
Colorize[img, ColorFunction -> "Rainbow"]


• That fixes the merged white tiles indeed, sadly it doesn't provide a way to colour the tiles independently.. :) And that would be uber cool.
– Öskå
Commented Jul 17, 2014 at 14:28
• @Öskå What do you mean color them independently? You can specify exact color conversions using a custom ColorFunction or ColorRules. Commented Jul 17, 2014 at 14:31
• @shrx It's interesting that "DarkRainbow" (default scheme) doesn't work. Even when I made the conversions manually it still reduced the image from 256 colors to 213. Commented Jul 17, 2014 at 14:33
• @mfvonh Right, they are indeed independently coloured here.., ideally I would love to be able to colour the middle tiles for example in black, and the rest in white. Thus it becomes a "I would need to lists of polygons" out of the image., which is harder.
– Öskå
Commented Jul 17, 2014 at 14:34
• @Öskå Are you looking for a generic solution? In these cases it is helpful if we can assume some properties about the image (so we're not relying on things like EdgeDetect, which as you see isn't always that great) Commented Jul 17, 2014 at 14:43