形状数:链码的最小一阶差分码
简单说来求形状数就是:先求出图像的链码 ,再求其一阶差分码,最后找一阶差分码的最小值
链码:用曲线(或折线)起始点的坐标和边界点方向代码来描述曲线或边界的方法
有4方向、8方向链码之分。
那么具体怎么计算链码呢?
拿上图8方向链码举例(右图):
假设起始点为1,则链码为 1 0 1 3 6 6 6 6 6…
这里说一下怎么求一阶差分链码:
假设4方向链码为 0 2 1 3 1 3 0
那么一阶差分链码为: 2 3 2 2 2 1 0
具体怎么来的呢?
解释:
从0—>2,按照逆时针旋转规则,0旋转到2,需要走2步:0–1—2
从2–>1,需要3步:2–3--0–1
依次类推
注意最后一个(0),其实就是起始点,形成闭合
C++算法(以4方向链码为例)
注:这里图片记得使用题目所给图像,否则需要对下面代码进行修改
该代码仅为 测试算法 还未封装为function
% write by 海轰
%该程序针对特定图片其作用
%为测试程序
t=im2bw(imread('homework1.png'));
%过滤边缘白点 这里仅针对这幅图像
t(:,1)=0;
t(140:145,:)=0;
imshow(t),title('原图');
[m,n]=size(t);
%行扫描 找出图像白色区域最左边的端点
for i=1:m
x=0;y=141;
tem=t(i,:);
h=sum(tem);
if h~=0
for j=1:n
if tem(j)==1
x=j;
break
end
end
%行扫描 反转 寻找白点区域最右边的端点
tem=flip(tem);
for j=1:n
if tem(j)==1
y=n-j+1;
break;
end
end
%对区域进去填充 便于找到边界
for j=x+1:y-1
t(i,j)=1;
end
end
end
figure,imshow(t),title('填充区域后');
t=bwperim(t,8);
figure,imshow(t),title('找到边界');
a=t;
rt=zeros(145,141);
%对图像进行重取样
%假设原图像为100*100 一点为(62,73)
%重取样模板为100*100 但是间隔为10 (分成10*10)
%先对(62,73)/10=(6.2,7.3)
%再取整 (6,7)
%再还原 10*(6,7)=(60,70)
%这样重取样后得到(60,70)
for i=1:m
for j=1:n
if t(i,j)==1
if round(j/15)==0
rt(15*round(i/15),15*(round(j/15)+1))=1;
else
rt(15*round(i/15),15*round(j/15))=1;
end
end
end
end
figure,imshow(rt),title('重取样后');
stack=[0 0];%保存起点
code=[];%保存链码
points=zeros(25,2);%保存端点
k=0;
t=rt;
%随便寻找起点
for i=1:m
for j=1:n
if t(i,j)==1
stack=[i j];
break;
end
end
end
s1=stack(1);
s2=stack(2)+1;
%while循环求链码
while (s1~=stack(1)||s2~=stack(2))&&k<500
k=k+1;
if k==1
s2=s2-1;
end
if s2+15<=141
if t(s1,s2+15)==1
code(k)=0;
points(k,1)=s1;
points(k,2)=s2;
t(s1,s2)=0;
s1=s1;s2=s2+15;
continue;
end
end
if s1-15>0&&s2+15<=141
if t(s1-15,s2+15)==1
code(k)=1;
points(k,1)=s1;
points(k,2)=s2;
t(s1,s2)=0;
s1=s1-15;
s2=s2+15;
continue;
end
end
if s1-15>0
if t(s1-15,s2)==1
code(k)=2;
points(k,1)=s1;
points(k,2)=s2;
t(s1,s2)=0;
s1=s1-15;s2=s2;
continue;
end
end
if s1-15>0&&s2-15>0
if t(s1-15,s2-15)==1
code(k)=3;
points(k,1)=s1;
points(k,2)=s2;
t(s1,s2)=0;
s1=s1-15;s2=s2-15;
continue;
end
end
if s2-15>0
if t(s1,s2-15)==1
code(k)=4;
points(k,1)=s1;
points(k,2)=s2;
t(s1,s2)=0;
s1=s1;s2=s2-15;
continue;
end
end
if s2-15>0
if t(s1+15,s2-15)==1
code(k)=5;
points(k,1)=s1;
points(k,2)=s2;
t(s1,s2)=0;
s1=s1+15;
s2=s2-15;
continue;
end
end
if t(s1+15,s2)==1
code(k)=6;
points(k,1)=s1;
points(k,2)=s2;
t(s1,s2)=0;
s1=s1+15;s2=s2;
continue;
end
if s2+15<=141
if t(s1+15,s2+15)==1
code(k)=7;
points(k,1)=s1;
points(k,2)=s2;
t(s1,s2)=0;
s1=s1+15;
s2=s2+15;
continue;
end
end
end
xt=rt-t;
figure,imshow(xt),title('相似多边形'),hold on;
for i=1:25
if i==25
plot([points(25,2);points(1,2)],[points(25,1);points(1,1)]);
else
plot(points(i:i+1,2),points(i:i+1,1));
end
end
获取更多资料、代码,微信公众号:海轰Pro
回复 海轰 即可