input = imread('a1_input.jpg');
input_size = size(input);
height = floor(input_size(1)/3);
width = input_size(2);

B = input(1:height,:);
G = input(height+1:2*height,:);
R = input(2*height+1:3*height,:);

range = 15;
margin = 20;

angle_range = 10;


R = double(R);
G = double(G);
B = double(B);

template = R(margin+1:height-margin,margin+1:width-margin);

error_G = zeros(2*range+1,2*range+1,2*angle_range+1);
temp_G = zeros(height-2*margin,width-2*margin);
for theta=-angle_range:angle_range
    rotate_G = imrotate(G,theta,'bilinear','crop');
    for x=-range:range
        for y=-range:range
            temp_G(1:height-2*margin,1:width-2*margin) = rotate_G(margin+1+x:height-margin+x,margin+1+y:width-margin+y);
            error_G(range+1+x,range+1+y,angle_range+1+theta)=sum(sum((template-temp_G).^2));
        end
    end
end

error_B = zeros(2*range+1,2*range+1,2*angle_range+1);
temp_B = zeros(height-2*margin,width-2*margin);
for theta=-angle_range:angle_range
    rotate_B = imrotate(B,theta,'bilinear','crop');
    for x=-range:range
        for y=-range:range
            temp_B(1:height-2*margin,1:width-2*margin) = rotate_B(margin+1+x:height-margin+x,margin+1+y:width-margin+y);
            error_B(range+1+x,range+1+y,angle_range+1+theta)=sum(sum((template-temp_B).^2));
        end
    end
end

[error_G3 idx3] = min(error_G, [], 3);
[error_G2 idx2] = min(error_G3, [], 2);
[error_G1 idx1] = min(error_G2, [], 1);
idx1;
idx2=idx2(idx1);
idx3=idx3(idx1,idx2);
G_idx1 = idx1-range-1;
G_idx2 = idx2-range-1;
G_idx3 = idx3-angle_range-1;

[error_B3 idx3] = min(error_B, [], 3);
[error_B2 idx2] = min(error_B3, [], 2);
[error_B1 idx1] = min(error_B2, [], 1);
idx1;
idx2=idx2(idx1);
idx3=idx3(idx1,idx2);
B_idx1 = idx1-range-1;
B_idx2 = idx2-range-1;
B_idx3 = idx3-angle_range-1;

G = imrotate(G,G_idx3,'bilinear','crop');
B = imrotate(B,B_idx3,'bilinear','crop');

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+G_idx1:height-margin+G_idx1,margin+1+G_idx2:width-margin+G_idx2);
output(:,:,3) = B(margin+1+B_idx1:height-margin+B_idx1,margin+1+B_idx2:width-margin+B_idx2);
output=uint8(output);

imshow(output);

    

