RGB to Lab colorspace conversion

Issue #6 new
Joe Lencioni created an issue

I am working on an image resizing and cropping script that attempts to detect which areas of an image are more important when making cropping decisions--essentially asking the computer to determine perceptual color differences. To accomplish this, I convert pixels from the RGB colorspace into Lab colorspace and compare the differences. (http://en.wikipedia.org/wiki/Lab_color_space#Advantages_of_Lab). While I can make this happen in PHP, it is slow and uses too much memory. I would love to see functions to facilitate this conversion and comparison directly in GD.

To convert from RGB to Lab, you first need to convert from RGB to XYZ colorspace and then from XYZ to Lab colorspace. Here are the functions that I use for conversion in PHP (which have been derived from the formulas on the EasyRGB website http://www.easyrgb.com/index.php?X=MATH):

GD color index to RGB: http://code.google.com/p/smart-lencioni-image-resizer/source/browse/croppers/smart.class.php?spec=svn396646277d47c1571ff1dae31a6a5c5fed459bda&r=abd3273a317de1f9807541685f50f4e234be0561#450

RGB to XYZ: http://code.google.com/p/smart-lencioni-image-resizer/source/browse/croppers/smart.class.php?spec=svn396646277d47c1571ff1dae31a6a5c5fed459bda&r=abd3273a317de1f9807541685f50f4e234be0561#469

XYZ to CIE-Lab* (more complex): http://code.google.com/p/smart-lencioni-image-resizer/source/browse/croppers/smart.class.php?spec=svn396646277d47c1571ff1dae31a6a5c5fed459bda&r=abd3273a317de1f9807541685f50f4e234be0561#531

or

XYZ to Hunter-Lab (less complex): http://code.google.com/p/smart-lencioni-image-resizer/source/browse/croppers/smart.class.php?spec=svn396646277d47c1571ff1dae31a6a5c5fed459bda&r=abd3273a317de1f9807541685f50f4e234be0561#511

And comparing the colors (more info at http://en.wikipedia.org/wiki/Color_difference):

deltaE 2000 (complex): http://code.google.com/p/smart-lencioni-image-resizer/source/browse/croppers/smart.class.php?spec=svn396646277d47c1571ff1dae31a6a5c5fed459bda&r=abd3273a317de1f9807541685f50f4e234be0561#588

or

deltaE 76 (simple): http://code.google.com/p/smart-lencioni-image-resizer/source/browse/croppers/smart.class.php?spec=svn396646277d47c1571ff1dae31a6a5c5fed459bda&r=abd3273a317de1f9807541685f50f4e234be0561#573

or

deltaE CMC: http://code.google.com/p/smart-lencioni-image-resizer/source/browse/croppers/smart.class.php?spec=svn396646277d47c1571ff1dae31a6a5c5fed459bda&r=abd3273a317de1f9807541685f50f4e234be0561#672

For accuracy purposes, I would prefer to be able to use the more complex equations. However, if they prove to be too slow, it would be nice to fall back on the simpler versions.

So my question is this: does this kind of functionality make sense to include in GD (I hope so)? If so, will you add it? I am unfamiliar with C, otherwise I would submit the code, but hopefully it won't be too much work to convert the PHP functions I have provided here.

When you port this code, you might want to change some of the variables I set into parameters. For example, in deltaCMC(), I set $weightL and $weightC at the beginning to suit my needs. In GD, these would be better off as parameters.

Also, these are just the conversions that I needed. There are more conversions that people might find useful. For these, the EasyRGB website is a great starting point.

The links to the functions that I sent were all written by me, based off of the math on the Wikipedia articles: * http://en.wikipedia.org/wiki/Lab_color_space * http://en.wikipedia.org/wiki/Color_difference

and the EasyRGB website * http://www.easyrgb.com/index.php?X=MATH * http://www.easyrgb.com/index.php?X=DELT

And, although I have released my code under GPL, I am more than happy to give you permission to release it under a different license, such as BSD.

Thanks!

Comments (8)

  1. Pierre Joye

    Forgot to mention, yes, if we do include new code it must under the new BSD License, GPL is not an option :)

  2. Joe Lencioni reporter

    BSD is fine with me. I give you permission to use my code under the new BSD license. Is there anything else I can do to be helpful?

  3. Pierre Joye

    btw, do you use them already in a image comparison function (with visual difference + tolerance)? That's something I like to have for the tests suite but it is not yet ideal, still too many false positive :)

  4. Joe Lencioni reporter

    I do, but my algorithm takes shortcuts for speed and memory usage. http://code.google.com/p/smart-lencioni-image-resizer/source/browse/core/libs/gd/croppers/smart.class.php?spec=svncbb4135ac6ca250d4dd69c9bda63f4dc456c5aa0&r=a0ea528a6ca7ca2fe0ecd2dabff5d9689972afee#103

    The idea here is that it needs to determine how much to crop off the top and bottom OR left and right (near and far). To do this, it tries to compute the "interestingness" of each row and then compares the interestingness of the near row and the far row to determine which to keep.

    Also, I've been thinking that it might work a little better if it took the visual difference of each pixel and the four corners into account (so that the pixels that are visually close to the corner colors are less "interesting"). But it is just a hunch that I have and would make it even slower and use more memory, so I'm hesitant to work on that much.

  5. Pierre Joye

    Did you compare the results with my implementation in libgd? The gdImageCrop functions? It would be interested to see the diff from a perf and accuracy point of view as my methods are rather basics :)

    However for a real visual diff function, performence is not the actual problem but accuracy. I'm pretty sure that it should be fast enough in C :)

  6. Joe Lencioni reporter

    No, I have not looked at the gdImageCrop functions. And yes, this would all be much faster in C.

    Thanks for working on this!

  7. Log in to comment