matlab实现透视变换 |
您所在的位置:网站首页 › 动态栏显示 › matlab实现透视变换 |
这篇博客讲讲透视变换的原理和实现,透视变换也叫投影变换,仿射变换是透视变换的特例。主要是透视变换能保持“直线性”,即原图像里面的直线,经透视变换后仍为直线。下面给出数学推导: 透视变换矩阵变换公式为: 其中透视变换矩阵: 要移动的点,即源目标点为: 另外定点,即移动到的目标点为: 这是一个从二维空间变换到三维空间的转换,因为图像在二维平面,故除以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 |