The project aims to restore the color images automatically from digitized Prokudin-Gorskii glass plate images. To achieve this goal, I extracted the three color iamge, stack them together after the automatic alignment so as to form a color image. The webpage's template is downloaded from w3.css
I implemented the auto-alignment method based on Sum of Squared Differences (SSD) (after normalization (minus mean and then divided by std)) with both single-scale implementation and pyramid version.
For the single-scale alignment, I align b channel with r and g channel respectively. Before performing the alignment, I first crop the r and g channel, so that I can search for which part of b channel matches r(g)'s cropped part the best. Then I will calculate the offset and then do the alignment.
For the pyramid version, I use skimage.transform.resize to downscale the original image by 8, 4, 2, and 1, and perform single-scale alignment on each level. The alignment range is [-int(cropped_x_length/10), int(cropped_x_length/10)], [-int(cropped_y_length/10), int(cropped_y_length/10)] for x and y axes on the lowest level, and [-2, 2] for the higher levels.
The problem I came up with is that if I use small window size for searching ([30,30]), then the program will not perform well on some of the images. Thus, I developed two strategies.
Approach 1: The first is to use the whole image for searching at coarsest level of the pyramid, and then use windows (like size of [30,30]) to search.
Approach 2: Another is to use the whole image for searching at all the pyramid levels. Since, the exhaustive search is down at a very low level, the latter computation cost is affordable (I only search for the range [-2,2], but it will definitely be much slower than the [30,30] approach). I will compare the performance of these two approaches in the Example Images sections.
Offsets (r for red, g for green) are listed in the following pattern: x,y positive value corresponds to shift right/down, and vice versa
offset_r:(12,7)
offset_g:(7,0)
offset_r:(12,3)
offset_g:(5,2)
offset_r:(90,51)
offset_g:(41,18)
offset_r:(104,55)
offset_g:(49,24)
offset_r:(135,2)
offset_g:(42,3)
offset_r:(124,13)
offset_g:(60,17)
offset_r:(80,21)
offset_g:(32,16)
offset_r:(90,23)
offset_g:(41,17)
offset_r:(99,0)
offset_g:(57,6)
offset_r:(117,11)
offset_g:(55,9)
offset_r:(183,32)
offset_g:(87,18)
offset_r:(176,36)
offset_g:(79,29)
offset_r:(98,15)
offset_g:(42,23)
offset_r:(112,11)
offset_g:(53,14)
offset_r:(80,27)
offset_g:(26,0)
offset_r:(87,32)
offset_g:(43,6)
offset_r:(118,30)
offset_g:(63,25)
offset_r:(116,28)
offset_g:(56,21)
offset_r:(126,31)
offset_g:(65,15)
offset_r:(138,22)
offset_g:(65,12)
offset_r:(38,15)
offset_g:(7,16)
offset_r:(36,27)
offset_g:(14,21)
offset_r:(122,50)
offset_g:(50,39)
offset_r:(133,59)
offset_g:(59,36)
offset_r:(87,27)
offset_g:(0,23)
offset_r:(80,25)
offset_g:(0,13)
offset_r:(80,24)
offset_g:(22,24)
offset_r:(84,33)
offset_g:(36,26)