colormap sorted by color occurence (or kind of)

hello there.
i’m using colormap to extract color palette.so far so good.
my problem is sorting the colors.
the sorting options always sort by luminance (ascending and descending) , i would like the colors to be sorted by “importance”.
ie if i have a big blue sky and a little red thing in front , to have the blue first then the red.
I hope it makes sense.
how would you approach this?
thanks in advance
luc

That’s interesting !
I propose this, but this may not be the optimal way of doing it.

# Sort colors by occurences.
sort_colors_occ :
  e[^-1] "Sort colors of image$? by decreasing occurences."
  v - repeat $! l[$>]
    to_rgb
    256,256,256
    eval.. ">++i(#-1,R,G,B)"   # Count color occurences in the RGB cube
    rm..
    1,1,1,4
    eval.. ${-math_lib}"i?dar_insert(#-1,[x,y,z,i]);end(resize(#-1,1,dar_size(#-1),1,4,0))"
    rm.. s c,-3 rv a x sort -,y z 1,1 transpose
  endl done v +

Then :

$ gmic sp apples sort_colors_occ

displays this:

which looks reasonnable for this particular image.

Note that the command above assumes your image is in RGB8.

Could that be a official command? I remember that someone at PDN forum wants something like this (that person wanted to find mode of colors), and this leads to something like this. Maybe it can be modified to have 3 choices (All colors, most frequent colors, least frequent colors).

The main problem I see right now is that this command works only for RGB8 images.
It could be nice to have something more generic, working with any kind of float-valued images instead.

I think it’s possible to make one that’s independent of negative numbers, and whether they’re float or integer. It does involve adding another channel, and using that final channel to sort values.

Picture the process going like this.

  1. Search pixels by pixels. For first pixel, that very first color becomes a new pixel at a new layer.
  2. If the search does not find a color found in a new layer, then add it. Else, insert +=1 into the last channel of the found color at the location of the found color.
  3. pixelsort the new layer by last channel.

That should work for float images, and negative value images. It’ll be slow though.

This is what I came up with:

sort_by_occurance:
width={w}
remove_opacity
split c
unroll x
append c

# need some kind of sorting first, maybe this is not the best scheme

+luminance 

reverse
append y
sort +,x
rows 1

+area 1,0

reverse
append y
sort +,x
rows 1

# for easy viewing
split x,-$width
append y

Here is the result for the apples image David used

apples

It doesn’t look quite right, but it not all wrong :slight_smile:

I think this is better:

sort_by_occurance:
width={w}
remove_opacity

# give each 8 bit colour a unique number

+l[0] 
	bsr 0
	split c
	bsl[1] 8			
	bsl[2] 16		
	add
endl

reverse

split c
unroll x
append y

# sort by unique colour numbers

sort +,x

split y

# find area of for each colour number

area[0] 0,0


append y

# sort by area

sort -,x

split y

+append[1,2,3] c

# assign colour numbers again

l[-1]
	bsr 0
	split c
	bsl[1] 8			
	bsl[2] 16		
	add
endl

reverse[0,-1]
rm[-1]

append y

# remove duplicate colour numbers

discard x

split y

rm[0]
append c


# for easy viewing
split x,-$width
append y

This, does the trick for any kind of colors.
Beware, if your image has a huge number of different colors, it can take a looooong time :slight_smile:

sort_colors_occ :
  e[^-1] "Sort colors of image$? by decreasing occurences."
  v - repeat $! l[$>]
    r {whd},1,1,100%,-1
    repeat s ap "sort +,x" s x,0 ap "shift 0,0,0,1,2" done
    sort_list -,w
    ap "r 1,1,1,100%,0"
    a x
  endl done v +

wow.thanks for all this.David where can i see the initial image you used ?
hope it could make it into colormap directly!
luc

The initial image is the one from the sample (aka sp) command :

$ gmic sp apples

apples

Yes, I think I’ll change the sort_vectors argument directly in the colormap command, to allows sorting vectors by occurence rather than by luminance.

OK, so it is now available in command colormap (after an update, with G’MIC 2.8.0_pre) :

$ gmic up
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Update commands from the latest definition file on the G'MIC server.
[gmic]-0./ End G'MIC interpreter.

$ gmic h colormap

  gmic: GREYC's Magic for Image Computing. 
        (https://gmic.eu) 
 
        Version 2.8.0 (pre-release #191118) 
        Copyright (c) 2008-2019, David Tschumperle / GREYC Lab / CNRS. 
        (https://www.greyc.fr)

    colormap:
        nb_levels>=0,_method={ 0=median-cut | 1=k-means },_sort_vectors

      Estimate best-fitting colormap with 'nb_colors' entries, to index selected images.
      Set 'nb_levels==0' to extract all existing colors of an image.
      'sort_vectors' can be '{ 0=unsorted | 1=by increasing norm | 2=by decreasing occurence }'
      
      Default value: 'method=1' and 'sort_vectors=1'.
      
      Example: [#1]  image.jpg +colormap[0] 4 +\
                 colormap[0] 8 +colormap[0] 16

      Tutorial: https://gmic.eu/tutorial/_colormap.shtml

thanks David.so kind of you.cheers

1 Like

do i have to compile from source to get this ?
i’m using 2.7.4 from the ubuntu ppa

There should be a .deb package for ubuntu here, for the pre-release : Index of /files/prerelease

ok.up and running.thanks