P1 - Colorizing the Prokudin-Gorskii photo collection

CS194-26, Spring 2020

Overview

This project takes the individual color plates taken in Russia in the early 1900s and stitches them together into a color photo.

I started this project using the demo jupyter notebook from the Python review session. I thought I was making quick progress on the project, as from there it was easy to stack the channels to get an image, but I quickly ran into a problem with alignment. My naive approach was to inspect a 15 by 15 pixel range to see which shift matched the best with a reference image, which in my case was the green panel. I was using SSD over the raw pixel values at first, which always resulted in a crappy output image, and was stuck there for a while until I read on the spec you might have to use a cleverer metric, or different features than the raw pixels. From there I realized that what I wanted was to compare the image gradients instead, as the images themselves may have varying brightness, but the image features are expressed in the brightness differences. Alignment worked after that, and from there all I had to do was the pyramid implementation. I realized that I needed to go back and refactor my code to do this, as my naive align needed to support both varying ranges and needed to return the raw shifts so I could manipulate them in the recursive pyramid function. I ended up with code that aligns emir.tif and the other large images very well, using the parameter pyramid depth of 4 layers.

Code

All functions used and output duplication can be found in the P1.ipynb file. Use the command jupyter notebook to navigate to and open the notebook. The bottom few cells should contain all the code necessary for duplication.

Results

These results were producing by aligning the red and blue channels to the green channel:

./monastery.jpg - R offset: [-7, 1], B offset: [16, -2]

monastery

./tobolsk.jpg - R offset: [-9, 0], B offset: [10, -3]

tobolsk

./cathedral.jpg - R offset: [-6, 1], B offset: [8, -2]

cathedral

./workshop.tif - R offset: [-75, -11], B offset: [76, 4]

workshop

./emir.tif - R offset: [-71, 17], B offset: [78, -22]

emir

./three_generations.tif - R offset: [-70, -6], B offset: [71, -12]

three_generations

./melons.tif - R offset: [-33, 4], B offset: [46, -18]

melons

./onion_church.tif - R offset: [-71, 10], B offset: [75, -22]

onion_church

./train.tif - R offset: [-87, 28], B offset: [90, -1]

train

./icon.tif - R offset: [-82, 5], B offset: [90, -16]

icon

./village.tif - R offset: [-58, 10], B offset: [63, -13]

village

./self_portrait.tif - R offset: [-32, 8], B offset: [48, -30]

self_portrait

./harvesters.tif - R offset: [-64, -3], B offset: [69, -16]

harvesters

./lady.tif - R offset: [-65, 3], B offset: [71, -8]

lady

Handpicked results

./handpicked/00402v.jpg - R offset: [-6, 1], B offset: [5, -2]

00402v

./handpicked/00364v.jpg - R offset: [-8, 1], B offset: [9, -1]

00364v

./handpicked/00369v.jpg - R offset: [-6, 0], B offset: [8, 0]

00369v