This project involves automatic alignment of RGB color channels from the Prokudin-Gorskii collection.
The image for each color channel was obtained by dividing the original plate into thirds. A Gaussian filter was applied to each of the channels before alignment.
The number of scales for an image pyramid was then determined such that a translation of one pixel in the smallest level would represent at least a 5% shift in the image.
Working from the smallest scale to the largest, I then tested progressively finer translations and rotations to align the R or G channel to the B channel. A shift of +/-1 px was tested for each level in the y- and x-directions, and a rotation of +/-0.05*2^zoom_level deg (+/-128px and +/-6.4 deg for the .tif plates at the smallest level).
At each level, the results from the previous level were saved, and applied to the images at the current level before the new, finer translations and rotations were tested.
The scores for the translations and rotations were determined by applying NCC to the gradient magnitudes of the scaled/shifted/rotated channels, where the gradient magnitude was calculated as G = sqrt(gx^2 + gy^2), where gx and gy were determined by applying the horizonal and vertical Sobel filters, respectively. The evaluation was performed on the central 0.8-scale crop, due to the image borders.
Once the best translation and rotation were determined, the resulting image was converted to greyscale. The top border was then determined by finding points in the top-10% crop where the gradient was vertically aligned (theta = arctan2(gy / gx) within pi/8 of +/-pi/2), applying a top-40% filter for gradient magnitude G to these points, and then outputting the highest y-value such that at least 33% of points in the corresponding row matched the previous criteria. A corresponding process was repeated for the left/bottom/right borders.