【实践】数字图像处理DIP课程课业打卡实验2 图像几何变换
叮嘟!这里是小啊呜的学习课程资料整理。好记性不如烂笔头,今天也是努力进步的一天。一起加油进阶吧!
一、实验目的
1、通过编程实现图像缩放算法、镜像算法,加深对于该算法的原理和工作过程的理解;
2、理解图像仿射变换的工作原理。了解各种不同形式的仿射变换矩阵。
3、通过编程实现图像旋转、仿射变换。
二、实验内容
1、实现图像水平镜像的代码
参考测试代码:
I =imread('..\..\im\pepper1.bmp');
[im]=mirror_horizontal(I);
imshow(I);figure, imshow(im)
(备注:将执行正确的代码粘贴在此处,核心代码要求有注释)
% I =imread('im\pepper1.bmp');
% [im]=mirror_horizontal(I);
% imshow(I);figure, imshow(im)
function [im]=mirror_horizontal(I)
[M,N,K] = size(I);
J=zeros(M,N,K);
for i = 1:M
for j = 1:N
J(i,N-j+1,:)=I(i,j,:);
end
end
im=uint8(J);
2、实现直角坐标系中的图像缩小算法
要求:
算法实现为函数[im]= rsz_S1 (I,times1,times2)
,其中I为读入的图像矩阵;times1和times2分别为图像竖直方向和水平方向的缩小比例。
参考测试代码:
I =imread('.\han.jpg');
[im]= rsz_S1 (I,0.3,0.5);
imshow(I);figure, imshow(im);
算法伪代码如下:
输入参数:图像矩阵F,行缩小比例k1,列缩小比例k2
输出参数:缩小后的矩阵G
处理:
1、得到原始图像尺寸M、N、d
2、得到新图像尺寸:M2、N2
3、初始化新图像矩阵G
4、对新图像的每一行for i=1:M2
5、对新图像的每一列for j=1:N2
6、计算新图像的i行j列对应原图像的坐标x、y
7、检查x、y的边界条件
8、将原图x、y点的灰度值(或者R、G、B颜色值)赋给新图i、j点
(备注:将执行正确的代码粘贴在此处,核心代码要求有注释)
% I =imread('im\han.jpg');
% [im]= rsz_S1 (I,0.3,0.5);
% imshow(I);figure, imshow(im);
function [im_rsz_l]= rsz_S1 (I,Kr,Kc)
[M,N,K] = size(I);
M2=round(M*Kr);
N2=round(N*Kc);
J=zeros(M2,N2,K);
for i=1:M2
for j=1:N2
x=round(i/Kr);
y=round(j/Kc);
if x>M
x=M;
end
if y>N
y=N;
end
if x<1
x=1;
end
if y<1
y=1;
end
J(i,j,:)=I(x,y,:);
end
end
im_rsz_l=uint8(J);
end
3、实现基于仿射变换的图像变换代码。
要求:
算法实现为函数 [im]=aff(I,T),其中I为读入的图像矩阵;T为仿射变换矩阵。函数文件为aff.m
。
参考测试代码1:
I =imread('..\..\im\peppers.png');
dy=0.5;
A=[1 0 0;dy 1 0;0 0 1];
[im]=aff(I,A) ;
figure,imshow(I);figure, imshow(im);
参考测试代码2:
I =imread('..\..\im\peppers.png');
delta_ang = 30;
q=delta_ang*pi/180;
A=[cos(q) -sin(q) 0;sin(q) cos(q) 0;0 0 1]; %求旋转变换矩阵
[im]=aff(I,A) ;
figure,imshow(I);figure, imshow(im);
算法伪代码如下:
输入参数:图像矩阵F,仿射变换矩阵A
输出参数:变换后的图像矩阵G
处理:
1、求仿射变换A的逆变换矩阵InvA。
2、获得图像尺寸,计算图像的四个顶点的x、y坐标 。
3、根据仿射变换公式:rst=A*[x; y;1],计算图像的四个顶点旋转后的坐标。(x、y为原始图像的坐标,rst(1,:)是旋转后的行坐标,rst(2,:)是旋转后的列坐标)
4、根据四个顶点旋转后的坐标,计算画布扩展后的大小M2、N2,并计算x和y方向的偏移量deltaX、deltaY。初始化新图新G
5、对新图像G的每一行for i=1:M_2
6、对新图像G的每一列for j=1:N_2
6.1 根据仿射变换的逆变换矩阵InvA,计算像素点G(i,j,:)旋转前在原图像F中的坐标x、y(rst=InvA*[i-deltaX ;j-deltaY; 1 ])。
6.2 如果(x>0 && x<=M && y>0 && y<=N),则将F(x,y,:)的像素值采样并且赋给G(i,j,:)
(备注:将执行正确的代码粘贴在此处,核心代码要求有注释)
% 参考测试代码1:
% I =imread('im\peppers.png');
% dy=0.5;
% A=[1 0 0;dy 1 0;0 0 1];
% [im]=aff(I,A) ;
% figure,imshow(I);figure, imshow(im);
%
% 参考测试代码2:
% I =imread('im\peppers.png');
% delta_ang = 30;
% q=delta_ang*pi/180;
% A=[cos(q) -sin(q) 0;sin(q) cos(q) 0;0 0 1]; %求旋转变换矩阵
% [im]=aff(I,A) ;
% figure,imshow(I);figure, imshow(im);
function [im]=aff(I,A)
[M,N,K] = size(I);
InvA=inv(A); %%矩阵求逆;
x1=1;x2=M;x3=M;x4=1;
y1=1;y2=1;y3=N;y4=N;
x=[x1,x2,x3,x4];
y=[y1,y2,y3,y4];
d1=ones(1,4); %%产生一个1*4的矩阵
rst=A*[x;y;d1];
rst=round(rst);
xmin=min(rst(1,:)); %rst(1,:)是四个定点的行坐标x';
xmax=max(rst(1,:));
ymin=min(rst(2,:)); %rst(2,:)是四个定点的列坐标y';
ymax=max(rst(2,:));
if xmin<=0 %%计算行的方向上的偏移量;
deltaX = abs(xmin)+1;
else
deltaX = 0;
end
if ymin<=0
deltaY = abs(ymin)+1;
else
deltaY = 0;
end
M_2 =xmax- xmin+1; %%计算新的图像有几行、几列,并初始化新的图像;
N_2 =ymax- ymin+1;
im = ones(M_2,N_2,K)*-1;
for i=1:M_2
for j=1:N_2
rst = InvA*[i-deltaX j-deltaY 1]';
x=rst(1);
y=rst(2);
x=round(x);
y=round(y);
%%新图像的行列坐标i和j,经过旋转逆变换后的坐标为x、y,
%%如果x、y在原图像的合法范围内,就将原图像x、y处的像素值赋给新图像i、j处的像素;
if(x>0 && x<=M && y>0 && y<=N)
im(i,j,:)=I(x,y,:);
end
end
end
im=uint8(im);
end
Ending!
更多课程知识学习记录随后再来吧!
就酱,嘎啦!
注:
人生在勤,不索何获。