In this assignment, we were given Prokudin-Gorskii glass plate images and our task was to digitalize these glass plate images. This involved extracting the RGB channels from the glass plate images, aligning the 3 channels, and combining them to create the final RGB image.
To do the above task, we assume channels can be well aligned using pure translation. I aligned the reg and green channel with the blue channel. I started with a naive implementation where we defined a window of displacement from [-15, 15] for the horizontal and vertical displacement and did an exhaustive search over all possible combinations. The best displacement was chosen using SSD(Sum of Square Differences) or NCC(Normalized Cross Correlation) metric. Because all the images have a lot of noise on the border pixels, I calculated the metric for a cropped center region to avoid the bad region from affecting the result.
One possible option to calculate metrics like SSD or NCC was to do on the image values. However, this approach did not work for images like emir.tif because different channels can have different brightness values. Hence to deal with the above challenge, I used image gradients as a feature instead of image channel values and that gave me robust results.
Another challenge that I faced was that some images like cathedral.jpg were low resolution, however, images like emir.tif were very high-resolution images. Hence the naive exhaustive approach of finding the translation parameter would take a long time for these images. As a result, I create a pyramid of different resolutions for such images. I then started with the smallest image in that pyramid and found the displacement for that image and used that as an estimate for the next image in the pyramid. This enabled me to scale my approach for high-resolution images as well.
![]() |
![]() |
R=[12, 3] G = [5, 2] |
![]() |
![]() |
R=[107, 40] G = [49, 23] |
![]() |
![]() |
R=[124, 11] G = [60, 17] |
| R=[90, 23] G = [40, 16] |
||
![]() |
![]() |
R=[117, 27] G = [57, 22] |
![]() |
![]() |
R=[111, 8] G = [54, 0] |
![]() |
![]() |
R=[86, 29] G = [41, 1] |
![]() |
![]() |
R=[117, 27] G = [57, 22] |
![]() |
![]() |
R=[137, 22] G = [65, 12] |
Here instead of using image pixel values as features, I used image gradients as feature values for bette alignment. Image gradients helps because they are not senstive to image brightness and hence give better results than using raw pixels values as features. I implemented iamge gradient calculation by myself without using any special functions. It was done by using 2nd order finite difference method.
Here is an example of alignment done using pixel values and edge values. We can see that the edge alignment is much better than the colour alignment.
![]() |
![]() |
![]() |
Here I observed that all the images have a black and white border on the boundary. In order to remove it, I first removed all the rows and columns at the top and bottom that are majorly white. After removal of white color rows and columns, I then the black rows and columns on the edge. This was done by taking a mean of the rows and columns on the edges and removing them if they were majorly black or white.
Here are some an examples of auto cropping using the above algorithm:
![]() |
![]() |
![]() |
![]() |
To implement Auto Constrast I first found the histogram of the original image. I then used to cut the lowest 1% and higest 1% of the values and then scaled the minimum value to 0 and the maximum value to 255. This helped in increasing the contrast of the image.
Here are some an examples of auto contrast algorithm using the above algorithm:
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |