matlab实现透视变换

您所在的位置:网站首页 动态栏显示 matlab实现透视变换

matlab实现透视变换

2024-03-17 08:08| 来源: 网络整理| 查看: 265

这篇博客讲讲透视变换的原理和实现,透视变换也叫投影变换,仿射变换是透视变换的特例。主要是透视变换能保持“直线性”,即原图像里面的直线,经透视变换后仍为直线。下面给出数学推导:

透视变换矩阵变换公式为:

其中透视变换矩阵:

要移动的点,即源目标点为:

    

另外定点,即移动到的目标点为:

                       

这是一个从二维空间变换到三维空间的转换,因为图像在二维平面,故除以Z,  (X';Y';Z')表示图像上的点:

(X';Y';Z')是二维图像上的的位置左边,其中z=1,表示二维图像 令,展开上面公式,得到一个点的情况:

                                    

4个点可以得到8个方程,即可解出A。

                            

下面代码是上面公式的具体实现,ginput(4)是根据4组点对获取的透视变换矩阵。

clear all; close all; clc; f= imread('6.jpg'); imshow(f); fprintf('Begin to choose the color chip') choose=true; while choose     imshow(f)     dot=ginput(4);       %取四个点,依次是左上,左下,右下,右上     y=[dot(1,1),dot(2,1),dot(3,1),dot(4,1)];        %四个原顶点     x=[dot(1,2),dot(2,2),dot(3,2),dot(4,2)];     plot_x=[x,x(1)];     plot_y=[y,y(1)];     hold on     plot(plot_y,plot_x,'r','LineWidth',2)     hold off     fprintf('Do you satisfy the target you chosen ,press 0 to rechose or press anything else to go\n');     a=input('');     if a~=0         choose=false;     end end w=round(max(dot(:,1))-min(dot(:,1))); h=round(max(dot(:,2))-min(dot(:,2))); %从原四边形获得新矩形高

%这里是新的顶点,我取的矩形,也可以做成其他的形状 %大可以原图像是矩形,新图像是从dot中取得的点组成的任意四边形.:) Y=[1,1,w,w];      X=[1,h,h,1];

B=[X(1),Y(1),X(2),Y(2),X(3),Y(3),X(4),Y(4)]';   %变换后的四个顶点,方程右边的值 %联立解方程组,方程的系数 A=[x(1),y(1),1,0,0,0,-X(1)*x(1),-X(1)*y(1);                 0,0,0,x(1),y(1),1,-Y(1)*x(1),-Y(1)*y(1);    x(2),y(2),1,0,0,0,-X(2)*x(2),-X(2)*y(2);    0,0,0,x(2),y(2),1,-Y(2)*x(2),-Y(2)*y(2);    x(3),y(3),1,0,0,0,-X(3)*x(3),-X(3)*y(3);    0,0 ,0,x(3),y(3),1,-Y(3)*x(3),-Y(3)*y(3);    x(4),y(4),1,0,0,0,-X(4)*x(4),-X(4)*y(4);    0,0,0,x(4),y(4),1,-Y(4)*x(4),-Y(4)*y(4)];%求解变换矩阵的行列式 cut_picture=zeros(h,w); OutPicture=zeros(h,w,3); OutPicture=cast(OutPicture,'uint8');%类型变换为uint8 fa=inv(A)*B; fa=reshape([fa;1],[3,3]);%fa即是变换矩阵 cut=zeros(h+1,w+1); BW=roipoly(f,y,x);%生成所选中区域的二值化图像cut [coordinate_x,coordinate_y]=find(BW==1);%获得选中区域的坐标位置 coordinate=[coordinate_x,coordinate_y,ones(length(coordinate_y),1)];%增加z=1值以便进行左边变换 cut=coordinate*fa;%进行坐标变化 cut(:,1)=cut(:,1)./cut(:,3); cut(:,2)=cut(:,2)./cut(:,3);%获得图像上对应的x,y值 cut=floor(cut+eps); cut(find(cut(:,1:2)==0))=1;%边界为零的点变为1, cut_coordinate=cut(:,1:2);%获得变换后得坐标位置 for k=1:3     img=f(:,:,k);     for i=1:length(coordinate)         cut_picture(cut_coordinate(i,1),cut_coordinate(i,2))=img(coordinate(i,1),coordinate(i,2));     end%讲对应坐标的像素对应     cut_picture=cast(cut_picture,'uint8');     B=zeros(5,5);     D = padarray(cut_picture,[3 3],'replicate','both');%填充像素     for i=4:h+3         for j=4:w+3             if D(i,j)==0                 no_zero=find(D(i-1:i+1,j-1:j+1)~=0);                 [m,n]=size(no_zero);                 if m~=0                      B=D(i-1:i+1,j-1:j+1);                 else                     no_zero=find(D(i-2:i+2,j-2:j+2)~=0);                     [m,n]=size(no_zero);                     if m~=0                         B=D(i-2:i+2,j-2:j+2);                     else                          no_zero=find(D(i-3:i+3,j-3:j+3)~=0);                          B=D(i-3:i+3,j-3:j+3);                     end%以上是对没有被填充的点进行处理                 end                 cut_picture2(i-3,j-3)=median(B(no_zero));%原没有被插值成功的像素点,以周围非零像素的中位数代替;             else                cut_picture2(i-3,j-3)=cut_picture(i-3,j-3);             end         end     end     OutPicture(:,:,k)=cut_picture2; end%这里是对图像三通道进行处理的,便于得到彩色图像 imshow(OutPicture);

实现效果如下

经过变换后

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3