CS194-26 Project 1: Colorizing the Prokudin-Gorskii Photo Collection (Ujjaini Mukhopadhyay)

Overview:

In this project, we attempted to recolor images taken by Sergei Mikhailovich Prokudin-Gorskii, who took photos of the Russian Empire with three different filters. He used a red, green, and blue filter which means now we can combine those images (and align them properly) in order to actually see them.

Approach:

Included in the starter code was a method to split the singular tall image containing the three photographs into three separate images. We did this by simply dividing the height by three splitting that way. Then, we need a method to align (I'll detail two below) and combining the channels will allow us to see the final image in color.

Exhaustive Search (Naive):

The first method is exhaustive search because it finds the best shift for a "top" image when aligning it to the bottom by considering every possible shift from -15 to 15 in both the x and y direction. We use np.roll because we know that whatever values are rolled over to the other side of the image will create a border. To calculate which is the best shift, we are minimizing the np.linalg.norm (or normalized ssd). This worked a little better than np.sum(np.sum((img1 - img2)**2). Due to the aformentioned border, however, I found that it was better to "crop" off a 5px border. Here are some examples below:

G: (5, -1)
R: (8, -1)
G: (-3, 1)
R: (3, 2)
G: (3, 2)
R: (6, 3)

Pyramid Stack

Of course, the naive approach works well on small images BUT with larger resolution images, this is extremeley time consuming. Thus, we implemented a pyramid stack. I tried to recursively scale down my image by 4 until it was 400x400, find an alignement within +- 5 pixels that worked for the smaller image and started scaling these vectors so that they work on the larger images. I was also cropping off 2% of the image length when considering the best alignments. The results are shown below:

G: (0, -5)
R: (55, -14)
G: (59, 10)
R: (122, 8)
G: (41, 16)
R: (89, 22)
G: (57, -6)
R: (93, -17)
G: (83, 4)
R: (172, 6)
G: (52, 22)
R: (109, 35)
G: (76, -1)
R: (159, -3)
G: (52, 5)
R: (110, 7)
G: (40, -3)
R: (94, 2)
G: (53, -5)
R: (88, -15)

The Emir: The one picture my algorithm couldn't get right --> Edge Detection!.

G: (23, 8)
R: (108, 17)

This picture is still relatively blurry -- it's likely due to the fact that there is a lot of blue on the emir's robe, so any other colors have a lot less intensity. Instead, I tried to line up the edges in the image. I used filters.sobel(img) in order to do this. Here is the final result:

G: (49, 23)
R: (107, 40)

Looks like the edge detection worked!

Some other examples from LOC:

G: (48, -7)
R: (107, -18)
G: (12, -11)
R: (238, -22)