題目
計算下面圖像 邊界階數爲20的形狀數及其相應的近似多邊形
概念
形狀數:鏈碼的最小一階差分碼
簡單說來求形狀數就是:先求出圖像的鏈碼 ,再求其一階差分碼,最後找一階差分碼的最小值
鏈碼:用曲線(或折線)起始點的座標和邊界點方向代碼來描述曲線或邊界的方法
有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方向鏈碼爲例)
- 計算第一個數與第二個數差值
- 比較二者大小
- 若第一個數大,則一階差分爲 差值相反數
- 若第二個數大,則一階差分爲 4-差值
整理計算鏈碼算法
- 對圖像進行預處理 ,比如去除噪聲、邊緣化等 依照不同圖片採取不同措施
- 進行重取樣(重取樣原理在下面代碼中)
- 隨便找一個起始點,記錄起始位置
- 利用循環 or 遞歸 求鏈碼(類似C++中的走迷宮)
實驗代碼
注:這裏圖片記得使用題目所給圖像,否則需要對下面代碼進行修改
該代碼僅爲 測試算法 還未封裝爲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
回覆 海轟 即可