MATLAB--數字圖像處理 計算圖像鏈碼及其相似多邊形

題目

計算下面圖像 邊界階數爲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-差值

整理計算鏈碼算法

  1. 對圖像進行預處理 ,比如去除噪聲、邊緣化等 依照不同圖片採取不同措施
  2. 進行重取樣(重取樣原理在下面代碼中)
  3. 隨便找一個起始點,記錄起始位置
  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
回覆 海轟 即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章