Project 1: Images of the Russian Empire

Nathan Blair, CS194-26

My script aligns three-color images from photographs of individual color channels. These images are taken from the Prokudin-Gorskii collection of images of the Russian Empire in the early 1900s. Simply stacking the three channels on top of eachother is not sufficient, as the images are not perfectly aligned. So, I had to automatically align the images by checking many different alignments and seeing which one was the best. To score the best alignment, I used the sum squared difference metric. That is, the best alignment of two images was the alignment with the smallest sum((image1 - image2)^2) where subtraction and squaring happens element wise.

Initially, I checked alignment at a circular shift of up to 15 pixels to left and up to 15 pixels to the right of the original image. I also checked shifts up and down. This worked well for small images like this one:

However, on larger images, a more dramatic shift was necessary, so the naive method failed. As you can see, the so-called aligned image is not aligned at all.

So, I implemented a new way to propose image shifts for alignment. First, I downsampled the images being aligned to 64x64 pixels. Then I attempt to align the images at lower resolution by checking a [-5, 5] region of pixel shifts. Once I get the shift in the 64x64 pixel domain, I move to a scale twice as large, 128x128 pixels. Once again, I attempt to align the images using a [-5, 5] pixel shift, however, I center my shifts around the shift estimate I got from the 64x64 pixel image. I keep doing this, doubling image resolution until I am at the original image size. This allows me to deal with shifts of upwards of 15% misalignment, with only 11*(log2(original_image_width) - 6) alignment checks. This is oposed to the original method, that would require me to make .15 * original_image_width checks. The new method is asymptotically faster. The results are shown below.

I was also able to:

The results of my final program are shown below