您的位置:首页 > 编程语言 > MATLAB

pdf417项目:matlab利用仿射变换实现图片的旋转变换

2016-11-11 17:03 351 查看
主要是旋转二维码,需要四个顶点的坐标:

function [ rotatedGraph ] = rotate(x,y,I)

% 得到x数组坐标为:x1,x2,x3,x3,得到y数组坐标为y1,y2,y3,y4,并传入需要旋转的二值化之后的图片

% 输出就是旋转之后的图片

% 第一个点是参考点

% 定义2个变量存储另外一个点的坐标  

% 计算三个距离 

s2 = ( x(1) - x(2) )^2 + ( y(1) - y(2) )^2  ;

s3 = ( x(1) - x(3) )^2 + ( y(1) - y(3) )^2  ;

s4 = ( x(1) - x(3) )^2 + ( y(1) - y(3) )^2  ;

if(s2 < s3 & s3 < s4)

     ix = x(3); iy = y(3);

 elseif (s3 < s2 & s2 < s4)

     ix = x(2); iy = y(2);

else 

     ix = x(4); iy = y(4);

end

k = (y(1) - iy) / (x(1) - ix);  %k是斜率,也就是倾斜角的tan值

ang = atan(k)*180/pi;

rotatedGraph = imagerotate(binaryzationGraph,ang,0);  %参数0是图片(必须二值化之后的),参数2是角度,参数3暂时为0,不用管

end

关于最后一行调用的imagerotate的函数实现(matlab里面有相关的封装好的函数,不过这里是自己实现的)

function I=imagerotate(I1,angle,isSameSize) %必须是二值化之后的

%功能:实现图像的旋转变换

%angle---旋转角度

%isSameSize---取0 尺寸变大 取1 不变

[m,n]=size(I1);

rad=angle*pi/180;   %转化成弧度制

oldWidth=m;

oldHeight=n;

if(isSameSize==0)

    %计算原图像中的四个角的坐标(以图像中心为坐标系原点)

    oldX1=-(oldWidth-1)/2;

    oldY1=(oldHeight-1)/2;

    oldX2=(oldWidth-1)/2;

    oldY2=(oldHeight-1)/2;

    oldX3=-(oldWidth-1)/2;

    oldY3=-(oldHeight-1)/2;

    oldX4=(oldWidth-1)/2;

    oldY4=-(oldHeight-1)/2;

    %计算新图像的4个角的坐标(以图像中心为坐标系原点),自己在纸上画一下就能看懂这个几何关系啦,文字不好说明,反正就是点跟着原点转

    newX1=oldX1*cos(rad)+oldY1*sin(rad);

    newY1=-oldX1*sin(rad)+oldY1*cos(rad);

    newX2=oldX2*cos(rad)+oldY2*sin(rad);

    newY2=-oldX2*sin(rad)+oldY2*cos(rad);

    newX3=oldX3*cos(rad)+oldY3*sin(rad);

    newY3=-oldX3*sin(rad)+oldY3*cos(rad);

    newX4=oldX4*cos(rad)+oldY4*sin(rad);

    newY4=-oldX4*sin(rad)+oldY4*cos(rad);

    %计算旋转后的图像的宽度和高度

    newWidth=round(max(abs(newX1-newX4),abs(newX2-newX3))+0.5);

    newHeight=round(max(abs(newY1-newY4),abs(newY2-newY3))+0.5);

    %旋转前中心坐标

    a=round((oldWidth-1)/2+0.5);

    b=round((oldHeight-1)/2+0.5);

    %旋转后中心坐标

    c=round((newWidth-1)/2+0.5);

    d=round((newHeight-1)/2+0.5);

else

    a=round((oldWidth-1)/2+0.5);

    b=round((oldHeight-1)/2+0.5);

    c=a;

    d=b;

    newWidth=oldWidth;

    newHeight=oldHeight;

end

%---------?????????????

t1=[1 0 0;0 1 0;-a -b 1];

t2=[cos(rad) -sin(rad) 0;sin(rad) cos(rad) 0;0 0 1];

t3=[1 0 0;0 1 0;c d 1];

T=t1*t2*t3;

%构造新坐标系x和y的值

tx=ones(newWidth,newHeight)*255;

ty=ones(newWidth,newHeight)*255;

for i=1:newWidth

    for j=1:newHeight

        tx(i,j)=i;

        ty(i,j)=j;

    end

end

T

%-----------调用Matlab的maketform 和 tforminv 函数-------%

% tform=maketform('affine',T);

% [w z]=tforminv(tform,tx,ty); %反向坐标值,得到新坐标 一一对应 的旧坐标

%--------------------------------------------------------%

%-----------自己实现---------------------------------%

tform = inv(T)

for i=1:newWidth

    for j=1:newHeight

        s = [tx(i,j), ty(i,j) 1] * tform;

        w(i,j) = s(1);

        z(i,j) = s(2);

    end

end

%-----------自己实现---------------------------------%

I=double(zeros(newWidth,newHeight));

%给新图像各像素点赋值

for i=1:newWidth

    for j=1:newHeight

        S_x=w(i,j);

        S_y=z(i,j);

        if(S_x>=m-1||S_y>=n-1||double(uint16(S_x))<=0||double(uint16(S_y))<=0) 

            I(i,j)=255; %不在原图像上,变成白色

        else

            if (S_x/double(uint16(S_x))==1.0&S_y/double(uint16(S_y))==1.0)

                I(i,j)=I1(uint16(S_x),uint16(S_y));%整数点

            else

                I(i,j)=I1(uint16(S_x),uint16(S_y));%或许应该取周围的像素点的一个加权平均

            end

        end

    end

end

%给新图像各像素点赋值

%for i=1:newWidth

%    for j=1:newHeight

%        S_x=w(i,j);

%        S_y=z(i,j);

%        if(S_x>=m-1||S_y>=n-1||double(uint16(S_x))<=0||double(uint16(S_y))<=0) 

%            I(i,j)=255; %不在原图像上

%        else

%            if (S_x/double(uint16(S_x))==1.0&S_y/double(uint16(S_y))==1.0)

%                I(i,j)=I1(uint16(S_x),uint16(S_y));%整数点

%            else

%                %不是整数点

%                a=double(uint16(S_x));

%                b=double(uint16(S_y));

%                u=S_x-a;

%                v=S_y-b;

%                x11=double(I1(a,b));

%                x12=double(I1(a,b+1));

%                x21=double(I1(a+1,b));

%                x22=double(I1(a+1,b+1));

%                I(i,j)=uint8((1-u)*(1-v)*x11+(1-u)*v*x12+u*(1-v)*x21+u*v*x22);

%            end

%        end

%    end

%end

end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: