使用双线性插值的Matlab中的图像旋转

问题描述 投票:0回答:2
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);  

我尝试使用反向旋转和双线性插值来旋转图像,但只有我看到错误消息。它说“第一个索引超出数组”。我的代码有什么问题吗?

image matlab rotation bilinear-interpolation
2个回答
0
投票

这里是具有许多更改的有效版本。主要区别在于,在将坐标添加到旋转图像之前,它会检查坐标是否存在于原始图像中。这允许任意旋转,例如45度。此外,MATLAB中的图像的第一个维度为y,第二个维度为x,因此可以通过I(y, x)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));  

0
投票

我不知道您是否一定要拥有自己的实现。但是,如果没有,您可以始终使用imrotate

imrotate

Rotated_I = imrotate(I, 90, 'bilinear', 'crop'); =>旋转角度

[90 =>双线性插值(替代项:'bilinear'nearest

[bicubic =>保持旋转图像的像素大小与输入图像相同

['crop'是图像处理工具箱的一部分。

© www.soinside.com 2019 - 2024. All rights reserved.