Showing Only the Dominant Hue In an Image

Having extracted the dominant hue from the images, we can manipulate the image such that pixels that are not (or close to) the dominant hue are instead made grayscale.

I converted to grayscale using the brightness of the image in the HSB. This worked really nicely.

From my earlier experiments I decided on a hue range of 320 (320 buckets).

I varied the tolerance (from 1 – 20) of how far away from the dominant hue we would show on the same four images, with varying results of aesthetic pleasingness. How dominant the dominant color in the image is really varies the effect. One of them, pretty much didn’t work at all until I hit a tolerance of about 55 – at which point, 1/3 of the spectrum.

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

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

	PImage img;
	static final int hueRange = 320; 
	static final int hueTolerance = 10;  // Adjust this.

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

	public void draw() {
		image(img, 0, 0, 640, 480);
	}

	private void processImage() {
		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 dominantHue = 0;
		for (int i = 1; i < hues.length; i++) {
 			if (hues[i] > hueCount) {
				hueCount = hues[i];
				dominantHue = i;
			}
		}

		// Manipulate photo, grayscale any pixel that isn't close to that hue.
		int lower = dominantHue - hueTolerance;
		int upper = dominantHue + hueTolerance;
		print("dominentHue" + dominantHue);
		for (int i = 0; i < numberOfPixels; i++) {
			int pixel = img.pixels[i];
			float hue = hue(pixel);
			if (!hueInRange(hue, lower, upper)) {
				float brightness = brightness(pixel);
				img.pixels[i] = color(brightness);
			}
		}
	}

	private static boolean hueInRange(float hue, int lower, int upper) {
	        // Should compensate for it being circular here - can go around.
                return hue < upper && hue > lower;
	}
}

Leave a Reply