CS194 Project 1: Images Of The Russian Empire

Billy Chau


Once upon a time, there was a Russian man who was too good at predicting the future, and he believed that color photography was going to be a big wave in the future; therefore, he asked the king for permission to travel around the empire to photograph. He used three glass plates with three different filters (R,G,B) to capture the scene. Luckily for us, the original RGB glass negatives were bought and digitalized by Library of Congress and is available online.


The goal of this project is to turn these digitalized negatives into a colorful scene so we can enjoy the beauty. In addition, we want to align the glass plates in a way to minimize artifacts produced by alignment.


First, my program crops out some portions of each edge so that the white and black edges won't have an impact on the algorithm. It turns out choosing a correct portion is significant to the success of the algorithm (explain?). Then, the program performs either basic alignment or alignments with pyramid based on the resolution of the image. In my program, if the width or height is smaller than 400, the image will be simply aligned by the align method; otherwise, pyramid alignment is used.

Simple Alignment

My alignment method first iterates two for-loops each starting from -15 to 15 for iterating all possible translations. For each translation, it is scored by the Sum of Squared Differences (SSD), and the translation with minimum error is returned.

Generated with simple alignment

Pyramid Alignment

So far so good, right? It turns out it won't work on high resolution image because the misalignment is usually out of the 30x30 window. So what we can do instead is to make the window bigger? Yes or no, if the window is large, the runtime will be so high that it takes few hours to finish.

It's time for pyramid method to show off!

As we know the only problem here is the runtime, pyramid method deals with this by downsampling the image and performing alignment in a lower resolution space. To be precise, the algorithm first builds a pyramid of images from high to low resolution, and it starts finding the best translation offset in the coarsest level. Then the translation offset will be passed down to the next level to be aligned so that it can minimize the search space by having a good starting point at that level. The whole process ends when either the width or height is smaller than 400 or the finest level is reached. Note that only the center portion of the image is used for alignment in pyramid alignment.

Oops!!! What is going on?

It turns out using the blue glass plate as the base could have a big impact on alignment.

In BGR order

One observation is that the pixel value of the b channel is high while the pixel value of the r channel is low, especially in the center of the image. The problem immediately surfaces as the algorithm uses mainly the center portions of the image for alignment. Therefore, there is a good chance that the SSD is really high even the alignment is correct.


Result shown here is aligned with green as base.

B:((40, 18), (89, 24)), G:((-41, -18), (48, 6))
B:((33, 2), (98, 5)), G:((-33, -2), (64, 2))
B:((48, 23), (-82, -70)), G:((-48, -23), (58, 18))
B:((60, 18), (124, 17)), G:((-60, -18), (64, -2))
B:((86, 0), (179, 12)), G:((-84, -10), (96, 4))
B:((50, 26), (108, 36)), G:((-50, -26), (58, 10))
B:((77, 29), (175, 37)), G:((-78, -29), (98, 8))
B:((49, 17), (108, 13)), G:((-50, -16), (58, -4))
B:((42, 6), (85, 32)), G:((-42, -6), (44, 26))
B:((53, 0), (105, -12)), G:((-54, 0), (52, -12))