Considering this image:

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

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


Mathematica graphics

where polygons with very light colours are merged.

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

Mathematica graphics

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 .

  • $\begingroup$ 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. $\endgroup$
    – george2079
    Commented Jul 17, 2014 at 18:46
  • $\begingroup$ @george2079 I don't have the original work for the real case. I guess that I could try to vectorize it with InkScape though. $\endgroup$
    – Öskå
    Commented Jul 17, 2014 at 19:08

3 Answers 3


As requested:

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

enter image description here

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]];
newColors = ColorData["AvocadoColors"] /@ Rescale[Range[Length@colors]];
Colorize[img, ColorRules -> MapThread[Rule, {colors, newColors}]]

enter image description here

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

enter image description here

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;

enter image description here

EdgeDetect[%, 1, .05]

enter image description here


enter image description here

  • $\begingroup$ "Too long for a comment" you sure? :P $\endgroup$
    – Öskå
    Commented Jul 17, 2014 at 15:17
  • $\begingroup$ 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 $\endgroup$
    – Öskå
    Commented Jul 17, 2014 at 15:21
  • $\begingroup$ @Öskå Beware, Mathematica SE can be an emotional roller coaster :P $\endgroup$
    – mfvonh
    Commented Jul 17, 2014 at 15:25
  • $\begingroup$ Unfortunately ColorRules is an option for Colorize since v9 apparently :) $\endgroup$
    – Öskå
    Commented Jul 17, 2014 at 17:34
  • $\begingroup$ 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. $\endgroup$
    – mfvonh
    Commented Jul 17, 2014 at 17:35


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 = 
    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]]

Mathematica graphics

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

Original answer:

You can choose a different ColorFunction:

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

Mathematica graphics

  • $\begingroup$ 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. $\endgroup$
    – Öskå
    Commented Jul 17, 2014 at 14:28
  • $\begingroup$ @Öskå What do you mean color them independently? You can specify exact color conversions using a custom ColorFunction or ColorRules. $\endgroup$
    – mfvonh
    Commented Jul 17, 2014 at 14:31
  • $\begingroup$ @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. $\endgroup$
    – mfvonh
    Commented Jul 17, 2014 at 14:33
  • $\begingroup$ @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. $\endgroup$
    – Öskå
    Commented Jul 17, 2014 at 14:34
  • $\begingroup$ @Ö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) $\endgroup$
    – mfvonh
    Commented Jul 17, 2014 at 14:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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