Briefly, this project comprises the coloring of an image via the process of stacking image negatives on top of each other. These image negatives are basically the original picture seen through different color filters. The bulk of this project was not on the stacking but rather on alignment; given that the image negatives we were given are not "perfect" digital images and are rather pictures of the physical negatives that exist today, without alignment the images would look blurry. The concept of image pyramids for efficient computation and the idea of L2 (sum of squared deviation) scoring on pixel brightness to optimize alignment were core to this project.

Approach: design an "align" function that returns an (x, y) tuple representing the displacement that optimally aligns two images together. For small images, the base range is given (here, [-20, 20]). For every possible combination of displacements in this range (40 * 40) = 1600, the L2 (sum of squared deviations) is calculated on the image vectors. The displaced vector with the minimum L2 norm is then considered to be the optimal displacement. As you will see, this works well on the majority of images, but since this method is inherently reliant on pixel brightness, this method is clearly suboptimal when the image negatives have a high variance on brightness value. This would occur when the original image tends heavily towards a specific RGB color, since when seen through the filter for that color it would be extremely dark, while light on the other image negatives.

These are the results of applying this method on the example images in the Prokudin-Gorskii.

Green to blue: The optimal displacement is x-disp = 3, y-disp = 34 with score 64146.478866745165
Red to blue: The optimal displacement is x-disp = 4, y-disp = 98 with score 109445.57183168284

png

Green to blue: The optimal displacement is x-disp = 2, y-disp = 5 with score 2878.5150941945403


Red to blue: The optimal displacement is x-disp = 3, y-disp = 12 with score 3644.360815071126

png

Green to blue: The optimal displacement is x-disp = 24, y-disp = 49 with score 169203.30912091248

Red to blue: The optimal displacement is x-disp = 43, y-disp = 65 with score 423342.72179905156

png

Green to blue: The optimal displacement is x-disp = 17, y-disp = 59 with score 306952.1230452973

Red to blue: The optimal displacement is x-disp = 13, y-disp = 123 with score 342966.9361112239

png

Green to blue: The optimal displacement is x-disp = 17, y-disp = 41 with score 277851.45602894056

Red to blue: The optimal displacement is x-disp = 23, y-disp = 89 with score 461751.8862172043

png

Green to blue: The optimal displacement is x-disp = 9, y-disp = 55 with score 61881.23325780483

Red to blue: The optimal displacement is x-disp = 12, y-disp = 116 with score 100619.78729061395

png

Green to blue: The optimal displacement is x-disp = 10, y-disp = 81 with score 85183.98655814918

Red to blue: The optimal displacement is x-disp = 12, y-disp = 174 with score 212224.14611888898

png

Green to blue: The optimal displacement is x-disp = 2, y-disp = -3 with score 2767.211887735486


Red to blue: The optimal displacement is x-disp = 2, y-disp = 3 with score 3769.3445751633985

png

Green to blue: The optimal displacement is x-disp = 27, y-disp = 51 with score 113556.84278187006

Red to blue: The optimal displacement is x-disp = 36, y-disp = 108 with score 194657.48287252514

png

Green to blue: The optimal displacement is x-disp = 29, y-disp = 78 with score 121586.56808051528

Red to blue: The optimal displacement is x-disp = 36, y-disp = 174 with score 112021.31910915115

png

Green to blue: The optimal displacement is x-disp = 14, y-disp = 52 with score 109393.54451278276

Red to blue: The optimal displacement is x-disp = 11, y-disp = 111 with score 89974.91363697076

png

The optimal displacement is x-disp = 3, y-disp = 3 with score 5580.17630142253

Red to blue: The optimal displacement is x-disp = 3, y-disp = 6 with score 5632.996416762784

png

Green to blue: The optimal displacement is x-disp = 6, y-disp = 42 with score 96023.47397899591

Red to blue: The optimal displacement is x-disp = 32, y-disp = 87 with score 105657.19888178226

png

Green to blue: The optimal displacement is x-disp = 0, y-disp = 53 with score 84433.60390531436

Red to blue: The optimal displacement is x-disp = -12, y-disp = 104 with score 243466.8519440584

png

#Files of my own choosing

colorize(["rock.tif", "rock2.tif"])
Green to blue: The optimal displacement is x-disp = 34, y-disp = 39 with score 202182.50780469037

Red to blue: The optimal displacement is x-disp = 59, y-disp = 94 with score 184392.67846212973

png

Green to blue: The optimal displacement is x-disp = -1, y-disp = 39 with score 256309.87961553255

Red to blue: The optimal displacement is x-disp = 174, y-disp = -174 with score 662192.5342714353

png

You may notice that the images are blurry / extremely misaligned for the picture of the emir, and the very last picture of the cliffside. This is because, as mentioned in the first section, these pictures have a high variance in brightness. In particular, both the emir picture and the cliffside have a high amount of blue (in the emir's clothing and in the water).