In this project, we want to find proper displacement to align the r, g, b-layers of the images taken by Prokudin-Gorskii.
For small figures, simply shift (using np.roll) the g-layer within a [-20, 20] range in both x, y directions, and find the displacement that lets the g-layer matches the b-layer most. Then do the same for the r-layer.
We believe two layers "matches" when the "distance" between them is minimized. The distance of two layers is the sum of distance of each corresponding pixels in the two layers.
Let a, b be the corresponding pixels in the g-layer, b-layer, respectively. Directly comparing the value of a and b is not reasonable because they just means the brightness in green and blue. Instead, we want to compare their role, or position, in the entire figure. Therefore, we represent each pixel by a 4-vector representative, which is the difference of the pixel and its N, E, S, W neighbors. For example, a is represented by (aN, aE, aS, aW), where aN = |value of a - value of the pixel above a| in the g-layer, etc. Comparing a pixel with its neighbors allows us to identify the "edges" within the image, and we can further aligns the "edges" of two layers. The distance of a and b is simply |aN-bN|+|aE-bE|+|aS-bS|+|aW-bW|. Summing up the distance of all pixels gives the distance of the two layers.
Recursively downsize the figure by building pyramids until the height is less than 100. Then search for best fit within a [-5, 5] range in both x, y directions. Tracing back the recursive process, given the best displacement of the down-sized (paramid) version, find the best displacement for the original figure by searching within a [-2, 2] neighbor of the given displacement. Final result is the best displacement of the entire layers.
Pyramid is built by scaling an image to 1/4 size by taking average of four (2 by 2) adjacent pixels.
cathedral, displacement = [2 5 3 12]
monastery, displacement = [2 -3 2 3]
tobolsk, displacement = [2 3 3 6]
church, displacement = [4 25 -4 58]
emir, displacement = [23 50 41 106]
harvesters, displacement = [14 60 12 123]
lady, displacement = [9 57 13 120]
melons, displacement = [10 80 13 177]
onion_church, displacement = [24 52 35 108]
sculpture, displacement = [-11 33 -27 140]
self_portrait, displacement = [30 82 37 175]
three_generations, displacement = [12 56 8 111]
train, displacement = [-2 40 28 85]
Religious painting, displacement = [6 29 7 69]
Arched entranceway, displacement = [1 38 -8 97]
Gondola, displacement = [15 15 30 81]
castle, displacement = [15 41 25 91]
Religious candlestick, displacement = [1 48 -7 106]