I wrote previously about scraping "fashionable" sites to derive some sense of web trends. What I'd like to work on now is extracting a palette from those images in an effort to hone my sense of color.
I'm not going to rehash how I scraped those images, I'll be operating in the
same directory structure as before. I am using
imagemagick again here, the more I
discover of it the more impressed I am. The convert
command is capable of
capturing a histogram in a given colorspace1 for an image. Here I am getting
a histogram of the top 5 colors in the image:
convert ./images/56d4a5cc61223.jpeg \
-colorspace LAB -colors 5 \
-format %c histogram:info:-
106616: ( 74, 62, 50) #4A3E32 srgb(74,62,50)
39165: (101,140, 82) #658C52 srgb(101,140,82)
41859: (171,149,106) #AB956A srgb(171,149,106)
54092: (187,175,159) #BBAF9F srgb(187,175,159)
108268: (249,248,245) #F9F8F5 srgb(249,248,245)
Based on this image:
The inclusion of standard hex color-codes is convenient, so I'll parse that out.
I'm doing some ugly text hacking here to generate an HTML div
only for the
sake of convenience. I'm also sorting the first column which represents a count
of the number of pixels of that color, by sorting on it I get an ordered list of
the most prominent colors.
echo "<div class=\"palette-2a458\">";
convert ./images/56d4a5cc61223.jpeg \
-colorspace LAB -colors 5 \
-format %c histogram:info:- \
| sort -rn \
| gsed 's/.*\(#[0-9A-F]\{6\}\).*/\1/' \
| sed -e 's/^/<div class="swatch-7a4be" style="background-color:/' \
-e 's/$/\"><\/div>/';
echo "</div>";
The results aren't perfect, they fail to account for some small but visually striking colors, which I think means I would need to incorporate something like a K-means clustering to do a better job. But I'm not unhappy with the results so far. Just for fun, let's take it down to the top 4 colors and run it against a random sample of 4 images to check it out:
swatch() {
echo "<img class=\"reference-3ca8d\" src=\"$1\"></img>";
echo "<div class=\"palette-2a458\">";
convert "$1" \
-colorspace LAB \
-colors 4 \
-format %c histogram:info:- \
| sort -rn \
| gsed 's/.*\(#[0-9A-F]\{6\}\).*/\1/' \
| sed -e 's/^/<div class="swatch-7a4be" style="background-color:/' \
-e 's/$/\"><\/div>/';
echo "</div>";
}
export -f swatch
find ./images -type f | gshuf | head -n4 | xargs -I{} bash -c 'swatch "$@"' _ {}
Not bad! This is pretty much what I envisioned in the first place so I can't complain about the results. I think I'll take a stab at clustering if I get a chance, if only to see how different the results are. It should be easier now that I've got a respectable set of sample data to test against.