`(x, y)`

for each of the colored plates, I used normalized cross correlation (NCC), which is a dot product between two normalized centered vectors, as suggested by the project spec. In this method, I maximized the normalized cross correlation among the range of displacements. Initially, I used sum of squared differences (SSD), which calculates the sum of the squared difference value for each pixel, and found the displacement that gave me the smallest sum of squared differences. However, the sum of squared differences was not very robust in that the images still appeared slightly misaligned and blurry.
`np.roll`

to shift the image based on the displacement, which was chosen in a range of `(-30, 30)`

: 30 pixels in both horizontal and vertical directions. After retrieving the best displacement coordinates for both the green and red filters, I then shifted the green filter and red images to their respective displacement coordinates and finally stack all the filters together by red, green, and blue to produce the colored image.
For the image pyramid algorithm, I defined a maximum number of levels for the pyramid, a factor alpha for scaling, and displacement for each level. First, I saved copies of the original filters, so at the end, I can align those original filters and stack them to produce the high resolution colorized imaages. Then, I started to scale the blue, green, and red filters down to the coarsest level, which I defined to be if the image's height was less than 250 pixels. While I scaled down, at each level, I would keep track of the factor that I would need to multiply to return that image to the original size through a list of multiplying factors. Now that the filters are at the blurriest level and a much smaller size than before, I started to scan with a range of

`(-20, 20)`

pixels to find the best displacement and updated the optimal displacement for the green and red filter with regards to the multiplying factor. After, I rotated the filters by the best displacement for that level and rescaled the filters to be finer to move to the next level. For all the finer levels after that, I scanned with a range of `(-5, 5)`

pixels and did the same process until I reached to the original size. With the optimal displacements calculated, I shifted the original green and red filters by those displacements and stacked the colored filters together to produce the colorized image. The parameters used for the image pyramid were 8 as the maximum number levels of the pyramid, a factor alpha of 0.5 for scaling, and a displacment of 5 for each level.
`emir.tif`

, due to considerable differences in brightness between the filters. Initially, I had a problem with blurriness with the naive alignment method of normalized cross correlation, but cropping the black edges helped fix that problem. Some other problems that I encountered were aligning photos that involved people, because for the `harvesters.tif`

and `lady.tif`

, there was some movement that went on between the separate color filter shots, so there are some misalignments of the girl near the left side of `harvesters.tif`

and slight blurriness around the lady's face of `lady.tif`

. Also, for images that had some sort of movement like wind, there would be a small notable patch of the filter in the colorized image, like the man's coat in `three_generations.tif`

.
`emir.tif`

, I used the Canny Edge Detector from `skimage`

with a sigma of 1.5 on the blue, green, and red filters. Using the normalized cross correlation and my image pyramid but with the Canny filter versions to compare and align the colored filters instead, `emir.tif`

was cleanly aligned. This worked a lot better compared to the RGB comparison as the filters were being aligned based on the outlines of the clothing and his silhouette. Also, similarly for `lady.tif`

, the Canny filter was able to align exactly on the face of the lady, compared to before where there was some haziness around her face.