13
$\begingroup$

This graphic is produced by running DominantColors (new in Mathematica 9) with different values, using the Lena image as the source:

lenna strips

Each row is a list of the dominant colours in an image, when asking for between 2 and 60. However I'm surprised that the order of the colors keeps changing: why would the order depend on how many you asked for?

Have I done something daft in my code? Or I have failed to grasp something obvious in the online documentation? (Either is likely.)

With[{l = ExampleData[{"TestImage", "Lena"}]},
    Graphics[
     Table[{colorList = DominantColors[l, d];
       {Table[{
            colorList[[x]], 
            Rectangle[{x - 1, 10 - d},{x, 10 - (d + 0.7)}]
              },
            {x, 1, Length@colorList}]}}, 
     {d, 2, 60}]]
]
$\endgroup$

2 Answers 2

15
$\begingroup$

It's not just the order, the actual colours themselves can change depending on how many you ask for. Sometimes, these colours might not even be in your image! The reason is because DominantColors does a clustering operation and returns the mean of the n clusters in the LAB space and doesn't necessarily pick the colours that appear common to the eye (although, they coincide more often than not).

To see what I mean, consider the following example:

img = Image[{Blue, Green, Yellow, Orange, Red, Pink, Cyan} /. 
    RGBColor -> ({{##}} &) // Transpose, ImageSize -> {300, 50}]

Image[{List @@@ DominantColors[img, #]}, 
    ImageSize -> {Automatic, 50}] & /@ Range@7 // Column

Until you get to 5 dominant colours, there's always one colour in the list that's not in the original image.

So to answer your question, just as you might expect a clustering operation on some random data to give you a centroid that's not an actual point in your data, DominantColors might return colours that are not in your image (but are close). This is the reason why you see some shuffling of the orders (the centroid for 2 clusters need not necessarily be the same for 3), although you can see that in general, they are roughly in the same normalized position.

$\endgroup$
1
  • 1
    $\begingroup$ Just great, thanks for this exemplary answer. I suppose the lack of this level of information in the online docs led me to jump to the wrong conclusions about what the function was doing... $\endgroup$
    – cormullion
    Dec 20, 2012 at 22:52
4
$\begingroup$

You could always sort them manually

dc[n_] := List @@@ DominantColors[img, n]
Column[Image[{Sort[dc[#]]}, ImageSize -> 10*#] & /@ Range[3, 40]
       ,Left, 0]

enter image description here

Might want to fiddle some with what to sort by (second argument to Sort)

EDIT:

clist[sort_, name_] := Rasterize@Column[
   {name}~Join~
    (Image[{Sort[dc[#], sort]}, ImageSize -> 10*#] & /@ 
      Range[3, 40]),
   Left,
   0]
lst = clist[#1, #2] & @@ # & /@ {
    {Min[#1] < Min[#2] &, "Min"},
    {Max[#1] < Max[#2] &, "Max"},
    {Mean[#1] < Mean[#2] &, "Mean"},
    {Norm[#1] < Norm[#2] &, "Two Norm"},
    {OrderedQ[{#1, #2}] &, "Default"}
    };
ListAnimate[lst]

enter image description here

If there's a way to sort it rainbowish I believe that could be good

$\endgroup$
2
  • $\begingroup$ You can sort "rainbowish" if you ColorConvert to "HSB". $\endgroup$
    – Szabolcs
    Dec 20, 2012 at 20:37
  • $\begingroup$ @ssch Flashy! Thanks... $\endgroup$
    – cormullion
    Dec 20, 2012 at 22:53

Your Answer

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

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