2

I need to find out what are the N dominant colors of an image. I've written a function inspired from this : http://bubble.ro/How_to_create_the_histogram_of_an_image_using_PHP.html

The picture is drawn inside of a hidden canvas that has the same surface as the picture.

Here is my code :

lwf.image.getDominantColors = function(args) {

    // args.imageData is the ImageData object got from the canvas 2d context.
    // canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height)

    if(!args.imageData) alert('lwf::image::getDominantColors() : no ImageData provided.');

    // args.sampling defines the percentage of pixels to be tested (0.01 for example).

    var sampling = undefined != args.sampling && 0 > args.sampling && args.sampling <= 1
      ? args.sampling
      : lwf.image.DFLT_PX_SAMPLING_RATIO; // Default value

    var w = args.imageData.width,
        h = args.imageData.height,
        total = w * h,
        mat = args.imageData.data;

    // Interval allows me to skip pixels on X and Y axis to make the computation faster.
    // The top-left pixel of each interval * interval square is tested.

    var interval = Math.round(Math.sqrt(1 / sampling));

    var histogram = new Array();

    var x = 0, y = 0, // Coordinates of the tested pixel.
        i = 0, j = 0; // Use to get the number of tested pixels.

    for(i = 0, x = 0; x < w; ++i, x += interval) {

        for(j = 0, y = 0; y < h; ++j, y += interval) {

            var start = (y * w + x) << 2;

            var r = mat[start    ],
                g = mat[start + 1],
                b = mat[start + 2];

            var value = Math.round((r + g + b) / 3);

            // TODO
        }
    }

    var tested = i * j;

    // TODO

    return histogram;

}; // lwf::image::getDominantColors()

I don't know how to complete this so that it returns an equivalent of a PHP array indicating, foreach color that was found, a value representing its presence.

And another question : what does the following expression represent ?

var value = Math.round((r + g + b) / 3);

It's strange because if we have r = 200, g = 100, b = 100 and r = 100, g = 100, b = 200, both will have the same value but for two different colors. There's no explaination about this in the tutorial i found.

Does anyone have an idea ? Thanks in advance :)

Virus721
  • 8,061
  • 12
  • 67
  • 123
  • `value = Math.round((r + g + b) / 3);` is a crude estimate of a color's intensity. http://stackoverflow.com/questions/687261/converting-rgb-to-grayscale-intensity provides more detail and a better equation. – broofa Dec 04 '12 at 13:10
  • Thanks for your answer. By "intensity", do you mean saturation or how bright it is ? – Virus721 Dec 04 '12 at 13:15
  • Brightness. The "V" in HSV color model. http://en.wikipedia.org/wiki/Comparison_of_color_models_in_computer_graphics#HSV – broofa Dec 04 '12 at 13:30
  • The "V" in "HSV" solves none of your problems. It represents the maximum between the bands R, G, B when converting from the color system RGB to HSV. So, you would basically get `value = max(max(r, g), b)`. Now, to find the dominant colors there are many many ways to do so. A simple way (not necessarily good or fast) is the k-means algorithm. – mmgp Dec 16 '12 at 04:11
  • https://github.com/leeoniya/RgbQuant.js NeuQuant.js – PAEz Sep 20 '13 at 07:59

0 Answers0