图像的几何变换(一)

图像的几何变换是指改变图像的几何位置、几何形状、几何尺寸等几何特征。

 

一.图像的平移

图像平移是将一幅图像中所有的点都按照指定的平移量在水平、垂直方向移动,平移后的图像与原图像相同。

利用齐次坐标,变换前后图像上的点P0(x0,y0)和P(x,y)之间的关系可以用如下的矩阵变换表示为

平移变换的几点说明:

①平移后图像上的每一点都可以在原图像中找到对应的点。对于不在原图像中的点,可以直接将它的像素值统一设置为0或这255(对于灰度图就是黑色或者白色);

②若图像平移后并没被放大,说明移出的部分被截断,原图像中有像素点被移出显示区域。

③若不想丢失被移出的部分图像,则将新生成的图像扩大。

代码如下:

clear all;
close all;
I = imread('lenna.jpg');

delta_x = 10;                                       % 水平方向的偏移量
delta_y = 10;                                       % 垂直方向的偏移量
[M N] = size(I);                                    % 原图像的宽度和高度
I2 = zeros(M, N);
for x = 1 : M
    if x + delta_x <= M
        for y = 1 : N
            if y + delta_y <= N
               I2(x + delta_x, y + delta_y) = I(x, y);
            end
        end
    end
end
subplot(1, 2, 1), imshow(I);
subplot(1, 2, 2), imshow(uint8(I2));

平移后的图像显示如下:

二.图像的旋转

一般图像的旋转是以图像的中心为原点,旋转一定的角度,即将图像上的所有像素都旋转一个相同的角度。

图像的旋转变换也可以用矩阵变换表示。设点P0(x0, y0)旋转θ角后的对应点为P(x, y),则变换公式为:

逆时针旋转或者是顺时针旋转

利用公式进行图像旋转变换时,需要注意如下两点:

①为了避免图像信息的丢失,图像旋转后必须进行平移变换。

②图像旋转之后,会出现许多空洞点,我们必须对这些空洞点进行填充处理,否则图像旋转后的效果不好,一般也将这种操作称作为插值处理。

上述的旋转是绕坐标轴原点(0,0)进行的,如果是绕某一个指定点旋转,则先要将坐标系平移到该点,再进行旋转,然后将旋转后的图像平移回原坐标系。因此,我们得到绕任一点(x0,y0)的旋转变换公式为:

x’ = (x-x0)·cos(θ) + (y-y0)·sin(θ) + x0

y’ = -(x-x0)·sin(θ) + (y-y0)·cos(θ) + y0

代码如下:

clear all;
close all;
I = imread('lenna.jpg');

H = 1;                      % 矩阵pix第一个元素,即高度
W = 2;                      % 矩阵pix第二个元素,即宽度

[M N] = size(I);                                                        % M为原图像的高度,N为原图像的宽度
theta = 30 / 180 * pi;                                                  % 旋转角度为顺时针方向30度
rot = [cos(theta) -sin(theta) 0; sin(theta) cos(theta) 0; 0 0 1];       % 变换矩阵
inv_rot = inv(rot);                                                     % 变换矩阵的逆运算
pix1 = [1 1 1] * rot;                                                   % 变换后图像左上点的坐标
pix2 = [1 N 1] * rot;                                                   % 变换后图像右上点的坐标
pix3 = [M 1 1] * rot;                                                   % 变换后图像左下点的坐标
pix4 = [M N 1] * rot;                                                   % 变换后图像右下点的坐标

height = round(max([abs(pix1(H) - pix4(H)) abs(pix2(H) - pix3(H))])  + 0.5);        % 变换后图像的高度
width = round(max([abs(pix1(W) - pix4(W)) abs(pix2(W) - pix3(W))])  + 0.5);         % 变换后图像的宽度
delta_y = abs(min([pix1(H) pix2(H) pix3(H) pix4(H)]));                              % y方向负轴超出的偏移量
delta_x = abs(min([pix1(W) pix2(W) pix3(W) pix4(W)]));                              % y方向负轴超出的偏移量

I2 = zeros(height, width);
for y = 1 - delta_y : height - delta_y
   for x = 1 - delta_x : width - delta_x
      pix = [y x 1] * inv_rot;
      if pix(H) > 0.5 && pix(W) > 0.5 && pix(H) < M && pix(W) < N
          I2(y + delta_y, x + delta_x) = I(round(pix(H)), round(pix(W)));
      end
   end
end

subplot(1, 2, 1), imshow(I), title('原图像');
subplot(1, 2, 2), imshow(uint8(I2)), title('旋转后的图像');

旋转后的图像显示如下:

三.图像的比例缩放

图像的比例缩放变换是指给定的图像在x轴方向按比例缩放fx倍,在y轴方向缩放fy倍,从而获得一幅新的图象。比例缩放前后两点P0(x0,y0)、P(x,y)之间的关系用矩阵形式可以表现为:

在图像放大的正变换中,会出现很多的空格。因此,需要对放大后所多出来的空格填入适当的像素值。一般采用最邻近插值和线性插值法。

图像缩小代码如下:

clear all;
close all;

I = imread('lenna.jpg');
[M N] = size(I);

width = int32(0.5 * N)                                    % 将图像宽度缩小为原来的1/2
height = int32(0.5 * M)                                   % 将图像高度缩小为原来的1/2

I2 = uint8(zeros(height, width));
widthScale = floor(N / width);
heightScale = floor(M / height);

for y = 1 : height
   for x = 1 : width
       oldX = x * widthScale;
       oldY = y * heightScale;
       I2(y, x) = I(oldY, oldX);
   end
end

a1 = subplot(1, 2, 1);
imshow(I), title('原图像');
a2 = subplot(1, 2, 2);
imshow(I2), title('缩小后的图像');
set(a2, 'XLim', get(a1, 'XLim'), 'YLim', get(a1, 'YLim'));          % 将两个sunplot的x,y轴单位长度设为一样

缩小后的图像显示如下:

图像放大代码如下:

clear all;
close all;

I = imread('lenna.jpg');
[M N] = size(I);

width = 2 * N;                                          % 将图像宽度放大为原来的2倍
height = 2 * M;                                         % 将图像高度放大为原来的2倍

I2 = uint8(zeros(height, width));
widthScale = width / N;
heightScale = height / M;

for y = 1 : height
   for x = 1 : width
       oldX = round(x / widthScale);
       oldY = round(y / heightScale);
       if oldX == 0 oldX = 1; end
       if oldY == 0 oldY = 1; end
       if oldX > N oldX = N; end
       if oldY > M oldY = M; end
       I2(y, x) = I(oldY, oldX);
   end
end

a1 = subplot(1, 2, 1);
imshow(I), title('原图像');
a2 = subplot(1, 2, 2);
imshow(I2), title('放大后的图像');
set(a1, 'XLim', get(a2, 'XLim'), 'YLim', get(a2, 'YLim'));          % 将两个sunplot的x,y轴单位长度设为一样

放大后的图像显示如下:

原文地址:https://www.cnblogs.com/minisculestep/p/4865209.html