Extracting the Dominant Color from an Image in Processing

I’ve had an idea in mind for a while now, that requires extracting the dominant color from an image. I had no idea how to do this, and worried it would be really hard.

The first thing was extracting the pixels from the image for processing, this was super easy thanks to this handy image processing tutorial.

Some Googling took me to Stack Overflow (always a great starting point) and I discovered the concept of color “bins” – this makes sense, I’d imagine it’s quite possible that all pixels in an image are subtly different, and actually you want to group them in some way. This led me to find out about calculating distances between colors, which is a solved problem, but somewhat complicated.

Finally I ended up looking at HSB colors – hue, saturation, brightness, and this really simple tutorial. Colors are represented on a cone, and the values are as follows (from the tutorial).

Hue is the actual color. It is measured in angular degrees counter-clockwise around the cone starting and ending at red = 0 or 360 (so yellow = 60, green = 120, etc.).

Saturation is the purity of the color, measured in percent from the centre of the cone (0) to the surface (100). At 0% saturation, hue is meaningless.

Brightness is measured in percent from black (0) to white (100). At 0% brightness, both hue and saturation are meaningless.

At this point, it was clear to me that what I really wanted to do was to extract the dominant hue, and then I planned to average the brightness and the saturation. In the end, I decided to average the brightness and saturation for that hue, rather than for the entire image.

After this, it should have been easy, but I had some confusion in terms of the range of hues, and converting from HSB to RGB. This I eventually fixed by just setting the ColorMode and working purely in HSB. The ColorMode allows me to set the maximum range, and as I just round the float to an int I can make my buckets bigger or smaller according to that. It turned out that 360 ended up being pretty close to what I want, although I think 320 is slightly better! It’s interesting to see the change of the extracted “dominant” color as the buckets change in size.

 

If you liked this, you might also be interested in: Colors of the Internet (which I found as I was waiting for pictures to upload to this post – beautiful timing!)

Source Code

import processing.core.PApplet;
import processing.core.PImage;

@SuppressWarnings("serial")
public class ImageViewApplet extends PApplet {

	PImage img;
	float hue;
	static final int hueRange = 360; 
	float saturation;
	float brightness;

	public void setup() {
		size(640,600);
		background(0);
		img = loadImage("" /* Your image here */);
		colorMode(HSB, (hueRange - 1));
		extractColorFromImage();
	}

	public void draw() {
		image(img, 0, 0, 640, 480);
		fill(hue, saturation, brightness);
		rect(0, 480, 640, 120);
	}

	private void extractColorFromImage() {
		img.loadPixels();
		int numberOfPixels = img.pixels.length;
		int[] hues = new int[hueRange];
		float[] saturations = new float[hueRange];
		float[] brightnesses = new float[hueRange];

		for (int i = 0; i < numberOfPixels; i++) {
			int pixel = img.pixels[i];
			int hue = Math.round(hue(pixel));
			float saturation = saturation(pixel);
			float brightness = brightness(pixel);
			hues[hue]++;
			saturations[hue] += saturation;
			brightnesses[hue] += brightness;
		}

		// Find the most common hue.
		int hueCount = hues[0];
		int hue = 0;
		for (int i = 1; i < hues.length; i++) {
 			if (hues[i] > hueCount) {
				hueCount = hues[i];
				hue = i;
			}
		}

		// Set the vars for displaying the color.
		this.hue = hue;
		saturation = saturations[hue] / hueCount;
		brightness = brightnesses[hue] / hueCount;
	}
}

2 thoughts on “Extracting the Dominant Color from an Image in Processing

  1. Wow this is so good..
    Actually i still confuse with the “@SuppressWarnings(“serial”)” and
    “public class ImageViewApplet extends PApplet {}”
    I can’t run the program with it. So I decide to remove it.

    I wanna ask for something, can I use this code for my project?
    I will be very, very, grateful if you allow me… Surely I will insert this honorable source in my references..
    Maybe I will also modified the program a little…
    may I do that all?

    Thank you very much! ^_^

    [WORDPRESS HASHCASH] The poster sent us ‘0 which is not a hashcash value.

Leave a Reply