数字图像处理报告:实验1 图像插值,图像几何变换:图像旋转、缩放

 

  • 实验1 图像插值,图像几何变换:图像旋转、缩放
  • 实验主题:

学习双线性插值算法,通过其对图片进行旋转与缩放操作。

  • 实验目的:
  1. 掌握图像插值基本原理和图像几何变换方法。

2.学习使用程序设计环境。

3.掌握双线性插值算法,实现图像的旋转、缩放。

  • 实验平台:
  1. 编程平台:Matlab R2020b
  2. 编程语言:MATLAB
  • 实验要求:

根据选择的图像,编写程序使用双线性插值算法对其进行旋转、缩放处理。

  • 实验代码:
  1. 旋转操作代码:
    function rotation(image,angle)
    img=imread(image);    
    [h,w]=size(img);
    %img2=imrotate(img,45,'bilinear');
    
    theta=angle/180*pi;
    rot=[cos(theta) sin(theta) 0;-sin(theta) cos(theta) 0;0 0 1]; 
    pix1=[1 1 1]*rot;               %变换后图像左上点的坐标
    pix2=[1 w 1]*rot;               %变换后图像右上点的坐标
    pix3=[h 1 1]*rot;               %变换后图像左下点的坐标
    pix4=[h w 1]*rot;               %变换后图像右下点的坐标
    
    height=round(max([abs(pix1(1)-pix4(1))+0.5 abs(pix2(1)-pix3(1))+0.5]));     %变换后图像的高度
    width=round(max([abs(pix1(2)-pix4(2))+0.5 abs(pix2(2)-pix3(2))+0.5]));      %变换后图像的宽度
    imgn=zeros(height,width);
    
    delta_y=abs(min([pix1(1) pix2(1) pix3(1) pix4(1)]));             %取得y方向的负轴超出的偏移量
    delta_x=abs(min([pix1(2) pix2(2) pix3(2) pix4(2)]));             %取得x方向的负轴超出的偏移量
    
    for i=1-delta_y:height-delta_y
        for j=1-delta_x:width-delta_x
            pix=[i j 1]/rot;                                
            %用变换后图像的点的坐标去寻找原图像点的坐标,                                         
            %否则有些变换后的图像的像素点无法完全填充
            float_Y=pix(1)-floor(pix(1)); 
            float_X=pix(2)-floor(pix(2));    
    
            if pix(1)>=1 && pix(2)>=1 && pix(1) <= h && pix(2) <= w     
    
                pix_up_left=[floor(pix(1)) floor(pix(2))];           %四个相邻的点
                pix_up_right=[floor(pix(1)) ceil(pix(2))];
                pix_down_left=[ceil(pix(1)) floor(pix(2))];
                pix_down_right=[ceil(pix(1)) ceil(pix(2))]; 
    
                value_up_left=(1-float_X)*(1-float_Y);               %计算临近四个点的权重
                value_up_right=float_X*(1-float_Y);
                value_down_left=(1-float_X)*float_Y;
                value_down_right=float_X*float_Y;
    
                imgn(i+delta_y,j+delta_x)=value_up_left*img(pix_up_left(1),pix_up_left(2))+ ...
                                            value_up_right*img(pix_up_right(1),pix_up_right(2))+ ...
                                            value_down_left*img(pix_down_left(1),pix_down_left(2))+ ...
                                            value_down_right*img(pix_down_right(1),pix_down_right(2));
            end       
    
        end
    end
    subplot(1,2,1);imshow(img);title('原图像');
    subplot(1,2,2);imshow(uint8(imgn));title(sprintf('双线性插值%d度旋转结果',angle));
    imwrite(uint8(imgn),'rotation.jpg');
    
  2. 缩放操作代码:
    %此为控制台调用程序
    %zoom('a.png',1.5,1)
    
    function zoom( input_img,x,y )
    %input_img为输入图片;x,y为放大倍数
    %[X, map] = imread(...) 读取索引图像X以及与之对应的颜色表到map中。颜色表中的值将归一化到[0,1]之间。
    [I,~] = imread(input_img);
    input_img = imread(input_img);
    
    %获取原图像的长宽
    [width,height,~] = size(I);
    
    %计算新图像的长宽;round()四舍五入
    new_width = round(width*x);
    new_height = round(height*y);
    
    %figure();生成一个新窗口
    figure();
    imshow(input_img);
    title(['原图像(大小: ',num2str(width),'*',num2str(height),')']);
    
    %双线性差值法
    for i = 1:new_width
        for j = 1:new_height
            
            %x,y为放大倍数
            %原来图像的坐标,向下取整
            tempx = floor((i-1)/x);
            tempy = floor((j-1)/y);
            
            %对四条边和四个顶点进行处理,将原坐标转换成调整后的坐标。
            %将(1,j)调整为(1,tempy+1),(i,1)调整为(tempx+1,1)
            if tempx == 0 || tempy == 0 || tempx == width-1 || tempy == height-1
                output_img(1,j,:) = input_img(1,tempy+1,:);
                output_img(i,1,:) = input_img(tempx+1,1,:);
                
            %对其余像素进行处理
            else
                %计算原图像坐标减去新图像坐标的小数部分为其余像素点
                a = (i-1) / x - tempx;
                b = (j-1) / y - tempy;
                
                %保证此图像中坐标最小值为1
                tempx = tempx+1;
                tempy = tempy+1;
                
                %双线性插值计算公式变形
                output_img(i,j,:) = input_img(tempx,tempy,:)*(1-a)*(1-b)+input_img(tempx,tempy+1,:)*(1-a)*b...
                    +input_img(tempx+1,tempy,:)*a*(1-b)+input_img(tempx+1,tempy+1,:)*a*b;
            end
        end
    end
    figure();
    imshow(output_img);
    title(['缩放后的图像(大小: ',num2str(new_width),'*',num2str(new_height),')']);
    imwrite(output_img,'resize2.jpg');
    end
    

     

  • 实验结果:

 

969f680d149044948ce4cf17c19f313e.jpeg图1-1 图像放大结果

e19135c20a66486886ed86b2af94f35d.jpeg 图1-2 图像缩小结果

 

 

 

cd6ff2b4802b4bf595f0fba4ececcd76.jpeg图 1-3 图像旋转结果

 

  • 实验心得:

在这次实验当中,我们学习了双线性插值算法,并在此基础之上将其编程,将其以MATLAB代码的形式进行体现,且更进一步地编写了将图片进行缩放与旋转的代码。在编写过程中,可以发现无论是缩放操作的代码,还是旋转操作的代码,都需要获取图像四个角顶点的坐标,并通过插值算法对其进行操作,将其转化为我们所需要得到的图片的角定点的坐标。

Matlab的官方工具库里其实本身也有对图片进行缩放与旋转的函数:

  1. imresize(image,m,method)函数可以进行对图片的缩放:

image为需要进行处理的图片;m为缩放的倍数(m>1时放大,m<1时缩小);method用于指定插值的方法,可选值为“nearest”(默认)最近邻插值、“bilinear”双线性插值、“bicubic”双三次插值。

  1. imrotate(image,angle,method,bbox)函数可以进行对图片的旋转:

image为需要进行处理的图片;angle为旋转的倍数(输入整数,角度制,默认逆时针);method用于指定插值的方法,可选值为“nearest”(默认)最近邻插值、“bilinear”双线性插值、“bicubic”双三次插值;bbox用于指定返回图像的尺寸,可选值为“loose”(默认)输出足够容纳整个旋转图像的图像B,“crop”输出的图像与输入的图像保持同样的尺寸。

参考博客:

1.MATLAB学习之图片放大缩小(双线性插值法)_CTR_cg的博客-CSDN博客_matlab双线性插值缩小图像

2.Matlab学习笔记——双线性插值旋转图像_HelloAndy_的博客-CSDN博客_matlab双线性插值旋转图像 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kamen Black君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值