Question

I want to do exactly like the above image via code (android). But I'm confused about the algorithm to do that. All i know is:

With every pixel:

  1. Convert RGB to HSL

  2. ???

  3. Convert HSL back to RGB

Can anyone explain for me what to do in Step 2? Thanks so much.

ps: I can set saturation in android via ColorMatrix.setSaturation(0) but the result image not the same as Photoshop (Because the Hue and Lightness not changed?)

Was it helpful?

Solution

You have many options to desaturate an image. Moreover please note that desaturating an image is not simply to make it B&W but for some applications you may think they're equivalent.

I updated this post with more details.

Average

This is the first thing a student can image to do to convert to gray scale (at least what I first thought in the past!) and it appears like desaturation:

level = (R + G + B) / 3

It doesn't produce a bad result, it's fast and easy to implement. But it has the big drawback that it doesn't match the way humans perceive luminosity.

Luminance

This second method (Luminance is sometimes called Luminosity, Luma or Intensity) is a better model of the way our eyes perceive brightness. It is based on the fact that cone density in eye is not uniform across colors. We perceive green much more strongly than red and red more strongly than blue.
Because we don't perceive all colors with the same intensity, the average method is inaccurate (at least it doesn't produce a result that looks natural). How to manage this? Simply use a weighted average:

level = R * 0.3 + G * 0.59 + B * 0.11

As you can imagine there are a lot of discussions about these values. Original ITU-R recommendation proposed this formula:

level = R * 0.2126 + G * 0.7152 + B * 0.0722

If I'm not wrong Photoshop uses this one for its simple desaturation function (yes, it's the unrounded version of the first one):

level = R * 0.299 + G * 0.587 + B * 0.114

I don't think we may note a lot of difference anyway reccomandation changed recently, take a look here on Wikipedia for more details about this formula.

Do you want more details? Read this article of Charles Poynton: The rehabilitation of gamma and his FAQ about this topic.

Desaturation

You have each pixel described with the RGB color model but saturation belongs to the HSL color model (in reality you can use both HSL or HSV models when working with saturation). Please read the link for more details about these models.

Desaturating an image consists following steps:

  • Convert each pixel from RGB to HSL (see this article if you need details).
  • Force the saturation to zero (this should be what setSaturation(0) does)
  • Convert it back to RGB (see this bookmark).

Let me introduce a big semplification on this process: you can desaturate a color finding the midpoint between the maximum of RGB and the minimum of RGB (lightness, do you remember that a color, in the RGB color space, is a point in the 3D space?). The (simplified) formula to get the desaturated image is:

level = (max(R, G, B) + min(R, G, B)) / 2

De-composition

A simpler form of desaturation, called sometimes local maximal decomposition simply picks the maximum value of each RGB triplet:

level = max(R, G, B);

As you can imagine you can use both local maximum or local minimum (I wrote local because it searches the minimum/maximum for each pixel).

Other methods

Do not forget that you can get a B&W image (then something that looks like a desaturated image) in a very fast way simply keeping one single channel from the RGB triplet (for example the green channel) and copying that value to all channels).

Sometimes Photoshops tutorials don't use its functions to desaturate an image (the Desaturate function and the Adjustment palette) but to achieve better results they add a layer with a uniform color (calculated with values from Luminance section) and the they merge that layer with the original image (search for a tutorial and repro that steps in your code).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top