[Digital image processing] [Matlab] geometric transformation (translation, scaling, rotation, mirroring, transposition, etc.)

Note:
1. Use software: Matlab2019a.
2. Use images from Kris Wu Weibo.
3. So the coordinate system adopts the vertical as the x-axis and the horizontal as the y-axis (corresponding to the matlab matrix).
4. The beginner code is for reference only, you can simplify or add the parts you want.
5. I wish you all happy coding!

1. Image translation

1.1. Principle
Image translation is to move all points in the image horizontally and vertically according to the specified translation amount.
Suppose the point with the initial coordinates (x0, y0) is translated (tx, ty) and the coordinates become (x1, y1)
x1=x0+tx
y1=y0+ty

Insert picture description here
1.2. Algorithm
(1) Get the width and height of the original image.
(2) Enter the offset move_x, move_y.
(3) Create a new image blank matrix of the same size.
(4) Cycle each pixel in the original image in turn, read in a pixel (x0, y0), find the position of the target image (x1=x0-move_x, y1=y0-move_y) according to its coordinates, and set the pixel The gray value at (x0,y0) is assigned to (x1,y1) in the new image.
(5) According to the sign of the translation amount, it can be divided into the following 4 cases:
Insert picture description here
1.3. Code
mymove.m

% 函数mymove:实现图像的上下左右平移
% 输入参数:I为原图像
%         move_x,move_y为竖直,水平位移大小
% 输出参数:平移变换后的图像OUT
% 使用函数:double(I):增大精度,便于图像的计算
%         size(J):求矩阵的宽高
%         zeros():生成全零矩阵
%         inf:无穷大(白色)
function OUT = mymove(I,move_x,move_y)
J=double(I);
HW=size(J);%获取原图像大小
OUT=zeros(HW);%新建新的图像矩阵
OUT(1:HW(1),1:HW(2))=inf;%初始为全白图像
if((move_x>=0) && (move_y>=0))
    OUT(move_x+1:HW(1),move_y+1:HW(2))=J(1:HW(1)-move_x,1:HW(2)-move_y);
elseif((move_x>0) && (move_y<0))
    OUT(move_x+1:HW(1),1:HW(2)+move_y)=J(1:HW(1)-move_x,1-move_y:HW(2));
elseif((move_x<0) && (move_y>0))
    OUT(1:HW(1)+move_x,move_y+1:HW(2))=J(1-move_x:HW(1),1:HW(2)-move_y); 
elseif((move_x<0) && (move_y<0))
    OUT(1:HW(1)+move_x,1:HW(2)+move_y)=J(1-move_x:HW(1),1-move_y:HW(2));
end
OUT=uint8(OUT);
end

main.m

%主函数
close all;
clear all; %#ok<*CLALL>
clc;
%% RGB->灰度图像  
RGB=imread('kris(1).jpg'); %图像读入
I=rgb2gray(RGB); %把 RGB 图像转换成灰度图像
%% 图像的平移(Image translation)
move_x=100;%竖直位移(默认向下)
move_y=60;%水平位移(默认向右)
OUT_1_1=mymove(I,move_x,move_y);
move_x=100;move_y=-60;
OUT_1_2=mymove(I,move_x,move_y);
move_x=-100;move_y=60;
OUT_1_3=mymove(I,move_x,move_y);
move_x=-100;move_y=-60;
OUT_1_4=mymove(I,move_x,move_y);
move_x=1050;move_y=-60;%超出图像范围的情况
OUT_1_5=mymove(I,move_x,move_y);
figure,suptitle('【图像平移】');
subplot(2,3,1),imshow(I),axis on,title('原图像'); 
subplot(2,3,2),imshow(OUT_1_1),axis on,title('平移变换1');
subplot(2,3,3),imshow(OUT_1_2),axis on,title('平移变换2');
subplot(2,3,4),imshow(OUT_1_3),axis on,title('平移变换3');
subplot(2,3,5),imshow(OUT_1_4),axis on,title('平移变换4');
subplot(2,3,6),imshow(OUT_1_5),axis on,title('平移变换5(平移距离超出原图像坐标范围)');

1.4. Results screenshot

2. Image zoom

2.1. Principle
Suppose the image zoom ratio in the X axis direction is kx, and the zoom ratio in the Y axis direction is ky,
x1=x0 kx
y1=y0
ky

When kx>1 and ky>1, the original image is enlarged. When the image is enlarged, new pixels are generated, which can be approximated by interpolation algorithms.
When kx<1 and ky<1, the original image is reduced.
When kx=ky, the image is scaled proportionally; when kx≠ky, the image is scaled non-proportionally, the image will be deformed, and this deformation is irreversible.
2.2. Algorithm
(1) Get the width and height of the original image.
(2) Enter the zoom ratio: zoom_x, zoom_y.
(3) Get the width and height of the new image.
(4) The coordinates of each target point are cycled sequentially. Calculate the coordinates of the pixel in the original image, use bilinear interpolation algorithm, calculate the pixel value and assign it to the target point.
(5) The final output of the zoomed image, whether it is zoomed in or zoomed out, the size of the canvas remains unchanged, which makes it easier to observe the image transformation.
(6) The specific steps of the bilinear interpolation algorithm:
①The original image is scaled as required to obtain the scaled coordinates, and then the position of the coordinates on the original image is obtained from the scaled coordinates (i, j), namely (x ,y)=(i/zoom_x, j/zoom_y), which is the M point ([x]+u,[y]+v) shown in the figure above. Where (u, v) represents the coordinates of the decimal part.
② Suppose there are 4 points in the original image, R1 (a1, b1), R2 (a1, b2), R3 (a2, b1), R4 (a2, b2), and these four points are adjacent points, namely
a2-a1=1; b2-b1=1;
and the point M ([x]+u,[y]+v) in the figure is the point to be inserted into the zoomed image.
③According to the bilinear interpolation algorithm, first perform linear interpolation in the x direction, that is,
f(M1)=u f(R1)+(1-u) f(R2);
f(M2)=u
f(R3 )+(1-u) f(R4);

④ Perform linear interpolation in the y direction, that is,
f(M)=v f(M1)+(1-v) f(M2);
⑤In summary, there is : F(M)=uvf(R1)+(1-u)vf(R2)+u(1-v)f(R3)+(1-u)(1-v)f(R4) ;
Insert picture description here
2.3. Code
myimresize.m

% 函数myimresize:采用双线性插值法对图像进行缩放处理
% 输入参数:I为原图像
%           zoom_x,zoom_y表示缩放的倍数
% 输出参数:平移变换后的图像OUT
% 使用函数:floor(x):向下取整
%         ceil(x):向上取整
%         round(x):取最接近的整数
function OUT=myimresize(I,zoom_x,zoom_y)
J=double(I); %二维矩阵转为双精度类型
HW=size(J);%获取原图像大小
OUT=zeros(HW);%新建新的图像矩阵
OUT(1:HW(1),1:HW(2))=inf;%初始为空白
rHW=[round(HW(1)*zoom_y),round(HW(2)*zoom_x)];%新的图像高宽
for i = 1 : rHW(1)        %缩放后的图像的(i,j)位置对应原图的(x,y)
    for j = 1 : rHW(2)
        x = i / zoom_y ;
        y = j / zoom_x ;
        u = x - floor(x);
        v = y - floor(y); %得到小数部分坐标
        if x < 1           %图像的边界处理
            x = 1;
        end
        if y < 1
            y = 1;
        end
        %用原图的四个真实像素点来双线性插值获得“虚”像素的像素值
        OUT(i, j) = J(floor(x), floor(y)) * u * v + ...
                    J(floor(x), ceil(y)) * (1-u) * v + ...
                    J(ceil(x), floor(y)) * u * (1-v) + ...
                    J(ceil(x), ceil(y)) *(1-u) * (1-v);
    end
end
OUT=uint8(OUT(1:HW(1),1:HW(2)));
end

main.m

%主函数
close all;
clear all; %#ok<*CLALL>
clc;
%% RGB->灰度图像  
RGB=imread('kris(1).jpg'); %图像读入
I=rgb2gray(RGB); %把 RGB 图像转换成灰度图像
%% 图像的缩放(Image scaling)
zoom_x=0.5;zoom_y=0.5;%等比缩小
OUT_2_1=myimresize(I,zoom_x,zoom_y);
zoom_x=2;zoom_y=2;%等比放大
OUT_2_2=myimresize(I,zoom_x,zoom_y);
zoom_x=0.5;zoom_y=0.8;%非比例缩小
OUT_2_3=myimresize(I,zoom_x,zoom_y);
zoom_x=1.8;zoom_y=1;%非比例放大
OUT_2_4=myimresize(I,zoom_x,zoom_y);
figure,suptitle('【图像缩放1】');
subplot(1,3,1),imshow(I),axis on,title('原图像') 
subplot(1,3,2),imshow(OUT_2_1),axis on,title('等比缩小变换');
subplot(1,3,3),imshow(OUT_2_2),axis on,title('等比放大变换');
figure,suptitle('【图像缩放2】');
subplot(1,3,1),imshow(I),axis on,title('原图像') 
subplot(1,3,2),imshow(OUT_2_3),axis on,title('非比例缩小变换');
subplot(1,3,3),imshow(OUT_2_4),axis on,title('非比例放大变换');

2.4. Results screenshot
Insert picture description here
Insert picture description here

3. Image rotation

3.1. Principle It
must be specified what the image is rotated around. Generally, the rotation of an image takes the center of the image as the origin and rotates a certain angle.
After rotating, the size of the image is generally changed.
Suppose any point A0 (x0, y0) of the original image is rotated by an angle β counterclockwise to a new position A (x, y). For convenience, the polar coordinate form is used:
x0=rcos(β)
y0=rsin(β ) The

transformed coordinates after counterclockwise rotation are:
x1=x0cos(β)-y0sin(β)
y1=x0sin(β)+y0cos(β) The

transformation is shown in the following figure:
Insert picture description here
3.2. Algorithm
(1) Get the width and height of the original image .
(2) Enter the rotation angle: alpha, and perform the following processing:
① Convert the rotation angle to a calculation between 0 and 360;
② Obtain the rotation radian;
Insert picture description here
thus, the rotation angle can be divided into the above 4 intervals, and each interval corresponds to the transformation different.
(3) Get the width and height of the new image.
In order to ensure that the rotated image can be in the canvas without being cut, the initialized canvas is set to the maximum, so
two functions of abs (x) taking the absolute value and ceil (x) rounding up are used.

nHW(1)=ceil(HW(1)*abs(cos(abs(alpha)))+HW(2)*abs(sin(abs(alpha))));
nHW(2)=ceil(HW(1)*abs(sin(abs(alpha)))+HW(2)*abs(cos(abs(alpha))));

(4) The coordinates of each target point are cycled sequentially.
①Calculate the coordinates of the pixel in the original image:
Pay special attention to this place because our default setting is counterclockwise transformation, and when calculating, the coordinate point (i, j) of the new image is converted to calculate its position in the original image (x, y) So the conversion matrix should be reversed, that is, the conversion matrix is ​​as follows:
x=icos(β)+jsin(β)
y=-isin(β)+jcos(β) in

order to make all the images displayed on the canvas The exact center is divided into 4 cases according to the four intervals of the angle alpha, and the displacement of each case is different, and thus 4 different calculation formulas are obtained.
②Then use the bilinear interpolation algorithm (the specific steps are the same as when the image is zoomed) to calculate the pixel value and assign it to the target point.
(5) The final output of the zoomed image, whether it is zoomed in or zoomed out, the size of the canvas remains unchanged, which makes it easier to observe the image transformation.

3.3. Code
myimrotate.m

%函数myimrotate:采用双线性插值法实现图像旋转
%输入参数:I原图像
%        alpha:旋转的角度(>0为逆时针)
%输出参数:OUT旋转变换后的图像
%使用函数:mod(m,n):对m/n取余
%         abs(x):取绝对值
%         ceil(x):向上取整
%         pi:3.1415926......可直接使用
%         floor(x):向下取整
function OUT=myimrotate(I,alpha)
J=double(I);
HW=size(J);%获取原图像大小
alpha=mod(alpha,360);%将旋转角度转换到0~360之间计算
alpha=alpha*pi/180;%得到旋转弧度
%确保旋转后的图片还在坐标系内
nHW(1)=ceil(HW(1)*abs(cos(abs(alpha)))+HW(2)*abs(sin(abs(alpha))));%新图像的高heighth   
nHW(2)=ceil(HW(1)*abs(sin(abs(alpha)))+HW(2)*abs(cos(abs(alpha))));%新图像的宽width 
OUT=zeros(nHW);%新建新的图像矩阵
OUT(1:nHW(1),1:nHW(2))=inf;%初始为空白
u0=HW(2)*sin(alpha);u2=HW(1)*cos(alpha);%竖直方向的相关平移量
u1=HW(1)*sin(alpha);u3=HW(2)*cos(alpha);%水平方向的相关平移量
T=[cos(alpha),sin(alpha);-sin(alpha),cos(alpha)];%变换矩阵
for i = 1:nHW(1)%(i,j)是新图像坐标,变换到原图像坐标(x,y)中。          
    for j=1:nHW(2)
        if(alpha>=0 && alpha<=pi/2)
            XY=T*([i;j]-[u0;0]);%保证输出在图像的中心
        elseif(alpha>pi/2 && alpha<=pi)
            XY=T*([i;j]-[u0-u2;-u3]);%保证输出在图像的中心 
        elseif(alpha>pi && alpha<=3*pi/2)
            XY=T*([i;j]-[-u2;-u3-u1]);%保证输出在图像的中心
        elseif(alpha>3*pi/2 && alpha<=2*pi)
            XY=T*([i;j]-[0;-u1]);%保证输出在图像的中心
        end
        x=XY(1);%变换得到的原坐标
        y=XY(2);
        if x>=1 && x<=HW(1) && y>=1 && y<=HW(2) %若变换出的x和y在原图像范围内               
        u = x - floor(x);
        v = y - floor(y); %得到小数部分坐标
        %用原图的四个真实像素点来双线性插值获得“虚”像素的像素值
        OUT(i, j) = J(floor(x), floor(y)) * u * v + ...
                    J(floor(x), ceil(y)) * (1-u) * v + ...
                    J(ceil(x), floor(y)) * u * (1-v) + ...
                    J(ceil(x), ceil(y)) *(1-u) * (1-v);
        end
    end
end
OUT=uint8(OUT);
end

main.m

%主函数
close all;
clear all; 
clc;
%% RGB->灰度图像  
RGB=imread('kris(1).jpg'); %图像读入
I=rgb2gray(RGB); %把 RGB 图像转换成灰度图像
%% 图像的旋转(Image rotation)
alpha=30;%默认>0为逆时针旋转
OUT_2_1=myimrotate(I,alpha);
alpha=120;
OUT_2_2=myimrotate(I,alpha);
alpha=-30;%默认<0为顺时针旋转
OUT_2_3=myimrotate(I,alpha);
alpha=-100;
OUT_2_4=myimrotate(I,alpha);
figure,suptitle('【图像逆时针旋转】');
subplot(1,3,1),imshow(I),axis on,title('原图像');
subplot(1,3,2),imshow(OUT_2_1),axis on,title('图像旋转1');
subplot(1,3,3),imshow(OUT_2_2),axis on,title('图像旋转2');
figure,suptitle('【图像顺时针旋转】');
subplot(1,3,1),imshow(I),axis on,title('原图像');
subplot(1,3,2),imshow(OUT_2_3),axis on,title('图像旋转3');
subplot(1,3,3),imshow(OUT_2_4),axis on,title('图像旋转4');

3.4. Results screenshot
Insert picture description here
Insert picture description here

4. Image mirroring

4.1. Principle There
are two types: one is horizontal mirroring, the other is vertical mirroring.
Set the image height as Height and width as Width;
the horizontal mirroring operation of the image is centered on the vertical central axis of the original image, and the image is divided into left and right parts for symmetrical transformation;
x1=x0
y1=width+1-y0

vertical image The mirror operation is centered on the horizontal central axis of the original image, and the image is divided into upper and lower parts for symmetrical transformation.
x1=height+1-x0
y1=y0

The height and width of the image after mirror transformation are unchanged.
4.2. Algorithm
(1) Get the width and height of the original image.
(2) Enter choice.
(3) Create a new image blank matrix of the same size.
(4) Choose whether to mirror horizontally or vertically according to the choice.
4.3. Code
mymirror.m

%函数mymirror:实现图像镜像
%输入参数:I原图像
%        choice选择水平或垂直镜像
%输出参数:OUT镜像变换后的图像
%使用函数:strcmp(a,b):比较两个字符串是否相等
function OUT=mymirror(I,choice)
J=double(I);
HW=size(J);%获取原图像大小
OUT=zeros(HW);%新建新的图像矩阵
OUT(1:HW(1),1:HW(2))=inf;%初始为空白
for i = 1:HW(1)
    for j=1:HW(2)
        if strcmp(choice,'level')
            OUT(i, j) = J(i, HW(2)+1-j);
        elseif strcmp(choice,'vertical')
            OUT(i, j) = J(HW(1)+1-i, j);
        end
    end
end
OUT=uint8(OUT);
end

main.m

%主函数
close all;
clear all; %#ok<*CLALL>
clc;
%% RGB->灰度图像  
RGB=imread('kris(1).jpg'); %图像读入
I=rgb2gray(RGB); %把 RGB 图像转换成灰度图像
%% 4.图像的镜像变换(Image mirror transformation)
OUT_4_1=mymirror(I,'level');%选择参数'level'即为水平镜像
OUT_4_2=mymirror(I,'vertical');%选择参数'vertical'即为垂直镜像
figure,suptitle('【图像镜像变换】');
subplot(1,3,1),imshow(I),axis on,title('原图像');
subplot(1,3,2),imshow(OUT_4_1),axis on,title('水平镜像');
subplot(1,3,3),imshow(OUT_4_2),axis on,title('垂直镜像');

4.4. Results screenshot
Insert picture description here

5. Image transpose

5.1. Principle
Exchange the x coordinate and y coordinate of the image pixel. The height and width of the image will be changed, and the height and width of the image will be exchanged after transposition.
x1=y0
y1=x0

5.2. Algorithm
(1) Get the width and height of the original image.
(2) Create a new image blank matrix of the same size.
(3) Assign the corresponding point of the original image to the point of the new image.
5.3. Code
mytranspose.m

%函数mytranspose:实现图像转置
%输入参数:I原图像
%输出参数:OUT转置变换后的图像
function OUT=mytranspose(I)
J=double(I);
HW=size(J);%获取原图像大小
OUT=zeros(HW(2),HW(1));%新建新的图像矩阵
OUT(1:HW(2),1:HW(1))=inf;%初始为空白
for i = 1:HW(2)
    for j=1:HW(1)
       OUT(i, j) = J(j,i);
    end
end
OUT=uint8(OUT);
end

main.m

%主函数
close all;
clear all; %#ok<*CLALL>
clc;
%% RGB->灰度图像  
RGB=imread('kris(1).jpg'); %图像读入
I=rgb2gray(RGB); %把 RGB 图像转换成灰度图像
%% 5.图像的转置(Image transpose)
OUT_5_1=mytranspose(I);
figure,suptitle('【图像转置变换】');
subplot(1,2,1),imshow(I),axis on,title('原图像');
subplot(1,2,2),imshow(OUT_5_1),axis on,title('转置变换');

5.4. Results screenshot
Insert picture description here

6. Image cut

Very simple!

J=double(I);
OUT_6=J(500:1000,200:300);
OUT_6=uint8(OUT_6);

7. The overall shear of the image

id=maketform('affine',[1 4 0;2 1 0;0 0 1]');%创建图像整体切变参数结构体
id=imtransform(i,id,'FillValues',255);%实现图像整体切变

(The above other transformations can also be achieved by using maketform , you can try it yourself)

Okay, that’s all for this study, hee hee~~ code code

Guess you like

Origin blog.csdn.net/qq_41315788/article/details/105276063