In this project, glass plate negatives taken by photographer Sergei Mikhailovich Produkin-Gorskii are aligned to create colorized images. Produkin-Gorskii used a three-stack camera, with each camera capturing exposures with a different color filter. Combining these exposures enables us to see the original image in colorized form. The main obstacle to retrieving these colorized form, however, are the small offsets and misalignments in each exposure, preventing a naive stack of the three color layers on top of each other from generating a quality image.
The project specification contained many, very helpful hints and tricks. To that end, I initially followed the spec to the letter. The first part of the project involved a single-scale implementation that worked well for the smaller images (.jpg files) included. Here, the primary implementation tasks were coding the heuristics and setting up the exhaustive search. A major decision point here was which heuristic to choose from the two provided in the spec: sum of squared differences or normalized cross correlation. I experimented with both, and realized that for smaller images, they could result in dramatically different results, but one was not necessarily superior.
In fact, I noticed that images were not very clear at all, and so I took the next step of a fixed crop before applying the heuristics. This dramatically improved performance and actually caused both SSD and NCC to return the exact same results for all the small images. I choose to crop 15 off every side of the images, as during the exhaustive search, I followed the project spec's advice to use a [-15, 15] search range.
I then implemented the image pyramid approach in order to tackle the much larger .tif images. The primary technical challenge was figuring out what this meant at all; after following Piazza comments made by students and TAs alike, I grasped the concept. I decided to use a scale factor of 2 and a depth of 5 for my pyramid. This was made upon the observation that with this scale factor and depth, I was achieving good results on the majority of the images. I tried other scale factors, but either saw no realistic improvement or saw substantial slowdown. Increasing depth too much would sometimes cause problems with the way I was still applying the fixed crop. Additionally, at the deepest layer, I chose to use a default search range of [-30, 30], which is larger than the search range from before. This helped with accuracy a good amount at minimal additional time cost.
A very interesting note here is that I was still alternating between using SSD and NCC as my heuristic. However, upon reaching emir.tif, I decided to go with the SSD heuristic. The NCC heuristic would cause the red layer of emir.tif to appear significantly offset from the blue and green layers. As mentioned in the project specification, I believe this is due to the brightness differences of the layers. However, the SSD heuristic performs excellently and has no problems with emir.tif. This is of significant interest to me because I am not entirely sure why SSD would deal with the brightness issues any better. I suspect this is because at the smallest, coarsest version of emir.tif, SSD manages to find the correct range to align emir.tif because the differences here are more coarse, and this naturally has a ripple effect downward through the pyramid in choosing the right displacement. Besides emir.tif, SSD and NCC heuristics performed approximately the same with minor differences.
Displacements: G: [2, 5], R: [3, 12]
Displacements: G: [2, -3], R: [2, 3]
Displacements: G: [2, 5], R: [3, 12]
Displacements: G: [3, 36], R: [5, 97]
Displacements: G: [24, 48], R: [49, 107]
For an interesting comparison, I also include, below this line, the NCC heuristic version of emir.tif that I got.
Displacements: G: [20, 348], R: [-416, 336]
Displacements: G: [10, 59], R: [9, 121]
Displacements: G: [16, 41], R: [22, 89]
Displacements: G: [1, 56], R: [1, 107]
Displacements: G: [4, 83], R: [7, 174]
Displacements: G: [22, 52], R: [35, 108]
Displacements: G: [17, 75], R: [25, 169]
Displacements: G: [5, 52], R: [7, 110]
Displacements: G: [-2, 41], R: [25, 89]
Displacements: G: [-5, 53], R: [-14, 97]
Displacements: G: [24, 56], R: [17, 117]
Displacements: G: [23, 57], R: [24, 127]
Displacements: G: [12, 56], R: [9, 124]]