Dedicated to Pistachio, and may she continue being happy, nutty , spontaneous, and amazing like the person she is today.
One of my dear friends, Pistachio, is particularly fond of travelling and exploring new sights. It helps that she is a photographer too, so even though I don’t get to travel much myself, I get to view the world through her lens.
So one day, she shared with me 100 of her photos she took when she went to Tokyo for a short trip.
I thought that her photos had quite a variety of subjects and backgrounds, and wondered if they could be source material to make something out of.
In pondering what the best way to manipulate the photos were, I wanted it to be:
- easily replicable, so that I may apply the same methods to any of her other trip photos should she so fancy.
- easily automated, so none of those advanced photograph manipulating methods or having to manually crop subjects/images out.
- meaningful, so that each trip will likely stand out against each other.
I thus decided to extract the 5 most dominant colours from every photo, before making something out of them.
To do so, however, I needed to reduce the image size, so that the extraction speed would be much faster. Given that I was looking only for the dominant colours, the image size reduction process would likely not affect the dominant colours, and was thus safe for me to proceed. This was done via Adobe Photoshop CS6, and batch processing automated the process for me. Each photo was reduced by a factor of 100, and the 11 + MB photos were reduced to ~500 kB each.
Next, the dominant colour extraction was done via ColorThief for Python – 5 colours were extracted from each picture.
from colorthief import ColorThief
sorted = 
out = open("out.txt", "w")
for counter in range(1,101):
path = 'C:\\Users\\Garett\\Desktop\\New folder\\2 ('+str(counter)+').jpg'
color_thief = ColorThief(path)
palette = color_thief.get_palette(color_count=5)
for colors in palette:
newcol = colorsys.rgb_to_hsv(colors/255, colors/255, colors/255)
newcol = tuple([int(255*x) for x in newcol])
for rows in sorted:
Some discussion on colour sorting – feel free to skip!
If you are able to read the code above, you would also notice that there was a deliberate choice to convert the colours from RGB (default output of ColourThief) to HSV. This is because Colour is mainly visualised as a 3-dimensional space, due to how it’s created – both RGB and HSV have three channels, which can be thought of as 3 independent parameters.
Note: Although the HSV colour space is commonly represented in a cylinder, a conical representation is perhaps more accurate, because if Value is 0, then Hue and Saturation does not matter – the resulting colour is black with a RGB value of (0,0,0)
The challenge then, is how to map a 3D space into a 2D space. If we were to sort by RGB, then it means that colours will be compared based on the amount of red, followed by the amount of green, then the amount of blue. Based on such a sorting, the results will end up very noisy, and two colours with very similar hues may be separated far apart.
Thus, a HSV sorting was chosen for this project. Though by no means perfect, the results produced are much more pleasing on the eyes.
Nodebox was then used to display these colours in a manner reminiscent of Pantone colour chips (you know, those paint chips they show you when you are deciding upon the colour to paint your house).
I was rather satisfied after obtaining this picture, because firstly it represents a checkpoint in my project, but also I am quite confident that this spread of colours will differ depending on the countries that Pistachio decides to visit. On a side note,after this picture was obtained, it was quite easy to tell visually that the saturation of colours in Pistachio’s photos tended to be on the less saturated side.
Now it became a question on what to do with the colours.
The first idea I had was to lay dots on a vector image of the Tokyo Tower (Tokyo by Fabien Jouin from the Noun Project), and coloured with one of the colours extracted. These dots could be randomly scattered throughout the image, and this would be meaningful, because:
- The Tokyo Tower is a symbol of Tokyo. For other places that Pistachio decides to visit, it would be a simple matter of replacing the Tokyo Tower with other landmarks.
- When randomly scattered, the overall aesthetic of the picture would be governed by the average of the colours which would more likely than not be defined by the photos of the different places.
Although there was some shape being formed, it was still rather hard to make out the image of the Tokyo Tower. The next idea was then to try to evenly spread out the dots over the vector image, rather than having them being assigned randomly.
As compared to the previous image, the font size of the text was increased to prevent overlap of the dots. I quite liked the gradient and the “dotted” feel of the resultant image, but I felt that there was too much empty space (especially within the text) that was not fully utilised.
This time, I split the vector of Tokyo Tower to 1000 dots, so the colours looped twice. This resulted in both a sharper image of the Tokyo Tower, but also a nicer gradient. The words for Tokyo were also changed to the Japanese Kanji, with a thinner stroke width, allowing the colours to blend nicely. This feels closer to what I was going for, but I decided that Nodebox itself couldn’t achieve what I wanted.
I increased the size of every dot in the previous image, then ported it over to Photoshop, where I cut out the paths formed by the base characters and Tokyo Tower vector image. This results in the coloured dots “colouring in” the paths. To ease how the image looks on the eyes (since there were many overlapping dots due to the increased size), a Blur was also used on the image, resulting in what you see above.
At this point I was rather satisfied with the results, but I thought I wanted to push things further.
What we see above is one of the ways we could have used the pictures to form an image. Although the resultant image was meaningful, unique, and the process easily replicated, it didn’t tell a story.
I went to look into the metadata (probably more commonly known as the file properties), and tried to see what information I could use.
It had the date and time taken, F-stop, exposure time, ISO speed, Exposure bias, focal length, and max aperture. Looking at these, I thought date and time, as well as F-stop were perhaps the most interesting and meaningful, and focused on these.
To start off, I decided to sort the colours chronologically, then display them as a 10 x 10 grid of shapes. Hexagons were chosen as they were the shape of normal camera shutters, and f-stop would determine the size of the hexagon.
A reason why it made more sense to use only the dominant colours rather than the top 5 colours was because using the top 5 colours would make for long chains of hexagons of similar shape, rendering the pattern less visually informative. However, as can be easily seen, this was done with a trade-off on the vibrancy and variety of colours in the result.
I then tried to split the images by date taken, before extracting the top 5 colours and sorting by HSV, then colouring in hexagons whose sizes were determined by f-stop and opacity determined by exposure time.
I could almost visualise this on one of the postcards in the story of two graphic artists telling each other about their lives using postcards.
I thought about rainbows, and remembered that I once gave someone rainbow roses. If I could use the colour-sorted data to form flowers, with the size dependent on the colour sort, number of petals dependent on f-stop number, it could form a “rainbow flower”.
This failed in a spectacular manner.
I played around with the options further. What if we limited to only one day’s worth of photos.
The left one could look like petals. The right one, however, seemed almost like a dreamcatcher? Or something a Mongolian woman might wear on her head (idk why I got this impression, do forgive me if it is wholly inaccurate).
The above options were obtained when I used all the photos, and zoomed into the centre. Kinda trippy, but not as trippy as this other image I obtained:
Which I thought was trippy just because it looked like something else:
Eventually I settled on this:
Which looked enough like a dyed carnation for me to be appeased. I call it the “Tokyo Flower”.
I then tried my hand at another illustration. Using the dots sorted by Hue, Saturation, and Brightness, we use the hour and minute values to determine the absolute value of the angle between clock hands at that time. This data was then used to determine where the next dot would be placed.
Now, we note earlier that our colour sorting was did not produce the smoothest results. What if, instead of sorting our colours as an entire gradient, we tried to split the colours into seven different main “colours” (e.g. red, orange, yellow, green, blue, indigo, violet), before sorting by saturation and brightness within these colours?
The first attempt failed, of course, because I chose to split them into seven equal buckets of hue values, without looking through my data to see how much data that involves. The next iteration saw me splitting them into seven equal buckets.
This saw the circles being spread more evenly, though when zoomed out to its correct size, the full picture has a lot of space, resulting in the picture feeling very empty. A line that connected every dot according to date and time of the photo was thus added to fill up the void.
Though the effect is nice, we can’t really tell what colours the circles were. I tried expanding them, but there were so many colours that for them to be of an appropriate size, they overlapped greatly, which defeated the purpose.
Then I chanced upon the idea of making the circles hollow!
Somehow, you can appreciate both the visual gradient of the circles, as well as the sizes which were generated by comparing the f-stop values. Since the circles were already sorted into the seven rows(?) based on their hues, we could also see a black and white version of it.
I wondered if we could explore this radial concept, and thought of concentric arcs. Though it lacks the date and time information, I thought it was rather pretty as well.
Both these pictures were coloured with colours that were partially transparent, and it was interesting to see how, when these colours stacked upon each other, the seven segments could produce the different colours almost like a rainbow.
As again, this was yet another fun project to play around with. I was inspired by the recent emerging trend of data visualisations, and thought this was something I could work on for fun.
Behind all the pretty images formed above, though, was hours of annotating and planning. You see the visualisations, but before they are formed, the data had to be gathered, sorted, and annotated. Different manners for how the data could be used were visualised; and each visualisation, to me, had to be symbolic of something. I didn’t want my visualisations to show something just because it could, otherwise it would be very noisy. You notice that I tend to use f-stop to determine the size of the shapes, this is because f-stop determines the aperture setting, or how “large the aperture is” when the photo is taken. The usage of clock hands as angles for one of the illustrations was a non-conventional idea I thought of representing time. And so on.
Counting by raw hours, this post took nearly 2 full days to be complete, so in terms of time to word-count ratio this post is one of the least productive. Yet, through this, I learnt about extracting colours, sorting them, and the background work of data visualisation.
And hopefully you enjoyed this post as much as I did making it.