使用MATLAB imrotate的平铺图像

时间:2016-02-01 08:44:48

标签: image matlab image-processing

当我使用MATLAB的#include <stdio.h> #include <stdlib.h> int main(){ int* number = malloc(101 * sizeof(int)); int num = 0; number[num] = 1; while (number[num] <= 100){ printf(" %d\n ", number[num]); num = num +1; number[num] = number[num]+1; } return 0; } 函数时,输出图像缺少用零填充的部分。

我可以以某种方式使角落中的三角形(即缺失的部分)填充图像的相对边缘吗?所以我会将图像与周围的8个邻居平铺,然后旋转并裁剪出更大的图像?

感谢您的帮助,

2 个答案:

答案 0 :(得分:3)

我认为这样做的最好(也是内存效率最高)的方法是使用interp2在新的像素中心对原始图像进行采样(原始像素中心由所需角度的相反)。然后在这些采样点上使用mod以确保它们落在原始图像的维度内。 mod的额外好处是新的x,y坐标超出范围,只是“环绕”到图像的另一侧。

% Load some sample image
load mri 
im = double(D(:,:,12));
[rows, cols] = size(im);

% The original pixel centers
[xx,yy] = meshgrid(1:cols, 1:rows);

% Setup the rotation matrix
theta = pi/4;
R = [cos(-theta), -sin(-theta);
     sin(-theta), cos(-theta)];

% Center of Rotation (center of the image)
center = [cols/2, rows/2];

% Determine the new pixel centers (rotated)
xy = bsxfun(@minus, [xx(:), yy(:)], center) * R;
xy = bsxfun(@plus, xy, center);

% Mod these using the dimensions of the image to "wrap" around
x = mod(xy(:,1) - 1, cols - 1) + 1;
y = mod(xy(:,2) - 1, rows - 1) + 1;

% Sample the original image at the new pixel centers
im2 = interp2(xx, yy, im, x, y);
im2 = reshape(im2, [rows, cols])

旋转= 45度

enter image description here

这适用于任意宽高比(下面是一张图片,展示了由@BlackAdder引起的问题,其中由于图像高而窄,因此复制品[3,3]无效)。 / p>

旋转= 90度

enter image description here

这还有一个额外的好处,就是它不依赖于图像处理工具箱。

答案 1 :(得分:2)

使用图像处理工具箱,最直接的方法是使用padarray。给出一张图片:

>> img = reshape(1:25, 5, 5)
img =

    1    6   11   16   21
    2    7   12   17   22
    3    8   13   18   23
    4    9   14   19   24
    5   10   15   20   25

然后你可以在所有方面复制图像:

>> padarray(img, size(img), 'circular')
ans =

    1    6   11   16   21  |  1    6   11   16   21  |  1    6   11   16   21
    2    7   12   17   22  |  2    7   12   17   22  |  2    7   12   17   22
    3    8   13   18   23  |  3    8   13   18   23  |  3    8   13   18   23
    4    9   14   19   24  |  4    9   14   19   24  |  4    9   14   19   24
    5   10   15   20   25  |  5   10   15   20   25  |  5   10   15   20   25
   --------------------------------------------------------------------------
    1    6   11   16   21  |  1    6   11   16   21  |  1    6   11   16   21
    2    7   12   17   22  |  2    7   12   17   22  |  2    7   12   17   22
    3    8   13   18   23  |  3    8   13   18   23  |  3    8   13   18   23
    4    9   14   19   24  |  4    9   14   19   24  |  4    9   14   19   24
    5   10   15   20   25  |  5   10   15   20   25  |  5   10   15   20   25
   --------------------------------------------------------------------------
    1    6   11   16   21  |  1    6   11   16   21  |  1    6   11   16   21
    2    7   12   17   22  |  2    7   12   17   22  |  2    7   12   17   22
    3    8   13   18   23  |  3    8   13   18   23  |  3    8   13   18   23
    4    9   14   19   24  |  4    9   14   19   24  |  4    9   14   19   24
    5   10   15   20   25  |  5   10   15   20   25  |  5   10   15   20   25

(添加的线条用于显示中心的原始矩阵和填充的副本。)旋转完成后,您可以裁剪矩阵的中间位置以获得最终图像。

请注意,此方法也适用于3通道图像。

作为注释中的@Suever和@BlackAdder注释,此填充对于具有大纵横比(大于25.456:9)的图像可能不足,特别是对于接近45°的奇数倍的旋转。您可以通过计算可能需要的最大值来使填充更准确。

s = size(img);
s = s(1:2);                      % account for multi-channel images

maxext = sqrt(s * s.');          % calculate length of image diagonal
padsize = ceil((maxext - s)/2);  % find amount of padding needed for each side

padarray(img, padsize, 'circular');