True PseudoGrey in GIMP

I was in the process of including my last tutorial on curves in some forum posts around the internet when I visited gimpchat.com again. After I had posted my link I was perusing the tutorials board when I came across user lylejk's post about implementing a true pseudo-grey on images in GIMP.


Randi PseudoGrey (mouseover for desaturated 256 value version)

It was an interesting read, but the thing that started me thinking was the implementation. It was a manual implementation in his tutorial, and I figured I could slap together some script-fu to automate the process.

The basic premise behind this idea as originally presented by Rich Franzen () is to start with an 8-bit value for a pixel, then successive addition of 1 to either no channels, red, blue, green, red-blue, red-green, or blue-green would encode further grey values.

This will increase the maximum number of unique values in an image to 1786 different values, vs. the 256 different values of a straight 8-bit grayscale image.

This means that in a straight 256 value grayscale image, we could go from value 128 to 129 like so:
128
129

But with PseudoGrey, we can now encode much more information between those two values (thank you Saulgoode for correcting my encoding sequence!):
128, 128, 128
128,128,129
129,128,128
129,128,129
128,129,128
128,129,129
129,129,128
129,129,129

Now, it might be debatable on whether a person could really see a distinction even in 256 values, but the bottom line is that you can have much more data to work from and retain using PseudoGrey. (To illustrate the "debatable" idea - each of the lines above is actually that RGB color as indicated - can you tell the difference between them?)


Whitney PseudoGrey (mouseover for desaturated 256 value version)

The implementation that lylejk sorted out for GIMP is to use a black to white linear gradient as a layer in your image. I personally just created a new layer that was 2048 pixels wide, and about 10 pixels tall, then filled it with a gradient from black to white from/to the extents, taking up the entire layer.

If you do this, then have a look at the colorcube analysis:

Colors → Info → Colorcube Analysis

you'll notice that your gradient layer should report around 1786 unique colors. (For reference, I'll fill the layer with the black→white gradient with "Dithering" turned on in the Blend mode).

You now have a smooth black to white gradient with 1786 individual tones. Now you can just do a:

Colors → Map → Samples Colorize...


The Desination image will be your image that you want to convert to PseudoGrey, and your Sample will be your gradient layer. You'll want to make sure that "Hold Intensity" and "Original Intensity" are both unchecked, and that "Use subcolors" is checked.

Then just hit "Get Sample Colors", then "Apply" to remap your color image to PseudoGrey.

If you pixel peep your image now, you'll notice that it's mostly grayscale values (R,G,B all match values), but you'll also notice that there will be pixels whose R,G, or B value is just 1 off from the rest! PseudoGrey!

The thing is, this is a bunch of work. So what ruined my lunch hour was whipping up a script-fu to automate this process for me!

This script will create a new layer in your image that is 2048x10 pixels, then fill it with the appropriate black to white gradient. It will then call Samples Colorize... with the correct options for you, and will then remap your current layers colors to Pseudogrey.

You can download the Script-Fu for Pseudogrey here:
Pseudogrey on GIMP Registry
or you can get it here:
Pseudogrey on Google Drive

Update


I forgot to mention this in the post above, but after you run the PseudoGrey script, you can view all the extra tonal data you are saving by running:
Colors → Maximum RGB...
This will shift all of the subtle color different pixels to their maximum, making them very visible. All of those colored pixels now represent luminosity tones that you are saving above the 256 of a straight grayscale conversion!

Update


I've also written up the encoding in pure javascript that run entirely in the browser on your client side (no images are actually uploaded anywhere - it's converted entirely locally in your own browser). If you want to try it out, see here:
Javascript PseudoGrey Converter

This has a bug that does not produce expected results...

7 comments:

  1. I tried the script on a 256 greyscale RGB image and it didn't do anything.

    Alan

    ReplyDelete
    Replies
    1. Run the script against a full color layer to turn it into a pseudogray.

      Delete
  2. For your example of how additional information can be encoded between gray128 and gray129, the following is the list of those near-grays in order of increasing value.

    (128 128 128)
    (128 128 129)
    (129 128 128)
    (129 128 129)
    (128 129 128)
    (128 129 129)
    (129 129 128)
    (129 129 129)

    The mapping of the intermediate pseudo-grays in order of increasing brightness (as perceived by the human eye) is a significant factor in the efficacy of this technique. Your script works fine, as it relies upon the Blend Tool for calculation of these brightness values, and your description is not inaccurate, nonetheless, readers may be misled by the "random" ordering in your list of intermediate encodings.

    ReplyDelete
  3. Again I want to thank you here for doing this Script-fu too Pat. Very much appreciated. :)

    Lyle

    ReplyDelete
  4. Nice work Pat.

    Came across your PseudoGrey discussion in the flickr GIMP users group and suitably impressed. I worked on a methodology for such a process several years back but limited by my software choice it fell to the wayside. So although I use workaround methods for my own work it was such a shame that I couldn't extend the methods for others easy implementation. Now being a user of GIMP and firmly planted in the Linux world the opportunity to refine my process presents itself. Great to see someone else already working on such solutions.

    You've got some excellent work here, currently delving into your brilliant explanation of the 'wavelet decompose' retouching methods :-)


    Can see myself as an avid follower from now on and especially with the commendable actions you show by sharing your work and methods. Altruistic nature at it's best.


    Victor

    ReplyDelete
    Replies
    1. Thank you very much, I'm glad these ramblings can be useful to some people at least! :)

      I know that when I started out using GIMP (and many other FOSS programs), that it was the kindness of others sharing their experiences and knowledge that really helped me figure things out.

      I figured there might be others in a similar position, and it would be worthwhile to give back to the community in some small way.

      I really appreciate the kind comments, and as was said in the Flickr thread, it really helps my sanity to hear it's helpful in some way! :)

      Delete
  5. Bravo and thanks for starting this discussion ..... and continuing it on the Gimp group on flickr. I too find your blog helpful - and thought it was time I said so ; - )

    ReplyDelete