In this assignment we experimented with techniques for aligning separate color plates for images in order to make a color image using matlab. The goal is to align the plates so that there is no color fringing or ghosting as the boundaries of regions. We considered translations of the plates by integer numbers of pixels and performed experiments with multiple metrics for evaluating the quality of an alignment. We did experiments using images from the Prokudin-Gorskii Collection as well as some color plates we found on the web.
The basic algorithm used was a simple exhaustive search over offsets for a plate in order to align it to another plate. In order to make things run faster subsampling at multiple scales was applied to the images.
Here is the algorithm:
Here is parts of the code
...
error_G = zeros(2*range+1,2*range+1);
temp_G = zeros(height-2*margin,width-2*margin);
for x=-range:range
for y=-range:range
temp_G(1:height-2*margin,1:width-2*margin) = G(margin+1+x:height-margin+x,margin+1+y:width-margin+y);
error_G(range+1+x,range+1+y)=sum(sum((template-temp_G).^2));
end
end
...
[row_G,col_G] = find(error_G == min(error_G(:)));
[row_B,col_B] = find(error_B == min(error_B(:)));
output = zeros(height-2*margin,width-2*margin,3);
output(:,:,1) = R(margin+1:height-margin,margin+1:width-margin);
output(:,:,2) = G(margin+1+row_G-range-1:height-margin+row_G-range-1,margin+1+col_G-range-1:width-margin+col_G-range-1);
output(:,:,3) = B(margin+1+row_B-range-1:height-margin+row_B-range-1,margin+1+col_B-range-1:width-margin+col_B-range-1);
output=uint8(output);
I use the function 'imrotate' to rotate the image by a given theta angle, which is in '-angle_range' to 'angle_range'. The difference is that the error matrices are now 3-D instead of 2-D, --x, y, plus theta. All the other steps are similar to the previous one.
Full version of the code that considers rotations is photog_a1_rotate.m. 'angle_range' specifies the rotation angle range. Please rename the input triple image as 'a1_input.jpg'.
I defined a factor to specify how fine the fraction is, and make the matrices several times larger than the original one depending on the factor, and then do the one pixel shifting version alignment. Finally, re-size the result back to the original size.
For example, the increment is half a pixel. Then, the factor is 2. We will make, for example, a 100*100 matrix to be a 200*200 one. Every 2*2 elements in the new matrix equal to the corresponding element in original matrix. After do the alignment procedure for the new matrix, I re-size the result matrix to 100*100 by making each element in the 100*100 matrix as the average of corresponding 2*2 elements in the 200*200 matrix.
Full version of the code that considers rotations and considers shifting a fraction of a pixel is photog_a1_final.m. 'fraction_factor' specifies that the pixel fraction increment is 1/fraction_factor pixel. Please rename the input triple image as 'a1_input.jpg'.
There are three version of the code to align the pictures, namely photog_a1.m, photog_a1_rotate.m and photog_a1_final.m. The later, the more considerations, but the more computation time is needed. Generally, we find the first version is good enough for the pictures from the database, and it runs significantly faster.
Also, for the last version, since I double the matrix size and then cut off the margin and finally re-size it back, the output will look like cut less margin.
Wow, it all works! We might have added some intermediate results, like this visualization of the error as a function of offset for one of the plates. It would have been better with a "colorbar" legend to explain the meaning of the colors.
error_G for input2
error_B for input2