Friday, March 27, 2009

Fun with RMagick - Thumbnails

In addition to programming web applications and sites, I have done a bit of digital image processing. Some years ago, I wrote some scripts to perform photo resizing and watermarking on batches of thousands of images at a time. I used Gimp-Perl. Gimp because I wasn't able to achieve the same quality with GD and because I liked being able to perform the steps in a GUI before writing the code to perform the steps.

I have recently stumbled upon some free time so I decided to play around a bit more. This time I used Ruby with RMagick. I wanted to get away from using the Gimp and I wanted to brush up on my Ruby skills. Obviously, Ruby isn't the most efficient (execution-time wise) language available but this is mostly just for fun.

I was interested in the possibility of analyzing a photograph, figuring out the most "interesting" bit, and saving that bit as a thumbnail. Searching for the most "interesting" bit was the obvious challenge.

My implementation is a bit simplistic. I divide the image into a grid of 200x200 squares (or however large I want the thumbnail to be). For each grid square, I get RGB readings of each pixel (actually, in this example, every five pixels in order to speed things up) and then figure out the standard deviation for each pixel. This is what the "histogram" tool in Gimp does. Once I had a script that replicated Gimp's histogram, I was a bit unmotivated to finish the program. Everything else was just grunt work and I wasn't too enthused about the program design. I know that there must be much smarter ways to do this task. Anyway, I finally got around to coding up the rest of it today and I am glad I did. It was fun to run it over a batch of eight images and see the results.

It is cool to run a program when you don't know what the results are going to be (besides it works/does not work). Short of manually clicking through Gimp and figuring out 100 histograms for each image, I couldn't know what this program would produce.

The images were just ones that I had laying around on my hard drive. I tried to pick some indoor and outdoor ones.

The square with the highest contrast wins out and sometimes this makes an interesting thumbnail and sometimes it doesn't.

Some other possible ideas would be to find the part of image with a lot of one primary color or a part that has a lot of a certain color, surrounded by a lot of contrast.

I haven't commented the code but it is pretty simple. The heart of it is just the standard deviation algorithm.
Code at github.