1
clear
I = imread('256.jpg');
%imshow(I);
center = 128;
[x, y] = size(I); % declare image size array
Original = [x, y];
Rotated_I = zeros(x,y); %declare size of array to store pixel
theta = 90;

for row = 1:y
    for column = 1:x
         x_original = (column - 128) * cos(theta) - (row - 128)*sin(theta);
         y_original = (column - 128) * sin(theta) + (row - 128)*cos(theta); % reverse rotate

         p = floor(x_original);
         q = floor(y_original);
         a = y_original - p;
         b = x_original - q; %
         Rotated_I(column, row) = (1-a)*((1-b)*Original(p,q)+b*Original(p,q+1))+a*((q-b)*Original(p+1,q)+b*Original(p+1,q+1)); % Find pixel using bilinear interpolation

    end
end

imshow(Rotated_I);  

I tried to rotate image using reverse rotate and bilinear interpolation, but only i see is error message. It says "the first index exceeds array". Is there anything wrong in my code?

Dohoon Kim
  • 11
  • 2

2 Answers2

1

Here is a working version with a number of changes. The main difference is that it checks whether a coordinate exists in the original image before adding that to the rotate image. This allows for arbitrary rotations, like 45 degrees. Also, images in MATLAB have y as the first dimension and x as the second, so are accessed as I(y, x) or I(row, column).

clear
I = imread('256.jpg');
% imshow(I);
center = 128;
[y, x] = size(I); % in MATLAB, images are y-by-x in size (ie. y is dimension 1)
Original = I; % Original needs to be the image I
Rotated_I = zeros(y, x);
theta = 90;

for row = 1:y
    for column = 1:x
         x_original = (column - center) * cosd(theta) - (row - center)*sind(theta) + center; % theta is in degrees so use cosd and sind
         y_original = (column - center) * sind(theta) + (row - center)*cosd(theta) + center; % also add center back on

         p = floor(y_original); % x_original and y_original were swapped here
         q = floor(x_original); % x_original and y_original were swapped here
         a = y_original - p; 
         b = x_original - q;
         % check if the coordinate is in the original image to prevent errors
         if p > 0 && p <= y && q > 0 && q <= x
             Rotated_I(row, column) = Rotated_I(row, column) + (1-a)*(1-b)*Original(p,q);
         end
         if p > 0 && p <= y && q+1 > 0 && q+1 <= x
             Rotated_I(row, column) = Rotated_I(row, column) + (1-a)*b*Original(p,q+1);
         end
         if p+1 > 0 && p+1 <= y && q > 0 && q <= x
             Rotated_I(row, column) = Rotated_I(row, column) + a*(1-b)*Original(p+1,q);
         end
         if p+1 > 0 && p+1 <= y && q+1 > 0 && q+1 <= x
             Rotated_I(row, column) = Rotated_I(row, column) + a*b*Original(p+1,q+1);
         end
    end
end

% convert to uint image so it displays properly (double expects values from 0 to 1)
imshow(uint8(Rotated_I));  
Dominic D
  • 1,778
  • 2
  • 5
  • 12
0

I do not know if you necessarily want to have your own implementation or not. But if not, you could always use imrotate:

Rotated_I = imrotate(I, 90, 'bilinear', 'crop');

90 => Degrees of rotation

'bilinear' => Bilinear interpolation (alternatives: nearest, bicubic)

'crop' => Maintain the pixel size of the rotated image the same as the input image

imrotate is part of the Image Processing Toolbox.

If_You_Say_So
  • 1,195
  • 1
  • 10
  • 25