法一:直接曲线拟合
f=imread('C:\Users\win8\Desktop\t1.bmp');
XY=size(f);
xy=[];
for i=1:XY(1,1)
for j=1:XY(1,2)
if f(i,j)==0&f(i,j+1)~=0
xy=[xy;j,i];
end
end
end
x=xy(:,1)-520;
y=553-xy(:,2);
xy2=[x,y];
xy3=sortrows(xy2,2);
x=xy3(:,2);
y=xy3(:,1);
p=polyfit(x,y,20);
x1=min(x):0.1:max(x);y1=polyval(p,x1);
[x,y,z]=cylinder(y1,30);
mesh(x,y,z)
法二:分段拟合
f=imread('C:\Users\win8\Desktop\t1.bmp');
XY=size(f);
xy=[];
for i=1:XY(1,1)
for j=1:XY(1,2)
if f(i,j)==0&f(i,j+1)~=0
xy=[xy;j,i];
end
end
end
x=xy(:,1)-520;
y=553-xy(:,2);
xy2=[x,y];
xy3=sortrows(xy2,2);
a1=xy3(1:243,1:2);
a1x=a1(:,1);a1y=a1(:,2);
a1p=polyfit(a1y,a1x,1);
yy=xy3(:,2);
m1=a1p(1,1);n1=a1p(1,2);
a2=xy3(244:297,1:2);
a2x=a2(:,1);a2y=a2(:,2);
a2p=polyfit(a2y,a2x,3);
m2=a2p(1,1);n2=a2p(1,2);k2=a2p(1,3);l2=a2p(1,4);
a3=xy3(298:335,1:2);
a3x=a3(:,1);a3y=a3(:,2);
a4=xy3(336:384,1:2);
a4x=a4(:,1);a4y=a4(:,2);
a4p=polyfit(a4y,a4x,4);
m4=a4p(1,1);n4=a4p(1,2);k4=a4p(1,3);l4=a4p(1,4);h4=a4p(1,5);
g=(min(a1y)<=yy&yy<=max(a1y)).*(m1*yy+n1)+(min(a2y)<=yy&yy<=max(a2y)).*(m2*yy.^3+n2*yy.^2+k2*yy+l2)+(min(a3y)<=yy&yy<=max(a3y))*max(a3(:,1))+(min(a4y)<=yy&yy<=max(a4y)).*(m4*yy.^4+n4*yy.^3+k4*yy.^2+l4*yy+h4);
[x,y,z]=cylinder(g,30);
mesh(x,y,z)
图中的花瓶平面图是对称结构,可以想象花瓶的立体图是由花瓶平面的对称线旋转而得的旋转体。先以花瓶底部中心为坐标原点,坐标原点正右为轴,坐标原点正上为轴建立直角坐标系,继而求出花瓶一侧(右侧)全部边缘点的坐标。因为边缘点足够密集且数量较多,更适宜采用曲线拟合而不是插值的方法作出曲线近似表达式。利用软件中函数根据近似表达式作出花瓶三维立体图。为使得立体图的直观效果更好,可进一步建立右边缘曲线的分段函数表达式进行拟合。
A=imread('t1.bmp');%将图片的数据导入matlab形成二维矩阵。 0表示黑色,1表示白色。记得把题目里给的那张图放到matlab的路径下
m=1;
isfirst=1;
for i=1:648 %648和1152是图片的大小
for j=1:1152
if A(i,j)==0
if isfirst==1 %判断是否是第一次读到花瓶的边缘
fyh=i; %fyh表示黑色部分的第一行的行数
isfirst=0; %第一次读过之后将isfirst置0,这样下次就不会在执行这句了
end
x(m)=i;%x,y保存了所有黑色部分的坐标
y(m)=j;
m=m+1;
end
end
end
lyh=x(70349); %lyh是最后一行的行数,由于第70349个x是最后一个横坐标,所以该值也就是最后一行的值
m=1;
for i=1:1152 %这个循环用于找出黑色部分第一行的所有点的坐标,横坐标存到topx纵坐标存到topy
if A(fyh,i)==0
topx(m)=fyh;
topy(m)=i;
m=m+1;
end
end
isfirst=1;
m=1;
for i=fyh:lyh %从黑色部分的第一行到最后一行循环,找出每一行第一个黑色点的坐标,及左边边缘的坐标存入leftx和lefty中
for j=1:1152
if A(i,j)==0
if isfirst==1
leftx(m)=i;
lefty(m)=j;
m=m+1;
isfirst=0;
end
end
end
isfirst=1;
end
zhongdian=(topy(1)+topy(240))/2;%找出花瓶的对称轴,通过对称找出右边缘的坐标
for i=1:384
rightx(i)=leftx(i);
righty(i)=zhongdian*2-lefty(i);
end
m=1;
for i=1:1152 %这是找出花瓶底部的坐标,至此花瓶的边缘坐标全部找齐
if A(lyh,i)==0
bottomx(m)=lyh;
bottomy(m)=i;
m=m+1;
end
end
for i=1:384
rightx(i)=rightx(i)-170;%坐标变换,将右边缘的轮廓横放在x轴上
righty(i)=righty(i)-zhongdian;
end
for i=1:384
temp(i)=righty(385-i);
end
righty=temp;
X=rightx;
Y=righty;
[X,Y,Z]=cylinder(Y,30);%画图部分,cylinder是用来画旋转体的,括号里的Y表示到旋转轴的距离
mesh(X,Y,Z);
本视频展示如何用matlab绘制散圆状态图,可用于相关科研数据绘图!