# Detect each polygons in an image

Considering this image:

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

img = Import["http://i.imgur.com/Y87duSz.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. – george2079 Jul 17 '14 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å Jul 17 '14 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å Jul 17 '14 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å Jul 17 '14 at 15:21
• @Öskå Beware, Mathematica SE can be an emotional roller coaster :P – mfvonh Jul 17 '14 at 15:25
• Unfortunately ColorRules is an option for Colorize since v9 apparently :) – Öskå Jul 17 '14 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. – mfvonh Jul 17 '14 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"];

• @Öskå What do you mean color them independently? You can specify exact color conversions using a custom ColorFunction or ColorRules. – mfvonh Jul 17 '14 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. – mfvonh Jul 17 '14 at 14:33
• @Ö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) – mfvonh Jul 17 '14 at 14:43