GreycLab / gmic

GREYC's Magic for Image Computing: A Full-Featured Open-Source Framework for Image Processing
Other
66 stars 11 forks source link

Wrong generated colormap #36

Closed BitBlit88 closed 6 months ago

BitBlit88 commented 6 months ago

I observed a strang behaviour using the colormap command on an image with few colors.

To reproduce the issue I used a source image in 24 bit color format that uses exactly 16 colors. rgb24_16_colors Then I executed following comands with gmic version 3.3.3:

1) gmic input rgb24_16_colors.png colormap[0] 0,1,1 output palette_colormap_0-1-1.png 
2) gmic input rgb24_16_colors.png colormap[0] 0,1,2 output palette_colormap_0-1-2.png 
3) gmic input rgb24_16_colors.png colormap[0] 16,1,1 output palette_colormap_16-1-1.png 
4) gmic input rgb24_16_colors.png colormap[0] 16,1,2 output palette_colormap_16-1-2.png 

Command 1 and 2 uses "nb_levels=0". This extracts all colors from the source image. These commands produce a correct result: A palette with exactly 16 colors. The results only differ by the sorting method.

Result command 1: palette_colormap_0-1-1 Result command 2: palette_colormap_0-1-2

Command 3 and 4 uses "nb_levels=16". The generated colormaps contains colors that aren't available in the source image and there are some double entries.

Result command 3: palette_colormap_16-1-1 Result command 4: palette_colormap_16-1-2

I expected that command 1+3 and 2+4 would produce the same result.

I get another strange result if I use "nb_levels=256":

gmic input rgb24_16_colors.png colormap[0] 256,1,2 output palette_colormap_256-1-2.png

In this case a colormap with 256 entries is generated with a lot of double entries although I would expect that the result should only have 16 colors.

palette_colormap_256-1-2

Is this a bug or did I not properly understand how the colormap command works?

I also recognized that the colormap command with gmic version 3.1.6 produces different results for command 3 and 4.

BitBlit88 commented 6 months ago

I had a look at the colormap implementation in the gmic standard lib. If nb_levels is > 0, the colormap is created by using the median cut or k-means algorithm as described in the manual. If nb_levels is 0, the median cut or k-means algorithm is skipped and all colors are extracted.

So in the case where the total color count of an image is equal or less the nb_levels value, the colormap command uses the median cut and k-means algorithm and generates a non-optimal colormap.

Would it be better that in this case all colors should be extracted?

dtschump commented 6 months ago

Hello. Thanks for reporting. Yes you are right. Something must be made to improve this. But extracting all colors from an image takes a bit of time, particularly if the number of colors of an image is high, so it's a bit annoying to do this every time just to check that the number of colors is indeed less or equal than the specified argument to colormap.

I'll think about it. I think I can try to count the colors until it reaches the desired number of colors, and in that case I can stop counting.

dtschump commented 6 months ago

With : https://github.com/GreycLab/gmic/commit/c32b3eba1449bbb7efef7dd66e7dcbcfd3b10c08 I've added a check in command colormap to make sure the number of requested colors is lower than the number of actually used colors in the image. I hope this helps.

BitBlit88 commented 6 months ago

This is great, thank you. I tested your change and I can confirm that it works when using "sort by increasing norm". But if I use "sort by decreasing occurrence", the palette isn't sorted correctly.

dtschump commented 6 months ago

Ah yes, you are right. Commit https://github.com/GreycLab/gmic/commit/ba2bb2515afec0bb95ee4632ed2cdd774a07ff85 should fix this issue ($ gmic update to get the fix). Thanks!

BitBlit88 commented 6 months ago

Unfortunatly the commit doesn't fix the issue. "sort by decreasing occurrence" still isn't sorted correctly.

In case where this condition is true: if ${count_colors.}<=$1 +colormap2 0

The sorting algorithm is triggered twice: one time with sort option "1" and one time with sort option "2". I can't find the problem because although sorting twice the result should be correct.

I also noticed that you added the option that "count_colors" can count the colors until it reaches the desired number of colors, but this performance optimization isn't used.

Would it make sense to change the line to something like this: if ${count_colors. $1+1}<=$1 +colormap2 0

dtschump commented 6 months ago

You are right, sorry about this. I think https://github.com/GreycLab/gmic/commit/efdfd74f03a37b676ec88ba5de10a7257dcf1105 fixes it. I've tested with :

foo :
  400,400
  16,1,1,1,x rand.. 0,15,. rm.
  colormap 16,0,2

and it is actually working as expected. Can you confirm ? (update has been pushed on the G'MIC website).

BitBlit88 commented 6 months ago

It works perfectly now. Many thanks for your great support.