精华内容
下载资源
问答
  • Matlab图像几何变换之图像旋转

    万次阅读 多人点赞 2017-12-18 16:48:18
    Matlab图像旋转 旋转的原理如下: 点p0p_0绕坐标原点逆时针方向旋转θ\theta角度得到点p1p_1. 从①②可以得到旋转变换的矩阵公式: [x1y11]\begin{bmatrix}x_1&y_1&1\end{bmatrix}=[x0y01]\begin{b...

                                                               Matlab图像旋转
    ####以坐标原点为中心旋转的原理:
    p0p_0p0绕坐标原点逆时针方向旋转θ\thetaθ角度得到点p1p_1p1.
    这里写图片描述
    从①②可以得到旋转变换的矩阵公式:
    [x1y11]\begin{bmatrix}x_1&y_1&1\end{bmatrix}[x1y11]=[x0y01]\begin{bmatrix}x_0&y_0&1\end{bmatrix}[x0y01][cos(θ)sin(θ)0−sin(θ)cos(θ)0001]\begin{bmatrix}cos(\theta)&sin(\theta)&0\\-sin(\theta)&cos(\theta)&0\\0&0&1\end{bmatrix}cos(θ)sin(θ)0sin(θ)cos(θ)0001

    还可以得到逆运算矩阵公式:
    [x0y01]\begin{bmatrix}x_0&y_0&1\end{bmatrix}[x0y01]=[x1y11]\begin{bmatrix}x_1&y_1&1\end{bmatrix}[x1y11][cos(θ)−sin(θ)0sin(θ)cos(θ)0001]\begin{bmatrix}cos(\theta)&-sin(\theta)&0\\sin(\theta)&cos(\theta)&0\\0&0&1\end{bmatrix}cos(θ)sin(θ)0sin(θ)cos(θ)0001
    ####以任意图形中心点为坐标原点旋转原理:
    这里写图片描述

    从上图可知以任意图形中心点为坐标原点旋转我们需要三步:
    (1)将坐标系Ⅰ变成坐标系Ⅱ
    (2)在坐标系Ⅱ中旋转θ\thetaθ
    (3)将坐标系Ⅱ变成坐标系Ⅰ

    #####(1)将坐标系Ⅰ变成坐标系Ⅱ
    由Figure1得到Figure2可知,变换矩阵为:
    [xⅡyⅡ1]\begin{bmatrix}xⅡ\\yⅡ\\1\end{bmatrix}xy1=[xⅠyⅠ1]\begin{bmatrix}xⅠ\\yⅠ\\1\end{bmatrix}xy1[1000−10−0.5w0.5h1]\begin{bmatrix}1&0&0\\0&-1&0\\-0.5w&0.5h&1\end{bmatrix}100.5w010.5h001=[xⅠ−0.5w−(yⅠ−0.5h)1]\begin{bmatrix}xⅠ-0.5w\\-(yⅠ-0.5h)\\1\end{bmatrix}x0.5w(y0.5h)1

    #####(2)在坐标系Ⅱ中旋转θ\thetaθ
    见上面以坐标原点为中心旋转的原理

    #####(3)将坐标系Ⅱ变成坐标系Ⅰ
    由Figure3得到Figure4可知,变换矩阵为(其实就是(1)中变换矩阵的逆变换):
    [xⅠyⅠ1]\begin{bmatrix}xⅠ\\yⅠ\\1\end{bmatrix}xy1=[xⅡyⅡ1]\begin{bmatrix}xⅡ\\yⅡ\\1\end{bmatrix}xy1[1000−100.5nW0.5nH1]\begin{bmatrix}1&0&0\\0&-1&0\\0.5nW&0.5nH&1\end{bmatrix}100.5nW010.5nH001=[xⅡ+0.5nW−yⅡ+0.5nH1]\begin{bmatrix}xⅡ+0.5nW\\-yⅡ+0.5nH\\1\end{bmatrix}x+0.5nWy+0.5nH1

    从而将三步合起来,可以得到以任意图像中心为坐标原点旋转的变换矩阵:
    [x1y11]\begin{bmatrix}x_1\\y_1\\1\end{bmatrix}x1y11=[x0y01]\begin{bmatrix}x_0\\y_0\\1\end{bmatrix}x0y01[1000−10−0.5w0.5h1]\begin{bmatrix}1&0&0\\0&-1&0\\-0.5w&0.5h&1\end{bmatrix}100.5w010.5h001[cos(θ)sin(θ)0−sin(θ)cos(θ)0001]\begin{bmatrix}cos(\theta)&sin(\theta)&0\\-sin(\theta)&cos(\theta)&0\\0&0&1\end{bmatrix}cos(θ)sin(θ)0sin(θ)cos(θ)0001
    [1000−100.5nW0.5nH1]\begin{bmatrix}1&0&0\\0&-1&0\\0.5nW&0.5nH&1\end{bmatrix}100.5nW010.5nH001=[x0y01]\begin{bmatrix}x_0\\y_0\\1\end{bmatrix}x0y01[cos(θ)−sin(θ)0sin(θ)cos(θ)0−0.5wcos(θ)−0.5hsin(θ)+0.5nW−0.5wsin(θ)+0.5hcos(θ)+0.5nH1]\begin{bmatrix}cos(\theta)&-sin(\theta)&0\\sin(\theta)&cos(\theta)&0\\-0.5wcos(\theta)-0.5hsin(\theta)+0.5nW&-0.5wsin(\theta)+0.5hcos(\theta)+0.5nH&1\end{bmatrix}cos(θ)sin(θ)0.5wcos(θ)0.5hsin(θ)+0.5nWsin(θ)cos(θ)0.5wsin(θ)+0.5hcos(θ)+0.5nH001

    它的逆变换为:
    [x0y01]\begin{bmatrix}x_0\\y_0\\1\end{bmatrix}x0y01=[x1y11]\begin{bmatrix}x_1\\y_1\\1\end{bmatrix}x1y11[1000−10−0.5nW0.5nH1]\begin{bmatrix}1&0&0\\0&-1&0\\-0.5nW&0.5nH&1\end{bmatrix}100.5nW010.5nH001[cos(θ)−sin(θ)0sin(θ)cos(θ)0001]\begin{bmatrix}cos(\theta)&-sin(\theta)&0\\sin(\theta)&cos(\theta)&0\\0&0&1\end{bmatrix}cos(θ)sin(θ)0sin(θ)cos(θ)0001
    [1000−100.5w0.5h1]\begin{bmatrix}1&0&0\\0&-1&0\\0.5w&0.5h&1\end{bmatrix}100.5w010.5h001=[x0y01]\begin{bmatrix}x_0\\y_0\\1\end{bmatrix}x0y01[cos(θ)sin(θ)0−sin(θ)cos(θ)0−0.5nWcos(θ)+0.5nHsin(θ)+0.5w−0.5nWsin(θ)−0.5nHcos(θ)+0.5h1]\begin{bmatrix}cos(\theta)&sin(\theta)&0\\-sin(\theta)&cos(\theta)&0\\-0.5nWcos(\theta)+0.5nHsin(\theta)+0.5w&-0.5nWsin(\theta)-0.5nHcos(\theta)+0.5h&1\end{bmatrix}cos(θ)sin(θ)0.5nWcos(θ)+0.5nHsin(θ)+0.5wsin(θ)cos(θ)0.5nWsin(θ)0.5nHcos(θ)+0.5h001

    ####Matlab编程实现
    #####(1)Matlab自带函数实现图像任意角度旋转
    ######旋转函数介绍:
    B=imrotate(A,angle,method, ‘crop’)
      angle   :旋转角度,单位为度,角度为正值时逆时针旋转
    method :该可选参数为imrotate()指定插值方法
    ‘crop’:裁剪旋转后增大的图像

    clc                                 
    I=imread('potted-plantsk.jpg');
    figure,imshow(I);
    title('srcImage');
    I1=imrotate(I,30);                  %旋转30°
    I2=imrotate(I,30,'crop');           %旋转30°,并剪切图像,使得到的图像和原图像大小一致
    I3=imrotate(I,30,'bilinear','crop');%双线性插值法旋转30°,并剪切图像,使得到的图像和原图像大小一致
    figure,imshow(I1);
    title('I1');
    figure,imshow(I2);
    title('I2');
    figure,imshow(I3);
    title('I3');
    

    程序运行结果如下:
    这里写图片描述

    #####(2)自编myimrotate()函数实现图像任意角度旋转

    function [ A ] = myimrotate(B,degree)                                 %定义旋转函数,degree为要旋转的角度
    [r,c,d]=size(B);                                                      %获取输入图像B的行r、列c和通道数d,为了旋转彩色图像所以有必要得到通道数d
    nH=round(r*abs(cosd(degree))+c*abs(sind(degree)));                    %旋转图像后得到的新高度,“round()函数四舍五入“
    nW=round(c*abs(cosd(degree))+r*abs(sind(degree)));                    %旋转图像后得到的新宽度
    A=zeros(nH,nW,d);                                                     %定义生成目标图像的行列以及通道数
    M1=[1 0 0;0 -1 0;-0.5*nW 0.5*nH 1 ];                                  %坐标系变换矩阵M1
    M2=[cosd(degree) -sind(degree) 0;sind(degree) cosd(degree) 0;0 0 1];  %角度旋转变换矩阵M2,我用的是顺时针方向
    M3=[1 0 0;0 -1 0;0.5*c 0.5*r 1];                                      %坐标系变换矩阵M3
        for i=1:nW
            for j=1:nH
                temp=[i j 1]*M1*M2*M3;                                    %得到旋转后的矩阵temp
                y=temp(1,2);                                              %y取矩阵temp的第一行第二列,y对应j,为高度
                x=temp(1,1);                                              %x取矩阵temp的第一行第一列,x对应i,为宽度
                y=round(y);                                               %y四舍五入取整
                x=round(x);                                               %x四舍五入取整
               if(x>=1&&x<=c)&&(y>=1&&y<=r)                               %判断的得到的(x,y)点是否在原图像上
                   A(j,i,:)=B(y,x,:);                                     %将原图像的像素点赋值给对应的旋转后图像上的点
               end                                                        %(”有人疑惑为啥不是A(i,j,:)=B(x,y,:);因为i,x对应的是列,即宽,而j,y对应的是行,即高“),我这里以x为横坐标,y为竖向纵坐标
            end
        end
    end
    

    调用函数:

    clc                                 
    I=imread('potted-plantsk.jpg');
    figure,imshow(I);
    title('srcImage');
    I1=myimrotate(I,30);     %调用myimrotate()函数旋转30° 
    I2=myimrotate(I,-90);     %调用myimrotate()函数旋转-90°
    figure,imshow(uint8(I1));
    title('旋转30°:I1');
    figure,imshow(uint8(I2));
    title('旋转-90°:I2');
    

    程序运行结果:
    这里写图片描述

    补充一下:
    sin/cos/tan                     三角函数,角度单位为弧度
    asin/acos/atan                反三角函数,角度单位为弧度

    sind/cosd/tand               三角函数,角度单位为度
    asind/acosd/atand          反三角函数,角度单位为度

    补充:坐标系平移推导

    在这里插入图片描述

    展开全文
  • 本文介绍了图像旋转的基本原理MATLAB实现,在不借助MATLAB自带函数的情况下,自己书写了实现图像旋转步骤的几个函数,使用的插值方法为双线性插值。

    1.图像旋转的原理

    1.1.旋转矩阵

    旋转一幅图像(假设这幅图像大小是矩形的),当然应该从像素点(pixels)开始,在直角坐标系中,对点x0=[a0b0]x_0=\begin{bmatrix}a_0\\b_0\\ \end{bmatrix}逆时针旋转角度θ\thetax1=[a1b1]x_1=\begin{bmatrix}a_1\\b_1\\ \end{bmatrix}的变换公式为
    x1=[cosθsinθsinθcosθ]x0x_1=\begin{bmatrix}cos\theta &amp; -sin\theta \\ sin\theta &amp; cos\theta\\ \end{bmatrix}x_0
    那么对图像上的每个点调用这个旋转公式,将旧图像像素点的RGB值搬移到新图像像素点,就可以将图像旋转到任意位置。
    但是问题来了,显示屏的像素点是有限的,这意味着显示在显示屏上的像素点坐标必须是整数,旋转过后的图像的每个像素点坐标难免有非整数的情况,那么这种情况下我们怎么处理呢?
    我们不妨假设逆时针旋转θ\theta旋转后的图形上所有的像素点都是整点,对于旋转后的图形的每个像素点x1x_1,求旋转前图形的对应像素点的坐标x0x_0,取ω=θ\omega=-\theta为逆旋转角度,则旋转后的像素点和旋转前的像素点的对应关系为:
    x0=[cosωsinωsinωcosω]x1x_0=\begin{bmatrix}cos\omega &amp; -sin\omega \\ sin\omega &amp; cos\omega\\ \end{bmatrix}x_1
    此时x0x_0不一定为整点,x0x_0的像素值需要做一定的近似。近似的方法有最近邻插值、双线性插值等等,在这里我们就介绍比较实用且不是很复杂的双线性插值,该插值方法不会产生明显失真现象。
    对于像素点的旋转坐标函数编写如下:
    坐标旋转变换函数:rot.m

    function y=rot(p,angle)
    %p=[x,y]为角度制
    angle=angle*pi/180;%角度制输入进行计算
    y=[cos(angle) -sin(angle);sin(angle) cos(angle)]*p';
    end
    

    1.2.双线性插值

    对于x和y坐标非整数的非整点xpx_p,假设它周围的四个整点坐标分别为x11,x12,x21,x22x_{11},x_{12},x_{21},x_{22}(构成一个矩形)。假设第一维度是x坐标,第二维度是y坐标。则x11(1)=x21(1)xp(1)x12(1)=x22(1)x_{11}(1)=x_{21}(1)≤x_p(1)≤x_{12}(1)=x_{22}(1)
    x11(2)=x12(2)xp(2)x21(2)=x22(2)x_{11}(2)=x_{12}(2)≥x_p(2)≥x_{21}(2)=x_{22}(2)
    显然,即使xpx_p为整点,仍然存在这样的四个点x11,x12,x21,x22x_{11},x_{12},x_{21},x_{22}使得上式成立。
    在下图中,P为非整点,存在4个整点Q12,Q11,Q22,Q21Q_{12},Q_{11},Q_{22},Q_{21}将P点包围在其中,设纵向比例系数β=yy2y1y2\color{blue}\beta=\frac{y-y_2}{y_1-y_2},横向比例系数α=xx1x2x1\color{blue}\alpha=\frac{x-x_1}{x_2-x_1}颜色函数F(P)F(P)在四个整点处的值分比为F12,F11,F22,F21F_{12},F_{11},F_{22},F_{21},则P点的函数值
    FP=β[(1α)F11+αF21]+(1β)[(1α)F12+αF22]F_P=\beta[(1-\alpha)F_{11}+\alpha F_{21}]+(1-\beta)[(1-\alpha)F_{12}+\alpha F_{22}]写成矩阵的形式即为:
    FP=[1αα][F11F12F21F22][β1β]F_P=\begin{bmatrix}1-\alpha &amp; \alpha \end{bmatrix}\begin{bmatrix} F_{11} &amp; F_{12} \\[2ex] F_{21} &amp; F_{22} \end{bmatrix}\begin{bmatrix}\beta \\[2ex] 1-\beta \end{bmatrix}
    在这里插入图片描述
    对于灰度图像,F(P)F(P)是一维函数,对于RGB图像,F(P)=[FR(P)FG(P)FB(P)]F(P)=\begin{bmatrix}F_R(P) \\F_G(P) \\ F_B(P) \end{bmatrix}
    由于该公式较为复杂,可以单独编写双线性插值函数,输入为一个任意点坐标,和图像每个点的像素;输出为该点进行双线性插值后的颜色函数值。但需要主要的是,若给采集的4个周围整点,有其中一个超出了图像边界,考虑到图像边界一般为白色,则以白色为替代。检测点是否在画布内只需要条件判断语句就够了。
    检测是否在画布内的判断程序:isinrect.m

    function y=isinrect(plt,rect)
    if plt(1)>=rect(1) && plt(1)<=rect(2) && plt(2)>=rect(3) && plt(2)<=rect(4)
        y=true;
    else
        y=false;
    end
    

    双线性插值函数:linear_interp.m

    function y=linear_interp(p,img)
        %p为需要双线性插值的点坐标(向量)
        x=p(1);y=p(2);
        m=size(img,1);n=size(img,2);
        x1=floor(x);x2=ceil(x);y1=floor(y);y2=ceil(y);%[x,y]四周的四个整点
        left=x-x1;%距左边线距离
        bottom=y-y1;%距底线距离
        plt=[x1,y2;x2,y2;x1,y2;x2,y2];
        img_rect=[1,m,1,n];%原图像的矩形框
        pix_rect=zeros(1,4,3);
        for t=1:4
            if isinrect(plt(t,:),img_rect)
                for color=1:3
                    pix_rect(1,t,color)=img(plt(t,1),plt(t,2),color);
                end
            else
                pix_rect(1,t,:)=255;%背景色为白色
            end
        end
        pixels=zeros(1,3);%保存该点的三原色的三个像素
        pix_rect=reshape(pix_rect,2,2,3);
        for color=1:3
            pixels(color)=[bottom,1-bottom]*pix_rect(:,:,color)*[1-left;left];%双线性像素插值
        end
        y=pixels;
    end
    

    1.3.像素点匹配

    假设图像的点都是整点的情况下,新图像是一个旋转后的矩形,此时需要给新图像定界使得新图像能够包括在一个旋转角度为0°大矩形中。
    在这里插入图片描述
    left=max(x1,x2,x3,x4),right=min(x1,x2,x3,x4)left=max(x_1,x_2,x_3,x_4),right=min(x_1,x_2,x_3,x_4)
    top=max(y1,y2,y3,y4),bottom=min(y1,y2,y3,y4)top=max(y_1,y_2,y_3,y_4),bottom=min(y_1,y_2,y_3,y_4)

    filename='足球.bmp';%文件的完整路径名
    img=imread(filename);%导入图像
    % subplot(121)
    % imshow(img)%展示原图像
    m=size(img,1);n=size(img,2);%统计图像的长和宽
    plt=[0,0;m,0;m,n;0,n];%四个顶点坐标
    for t=1:4
        plt(t,:)=ceil(rot(plt(t,:),rot_angle));%三个顶点进行旋转坐标变换
    end
    %新的四个点坐标的x和y边界值
    left=min(plt(:,1));right=max(plt(:,1));
    bottom=min(plt(:,2));top=max(plt(:,2));
    M=right-left;N=top-bottom;%获取新的图像大小
    new_img=255*ones(M,N,3);%创建新画布
    left=min(plt(:,1));right=max(plt(:,1));
    bottom=min(plt(:,2));top=max(plt(:,2));
    

    定界完成后,只需要求出新图像定界后每个像素点对应的原图像像素点坐标,并按照双线性插值的方法取得像素值,对应到新图像点中,即可求出每个新图像点的像素值,旋转步骤即完成。要注意的是,如果双线性插值遇到了原图像界限外的点,为保证程序不出错,可以直接将界限外的点置为0(相当于非常弱的边缘虚化效果),或者直接将最外层边界整点进行最近邻插值(这种分段算法实现会略微麻烦)。主函数文件代码如下:
    主函数文件:img_process.m

    function img_process(rot_angle)
    close all
    filename='足球.bmp';%文件的完整路径名
    img=imread(filename);%导入图像
    figure
    imshow(img)%展示原图像
    m=size(img,1);n=size(img,2);%统计图像的长和宽
    plt=[0,0;m,0;m,n;0,n];%四个顶点坐标
    for t=1:4
        plt(t,:)=ceil(rot(plt(t,:),rot_angle));%三个顶点进行旋转坐标变换
    end
    %新的四个点坐标的x和y边界值
    left=min(plt(:,1));right=max(plt(:,1));
    bottom=min(plt(:,2));top=max(plt(:,2));
    M=right-left;N=top-bottom;%获取新的图像大小
    new_img=255*ones(M,N,3);%创建新画布
    for i=1:M
        for j=1:N
            init_plt=rot([i-1+left,j-1+bottom],-rot_angle);%新图像对应原图像的坐标
            init_plt=init_plt+1;%还原到Matlab坐标系
            new_img(i,j,:)=linear_interp(init_plt,img);
        end
    end
    figure
    imshow(uint8(new_img))%展示旋转后的新图像(底色为白色)
    

    2.实现效果与说明

    将上述标红的4个M文件放在一个文件夹,并更改MATLAB目录为该文件夹,并在该文件夹添加一张名为“足球.bmp”的位图文件,在命令行输入img_process(30)即可将该图像旋转30°显示,显示效果如下:

    原图像 新图像(旋转30°)
    原图像 在这里插入图片描述

    本文从原理上用MATLAB代码实现了图像的旋转,如果想直接调用MATLAB的函数,请查看imrotate函数的相关说明:
    new_img=imrotate(initial_img,angle,method, ‘crop’)

    • angle:逆时针旋转的角度,是角度值
    • method:该参数为插值方法,其中’bilinear’为双线性插值,可选
    • crop:旋转后增大图像
    展开全文
  • 图像旋转matlab

    2011-04-02 11:56:59
    matlab图像旋转的原始代码,有助于学习图像变换的基本原理
  • 【数字图像处理】MATLAB实现图像旋转

    万次阅读 多人点赞 2018-11-17 22:33:28
    图像旋转原理 图像旋转的本质利用的是向量的旋转。 矩阵乘法的实质是进行线性变换,因此对一个向量进行旋转操作也可以通过矩阵和向量相乘的方式进行。 【ps:线性代数的本质这个视频很直观地解释了各种线性代数...

    前言

    上节课学习了实现图像旋转的原理,下课后用matlab实现了一下图像旋转的功能,这里做个记录。


    图像旋转原理

    图像旋转的本质利用的是向量的旋转。

    矩阵乘法的实质是进行线性变换,因此对一个向量进行旋转操作也可以通过矩阵和向量相乘的方式进行。

    【ps:线性代数的本质这个视频很直观地解释了各种线性代数运算的实质,链接:https://www.bilibili.com/video/av6731067

    因为图像都是通过二维矩阵存放的(单通道),所以对图像进行旋转时要先设定一个像素作为旋转轴,然后其他的像素位置可以看作从旋转轴出发的向量。

    如图中间的红点为旋转轴,则旋转的实质就是将图中的各个向量进行旋转,然后将旋转前的位置的像素值赋值给旋转后的位置的像素值。

    假设有二维向量v = [x ; y],若要进行逆时针旋转角度a。则旋转矩阵R为

    旋转后的向量v2 = R * v。

    在正式处理过程中可以这么表示,原像素位置记为p,中心点记为c,旋转后像素位置记为pp

    则有(pp - c) = R*(p - c)

    pp = R*(p-c) + c


    代码实现过程

    一共写了三份代码,依次改进了旋转图像的效果。

    第一次实现代码

    第一次实现代码的思路是正向的思路,也就是把原图进行向量的旋转,找到旋转后的向量的位置,然后将原图的像素值赋值过去即可。

    代码实现

    % 读入图片
    im = imread('1.jpg');
    
    % 求出旋转矩阵
    a = 30 / 180 * pi;
    R = [cos(a), -sin(a); sin(a), cos(a)];
    
    % 求出图片大小 ch为通道数 h为高度 w为宽度
    sz = size(im);
    h = sz(1);
    w = sz(2);
    ch = sz(3);
    c = [h; w] / 2;
    
    % 初始化结果图像
    im2 = uint8(zeros(h, w, 3));
    for k = 1:ch
        for i = 1:h
           for j = 1:w
              p = [i; j];
              % round为四舍五入
              pp = round(R*(p-c)+c);
              if (pp(1) >= 1 && pp(1) <= h && pp(2) >= 1 && pp(2) <= w)
                  im2(pp(1), pp(2), k) = im(i, j, k); 
              end
           end
        end
    end
    
    % 显示图像
    figure;
    imshow(im2);

    结果显示

    原图:     旋转后:

    分析:可以看到有这么几个瑕疵,首先是图像的大小和原图一样导致边缘被裁剪了,其次是图像中会出现很多噪声很多杂点,出现杂点的原因是从原图旋转后的像素位置在原图可能找不到,解决方法是用逆向思维,从目标图片反向旋转到原图进行像素查找。

    第二次实现代码

    这次我先算出了旋转后要显示完整图像所需的画布大小,然后像素赋值的顺序反过来,从目标图片反向旋转到原图进行像素查找。此外还要注意,在改变目标画布大小后,图像中心点即旋转轴改变了,要单独进行计算。

    % 读入图片
    im = imread('1.jpg');
    
    % 求出旋转矩阵
    a = 30 / 180 * pi;
    R = [cos(a), -sin(a); sin(a), cos(a)];
    R = R'; % 求出旋转矩阵的逆矩阵进行逆向查找
    
    % 计算原图大小
    sz = size(im);
    h = sz(1);
    w = sz(2);
    ch = sz(3);
    c1 = [h; w] / 2;
    
    % 计算显示完整图像需要的画布大小
    hh = floor(w*sin(a)+h*cos(a))+1;
    ww = floor(w*cos(a)+h*sin(a))+1;
    c2 = [hh; ww] / 2;
    
    % 初始化目标画布
    im2 = uint8(ones(hh, ww, 3)*128);
    for k = 1:ch
        for i = 1:hh
           for j = 1:ww
              p = [i; j];
              pp = round(R*(p-c2)+c1);
              % 逆向进行像素查找
              if (pp(1) >= 1 && pp(1) <= h && pp(2) >= 1 && pp(2) <= w)
                 im2(i, j, k) = im(pp(1), pp(2), k); 
              end
           end
        end
    end
    
    % 显示图像
    figure;
    imshow(im2);

    结果显示

    原图:     旋转后:

    分析:可以看到噪声已经消失,同时显示的也是完整的旋转图像。但是这里的插值方式十分简陋,是直接用四舍五入的,还可以再次改进,通过使用线性插值的方法:https://blog.csdn.net/qq_34586921/article/details/84192850

    第三次代码实现

    和第二次代码实现比起来就是插值方法改变了,其他的都没有改变,插值方法改变后旋转后的图像质量更好了。

    % 读入图片
    im = imread('1.jpg');
    
    % 求出旋转矩阵
    a = 30 / 180 * pi;
    R = [cos(a), -sin(a); sin(a), cos(a)];
    R = R'; % 求出旋转矩阵的逆矩阵进行逆向查找
    
    % 计算原图大小
    sz = size(im);
    h = sz(1);
    w = sz(2);
    ch = sz(3);
    c1 = [h; w] / 2;
    
    % 计算显示完整图像需要的画布大小
    hh = floor(w*sin(a)+h*cos(a))+1;
    ww = floor(w*cos(a)+h*sin(a))+1;
    c2 = [hh; ww] / 2;
    
    % 初始化目标画布
    im2 = uint8(ones(hh, ww, 3)*128);
    for k = 1:ch
        for i = 1:hh
           for j = 1:ww
              p = [i; j];
              pp = (R*(p-c2)+c1);
              mn = floor(pp);
              ab = pp - mn;
              a = ab(1);
              b = ab(2);
              m = mn(1);
              n = mn(2);
              % 线性插值方法
              if (pp(1) >= 2 && pp(1) <= h-1 && pp(2) >= 2 && pp(2) <= w-1)
                 im2(i, j, k) = (1-a)*(1-b)*im(m, n, k) + a*(1-b)*im(m+1, n, k)...
                              + (1-a)*b*im(m, n, k)     + a*b*im(m, n, k);
              end
           end
        end
    end
    
    % 显示图像
    figure;
    imshow(im2);

    结果显示:

    原图:     旋转后: 


    总结

    学习不息,继续加油                  

    展开全文
  • matlab实现图像旋转

    万次阅读 2016-10-07 14:30:30
    要求 图像是彩色的;旋转后,原图像的四个角点应在新图像的四条...原理部分仅仅是代码中所体现的,具体推导过程参看百度文库 图像旋转 下图显示新图像与原图像的长宽关系,注意如果旋转角度是120度,则需要取...

    要求

    图像是彩色的;旋转后,原图像的四个角点应在新图像的四条边上(即新图像的大小是包含原图像旋转后的最小矩形);旋转的角度可以是 0~ 360度;函数的调用形式是 J=myrotate(I,angle);不允许使用 imrotate。

     

    原理

    原理部分仅仅是代码中所体现的,具体推导过程参看 百度文库 图像旋转

     

    下图显示新图像与原图像的长宽关系,注意如果旋转角度是120度,则需要取绝对值,具体参见下面源代码。

     

    下图显示原图像旋转后的点与原图像点的对应关系,以按此公式求得新图像每一点对应的原图像点。

    旋转后,由于图像点可能是非整数,出现像素空洞问题,故需要进行插值法,下面选用最近邻插值法。

     

     

    源代码

    function img_rotate=my_img_rotate_chazhi(img1,angle)
    % 旋转后图像=my_img_rotate(原图像,旋转角度) 0<旋转角度<360
    % 查找新图对应的原图像素点
    % 最邻近点插值方法
    
    [h,w,d]=size(img1);
    radian=angle/180*pi;
    cos_val	= cos(radian);
    sin_val	= sin(radian);
    
    w2=round(abs(cos_val)*w+h*abs(sin_val));
    h2=round(abs(cos_val)*h+w*abs(sin_val));
    img_rotate	= uint8(zeros(h2,w2,3));	%像素是整数
    
    
    for x=1:w2
        for y=1:h2
            x0 = uint32(x*cos_val + y*sin_val -0.5*w2*cos_val-0.5*h2*sin_val+0.5*w);
            y0= uint32(y*cos_val-x*sin_val+0.5*w2*sin_val-0.5*h2*cos_val+0.5*h);    
            
            x0=round(x0);         %最邻近插值
            y0=round(y0);         %最邻近插值
            if x0>0 && y0>0&& w >= x0&& h >= y0
                img_rotate(y,x,:) = img1(y0,x0,:);
            end
        end
    end
    %I = imread('C:\Users\Desktop\love.jpg')
    %I2=my_img_rotate(I,30);
    %figure,imshow(I2);

     

     

     

    展开全文
  • MATLAB实现图像旋转

    千次阅读 2020-01-23 22:15:41
    一、图像旋转原理 图像旋转的本质是向量的旋转。直接看图 向量的旋转很容易理解,在图像旋转中,图像中心到某一像素点就可视作一向量,对该向量进行关于中点的旋转即可对该像素点进行旋转,对所有像素点进行旋转...
  • 文章目录四、matlb的imrotate函数一、图像旋转原理二、使用matlab实现1、思路2、实现代码3、优化1、思路2、代码实现3、使用双线性插值4、matlab自带的imrotate函数 四、matlb的imrotate函数 一、图像旋转原理  ...
  • 图像旋转原理及实现

    万次阅读 多人点赞 2016-01-21 17:57:14
    在一次数字图像处理课中,我接触到了图片旋转的一些原理,当时没完全想明白,课后通过一段时间的学习,终于完成了图片旋转matlab程序。开始觉得应该挺简单的,但终究是纸上谈兵,在实现的过程中遇到很多问题。
  • 基于matlab图像旋转

    千次阅读 2013-06-27 16:10:55
     用matlab 的imrotate 函数对二值图像旋转时,不能实现功能,自己写了个旋转程序。旋转的基本原理如下:对原图中的点A(X0,Y0),旋转到(X1,Y1), 旋转角度为alpha,则 X1=X0*cos(alpha) +Y0*sin(alpha); Y1=-X0*...
  • MATLAB--数字图像处理 图像旋转

    千次阅读 2019-09-08 10:59:25
    图像旋转 图像的旋转其实矩阵的旋转,而整个矩阵的旋转,则可以看出单个坐标的旋转。也就是说,只有我们知道了单个坐标旋转后的坐标,那么就很好得出旋转之后的图像了。这里我们假定旋转后的图像大小不变哈。 对于看...
  • 本文采用基本原理图像进行旋转 使用MATLAB语言, 基本推导过程可参考https://blog.csdn.net/qq_42655135/article/details/88601342 一、程序 clear;close all;clc; gray=rgb2gray(imread('test1.jpg'));%转化...
  • 图像旋转图像的旋转其实矩阵的旋转,而整个矩阵的旋转,则可以看出单个坐标的旋转。也就是说,只有我们知道了单个坐标旋转后的坐标,那么就很好得出旋转之后的图像了。这里我们假定旋转后的图像大小不变哈。对于看...
  • 图像旋转(matlab)

    2017-03-09 11:01:39
    原理 没啥好说的 就一个矩阵乘法。浏览器没装latex,所以意思一下A = [cos(alpha) sin(alpha) 0; -sin(aplha) cos(alpha) 0; 0 0 1]; newij = A*[i;j;1];  就是坐标转化公式 newij 为新坐标,i,j 为旧坐标 ...
  • 目录:概述图像基本变换仿射变换原理python实现一、概述图像的几何变换主要包括:平移、缩放、旋转、仿射、透视等等。图像变换是建立在矩阵运算基础上的,通过矩阵运算可以很快的找到不同图像的对应关系。理解变换的...
  • VC++ matlab图像处理

    2013-09-15 15:17:54
    12.4.3 图像旋转 12.4.4 图像剪切 12.5 空间变换 12.5.1 仿射变换( affine transformation ) 12.5.2 透视变换 (Perspective Transformation) 12.5.3 空间变换的 MATLAB 函数 12.5.4 空间变换实例 12.6 图像...
  • 本人在MATLAB对某个课题进行研究的过程中,意外发现了用最简单的弧线和直线作螺旋图像的方法。本文的主要想讲以下内容:一、是记录和展示这个有趣的现象,用数据可视化展现数学之美二、是以这个现象为例展现一下对...
  • Matlab:图像平移算法的原理实现,缺陷分析及优化 文章目录1.怎么样确定平移之后新的图片的模板呢?2.图像中的坐标平移转换是如何实现的呢?在实现平移算法之前,我们首先来了解平移算法的背景知识:那么我们如何将...
  • 目录图像平移、旋转、缩放、镜像的MATLAB实现(仿照MATLAB内置函数实现)原理代码平移镜像缩放与旋转辅助工具图像预处理最近邻元法双线性内插法三次内插法旋转缩放提升运行效率的一些尝试实验结果 图像平移、旋转、...
  • 【数字图像处理知识】基础算法的Matlab 1)MATLAB实现 密码:94a2 2)Matlab程序 + 文档说明 3)总共64个 实现60个(具体见文档): Matlab程序索引(60个) 一、 图像几何变换 ...图像旋转(Ror...
  • MATLAB图形图像处理

    热门讨论 2011-01-03 12:20:11
    12.4.3 图像旋转 12.4.4 图像剪切 12.5 空间变换 12.5.1 仿射变换( affine transformation ) 12.5.2 透视变换 (Perspective Transformation) 12.5.3 空间变换的 MATLAB 函数 12.5.4 空间变换实例 12.6 图像...
  • matlab双线性插值实现彩色图像的平移、旋转、缩放、镜像原理概述代码平移镜像缩放旋转结果原图平移(向X正方向、Y正方向50个距离单位)镜像(左右、上下)缩放(查看分辨率可知是否成功)旋转(45°) 原理概述 图像...
  • 以任意图形中心点为坐标原点旋转原理: 从上图可知以任意图形中心点为坐标原点旋转我们需要三步: (1)将坐标系Ⅰ变成坐标系Ⅱ (2)在坐标系Ⅱ中旋转θθ角 (3)将坐标系Ⅱ变成坐标系Ⅰ **(1)将坐标系Ⅰ变成坐标系Ⅱ ...
  • 一、实验名称图像的几何变换二、实验目的1.熟悉MATLAB软件的使用。2.掌握图像几何变换的原理及数学运算。...得到该图像的垂直错切图像四、实验仪器与设备Win10 64位电脑MATLAB2017a五、实验原理...
  • 实验一 MATLAB图像处理实验报告 实 验 报告 课程名称 何变换 数字图像处理 实验名称 图像的几 姓 名 吴征宇 学 号 3101110002 专业班级 实验日期 20XX 年10 月 18日 成绩 指导教师 实验目的 掌握图像平移缩放旋转与...

空空如也

空空如也

1 2 3 4
收藏数 74
精华内容 29
关键字:

matlab图像旋转原理

matlab 订阅