0

enter image description hereI'd like to know if anyone knows about an algorithm that changes properties like saturation, color, brightness etc. of an Image, such that it matches a color palette, but also still looks good enough.

It would be nice if anyone could share any ideas on how to do that.

My goal is to achieve a better result by doing this, when dithering the image, because my palette only contains 20 color.

  • How would you quantify "still looks good enough"? – Scott Hunter Nov 19 '19 at 18:42
  • I mean i wouldnt want the colors of the image to be inversed or something like that. –  Nov 19 '19 at 18:43
  • I just want it to look better than just dithering it using the floyd steinberg algorithm, colorwise. –  Nov 19 '19 at 18:43
  • How would you quantify "look better"? – Scott Hunter Nov 19 '19 at 18:44
  • For example, when i dither using floyd steinberg, some areas are blown out, that shouldnt be. it would be cool if there was some "auto color grading" algorithm that i could use in java –  Nov 19 '19 at 18:45
  • @joKa dithering with 20 colors is enough if the colors are suited for dithering (containing R,G,B,BW with few shades) see [my simple dithering](https://stackoverflow.com/a/36820654/2521214) it looks good even with less than 16 colors ... but may be sharing some input images and the target palette would be a good idea ... and also your current output so we know what means better ... – Spektre Nov 19 '19 at 21:34
  • So i added an image for reference @spektre. The resulution and pixel size has to be as it is, were only talking about colors. I used a preset lut filter from some library for the second Image, which adds contrast or something. IMO in this case, using the LUT filter makes the image look much better –  Nov 20 '19 at 14:14
  • in this case the change is rather subtle, in some cases when the image is really flat, it makes a major difference –  Nov 20 '19 at 14:17
  • You are using a dithering algorithm from the 1970s. I suggest you look into the large improvements made since. [This answer](https://stackoverflow.com/a/52124238/7328782) shows results of some newer color dithering approaches. – Cris Luengo Nov 20 '19 at 14:21

1 Answers1

0

When I used my simple C++ dithering on this input image(cropped from yours):

in img

And use distinct colors as palette from this:

in pal

I got this output:

dithering

The squares in top are the palette used looks like more than 20 colors to me ... As you can see the output is much better than yours but your dithered result looks too pixelated is it downsampled and then zoomed?

Using just 2 shades of R,G,B,C,M,Y and 3 grayscales leads to 15 colors dithering:

15 colors

The more shades and combinations of RGB the better the result... Here all the combinations of 3 shades 3^3=27 colors:

27 colors

[Edit1] algorithm

  1. handle each line of image separately

    so process your image by horizontal or vertical lines. You need to have a r0,g0,b0 signed temp variable set to zero before processing any line and palette pal[] holding your allowed colors.

  2. for each pixel (of processed line)

    extract its r,g,b and add it to r0,g0,b0, then find closest color to (r0,g0,b0) in your palette pal[] and substract chosen r,g,b from r0,g0,b0.

something like this:

for (y=0;y<height;y++)
 {
 r0=0; g0=0; b0=0;
 for (x=0;x<width;x++)
  {
  // pick and add wanted color
  col=pixel(x,y);
  r0+=col.r;
  g0+=col.g;
  b0+=col.b;
  // chose closest color
  ix=0; col=(r0,g0,b0);
  for (i=0;i<palette_size;i++)
   if (color_distance(col,pal[i])<color_distance(col,pal[ix]))
    ix=i;
  col=pal[ix];
  // render and substract chosed color
  pixel(x,y)=col;
  r0-=col.r;
  g0-=col.g;
  b0-=col.b;
  }
 }

The choosing of closest color can be significantly speed up by LUT[r][g][b] table.

This approach is fast and simple but far from best visually.

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • as ive stated, it has to be zoomed in, and low res. But my pallette does only consist of 20 colors. im 100% certain about that –  Nov 20 '19 at 15:18
  • could you provide some pseudocode for your dithering, as im used to java –  Nov 20 '19 at 15:34
  • @joKa added edit... What is source and target resolution so we do not compare under different conditions (dithering looks worse in smaller resolution). The more than 20 colors is due to scaling while you zoomed some colors most likely bleeded or you used lossy compression somewhere along the way (like JPG) – Spektre Nov 20 '19 at 16:38
  • yeah i scaled it down true, i found myself using double instead of float to tackle my problem, results seems a bit better. im happy with that. Thank you for your help anyways! –  Nov 20 '19 at 20:15