Categories
Programming Visualization

Visualising A Photo Series

Whenever I’m scrolling through pictures I’ve taken, it seem like they are in sections – here’s when I was near the beach, he’s the park, the night sky and fireworks. I thought if you visualised the way that the dominant colors changed, patterns would emerge.

I found the perfect layout for this, the sunflower layout, and then did nothing about it for… a long time. I claim the craziness of work and life. Also, I knew nothing about color, and had no idea how I would go about extracting the dominant color from an image.

But I did some research and figured it out, the trick was working with hues rather than RGB values.

And voila, here is another way to see the story of my trip to North Korea.

Sunflower Visualization from Photos Taken in North Korea
Sunflower Visualization from Photos Taken in North Korea

Maybe the main thing I can see from this experiment is that I don’t take as colorful photos as I like to imagine I do. Also, that I took a lot of photos in North Korea (the major bottleneck to my blog posts about it).

So I put together another collection of images – almost everything I’ve taken since mid-June aside from in North Korea, including the shipwreck, my trips to Tasmania, Queenstown (skiing!), Hong Kong, Tokyo and photos I’d taken around Sydney and visualised that with the result below.

Sunflower visualization from photos taken between mid-June and late-August (aside from NK)
Sunflower visualization from photos taken between mid-June and late-August (aside from NK)

This is where I discovered that it doesn’t work well with panoramas (I had recently discovered the panorama feature on my iPhone and had taken a few, typically at 5-7MB in size) which threw an exception, because it was out of Java heap space. I’d need to make the code more efficient to process panoramas – for now, I just left them out.

I’d like to add more to it, maybe clicking on an element in the layout could bring up the photo, with only the dominant color (with some tolerance) exposed. Maybe animate it with the image that’s being processed displayed alongside. I’d love to pull in my most recent pictures on Twitter and display them this way. I think, how many images are needed to create something cool looking may make that prohibitive, though. For now, I’m happy that I’ve got something working.

Processing one image like this doesn’t take a noticeable amount of time, however this first (NK) one is made from 1048 images, and 2.26GB of data. On my 13″ Macbook pro… it takes a while.

Note – I made an HSBColor class that just holds hue, saturation, and brightness.

 

Source Code

 

import java.io.File;

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

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

	private static String filePath = "../data/nkimages/";
	private String[] fileNames;

	static final int hueRange = 320;
	private static final int radius = 9;
	private static final int scale = 7;

	private static final double goldenangle = Math.PI * (3 - Math.sqrt(5));

	private static final int wh = 500;

	public void setup() {
		size(wh, wh);
		background(0);
		noLoop();
		colorMode(HSB, hueRange - 1);
		// Read in images.
		File dir = new File(filePath);
		fileNames = dir.list();
	}

	public void draw() {
		int n = 0;
		double a = 0;

		for (String file : fileNames) {
			PImage img = loadImage(filePath + file);
			if (img == null) {
				continue;
			}
			print("processing image: " + file + "\n");

			double h = Math.sqrt(n)*scale;
			double x = wh/2 + Math.sin(a) * h;
			double y = wh/2 + Math.cos(a) * h;

			stroke(100);
			HSBColor color = extractColorFromImage(img);
			fill(color.h, color.s, color.b);
			ellipse((float) x, (float) y, radius, radius);

			a+=goldenangle;
			n++;
		}
	}

		private HSBColor extractColorFromImage(PImage img) {
			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;
				}
			}

			// Return the color to display.
			float s = saturations[hue] / hueCount;
			float b = brightnesses[hue] / hueCount;
			return new HSBColor(hue, s, b);
		}
}

One reply on “Visualising A Photo Series”

hmm, maybe you could line up all the colours in your image into an array — convert to CieLAB — make a 2d array by (a,b) — and then from there try to get at the “principal components” of the colours in your images.

second variation — convert to HSV space — find the principal hues (eg by clustering) in your frame — and increase the saturation if it’s too boring

Comments are closed.