本章的練習主要是形態學的一些基本概念和技術,這些構成了一組提取圖像特征的有力工具,針對二值圖像和灰度圖像的腐蝕、膨脹和重構的基本操作可以組合使用,以執行非常寬泛的任務。其練習代碼和結果如下:
1 %% 第9章 形態學處理
2
3 %% imdilate膨脹
4 clc
5 clear
6
7 A1=imread('.\images\dipum_images_ch09\Fig0906(a)(broken-text).tif');
8 info=imfinfo('.\images\dipum_images_ch09\Fig0906(a)(broken-text).tif')
9 B=[0 1 0
10 1 1 1
11 0 1 0];
12 A2=imdilate(A1,B);%圖像A1被結構元素B膨脹
13 A3=imdilate(A2,B);
14 A4=imdilate(A3,B);
15
16 subplot(221),imshow(A1);
17 title('imdilate膨脹原始圖像');
18
19 subplot(222),imshow(A2);
20 title('使用B后1次膨脹后的圖像');
21
22 subplot(223),imshow(A3);
23 title('使用B后2次膨脹后的圖像');
24
25 subplot(224),imshow(A4);
26 title('使用B后3次膨脹后的圖像');
27%imdilate圖像膨脹處理過程運行結果如下:
28
29 %% imerode腐蝕
30 clc
31 clear
32 A1=imread('.\images\dipum_images_ch09\Fig0908(a)(wirebond-mask).tif');
33 subplot(221),imshow(A1);
34 title('腐蝕原始圖像');
35
36 %strel函數的功能是運用各種形狀和大小構造結構元素
37 se1=strel('disk',5);%這里是創建一個半徑為5的平坦型圓盤結構元素
38 A2=imerode(A1,se1);
39 subplot(222),imshow(A2);
40 title('使用結構原始disk(5)腐蝕后的圖像');
41
42 se2=strel('disk',10);
43 A3=imerode(A1,se2);
44 subplot(223),imshow(A3);
45 title('使用結構原始disk(10)腐蝕后的圖像');
46
47 se3=strel('disk',20);
48 A4=imerode(A1,se3);
49 subplot(224),imshow(A4);
50 title('使用結構原始disk(20)腐蝕后的圖像');
51 %圖像腐蝕處理過程運行結果如下:
52

53 %% 開運算和閉運算
54 clc
55 clear
56 f=imread('.\images\dipum_images_ch09\Fig0910(a)(shapes).tif');
57 %se=strel('square',5');%方型結構元素
58 se=strel('disk',5');%圓盤型結構元素
59 imshow(f);%原圖像
60 title('開閉運算原始圖像')
61%運行結果如下:
62
63 %開運算數學上是先腐蝕后膨脹的結果
64 %開運算的物理結果為完全刪除了不能包含結構元素的對象區域,平滑
65 %了對象的輪廓,斷開了狹窄的連接,去掉了細小的突出部分
66 fo=imopen(f,se);%直接開運算
67 figure,subplot(221),imshow(fo);
68 title('直接開運算');
69
70 %閉運算在數學上是先膨脹再腐蝕的結果
71 %閉運算的物理結果也是會平滑對象的輪廓,但是與開運算不同的是,閉運算
72 %一般會將狹窄的缺口連接起來形成細長的彎口,並填充比結構元素小的洞
73 fc=imclose(f,se);%直接閉運算
74 subplot(222),imshow(fc);
75 title('直接閉運算');
76
77 foc=imclose(fo,se);%先開后閉運算
78 subplot(223),imshow(foc);
79 title('先開后閉運算');
80
81 fco=imopen(fc,se);%先閉后開運算
82 subplot(224),imshow(fco);
83 title('先閉后開運算');
84%開閉運算結果如下:
85
86 %先膨脹再腐蝕
87 fse=imdilate(f,se);%膨脹
88
89 %gcf為得到當前圖像的句柄,當前圖像是指例如PLOT,TITLE,SURF等
90 %get函數為得到物體的屬性,get(0,'screensize')為返回所有物體screensize屬性值
91 %set函數為設置物體的屬性
92 figure,set(gcf,'outerposition',get(0,'screensize'));%具體目的是設置當前窗口的大小
93 subplot(211),imshow(fse);
94 title('使用disk(5)先膨脹后的圖像');
95
96 fes=imerode(fse,se);
97 subplot(212),imshow(fes);
98 title('使用disk(5)先膨脹再腐蝕后的圖像');
99%先膨脹后腐蝕圖像如下:
100
101 %先腐蝕再膨脹
102 fse=imerode(f,se);
103 figure,set(gcf,'outerposition',get(0,'screensize'))
104 subplot(211),imshow(fse);
105 title('使用disk(5)先腐蝕后的圖像');
106
107 fes=imdilate(fse,se);
108 subplot(212),imshow(fes);
109 title('使用disk(5)先腐蝕再膨脹后的圖像');
110%先腐蝕后膨脹的圖像如下:
111
112 %% imopen imclose在指紋上的應用
113 clc
114 clear
115 f=imread('.\images\dipum_images_ch09\Fig0911(a)(noisy-fingerprint).tif');
116 se=strel('square',3);%邊長為3的方形結構元素
117 subplot(121),imshow(f);
118 title('指紋原始圖像');
119
120 A=imerode(f,se);%腐蝕
121 subplot(122),imshow(A);
122 title('腐蝕后的指紋原始圖像');
123%指紋原始圖像和腐蝕后的圖像結果如下:
124
125 fo=imopen(f,se);
126 figure,subplot(221),imshow(fo);
127 title('使用square(3)開操作后的圖像');
128
129 fc=imclose(f,se);
130 subplot(222),imshow(fc);
131 title('使用square閉操作后的圖像');
132
133 foc=imclose(fo,se);
134 subplot(223),imshow(foc);
135 title('使用square(3)先開后閉操作后的圖像')
136
137 fco=imopen(fc,se);
138 subplot(224),imshow(fco);
139 title('使用square(3)先閉后開操作后的圖像');
140%指紋圖像開閉操作過程結果如下:
141
142 %% bwhitmiss擊中或擊不中變換
143 clc
144 clear
145 f=imread('.\images\dipum_images_ch09\Fig0913(a)(small-squares).tif');
146 imshow(f);
147 title('擊中或不擊中原始圖像');
148%擊中或不擊中原始圖像顯示結果如下:
149
150 B1=strel([0 0 0;0 1 1;0 1 0]);%擊中:要求擊中所有1的位置
151 B2=strel([1 1 1;1 0 0;1 0 0]);%擊不中,要求擊不中所有1的位置
152 B3=strel([0 1 0;1 1 1;0 1 0]);%擊中
153 B4=strel([1 0 1;0 0 0;0 0 0]);%擊不中
154 B5=strel([0 0 0;0 1 0;0 0 0]);%擊中
155 B6=strel([1 1 1;1 0 0;1 0 0]);%擊不中
156
157 g=imerode(f,B1)&imerode(~f,B2)%利用定義來實現擊中或擊不中
158 figure,subplot(221),imshow(g);
159 title('定義實現組1擊中擊不中圖像');
160
161 g1=bwhitmiss(f,B1,B2);
162 subplot(222),imshow(g1);
163 title('結構數組1擊中擊不中后的圖像');
164
165 g2=bwhitmiss(f,B3,B4);
166 subplot(223),imshow(g2);
167 title('結構數組2擊中擊不中的圖像');
168
169 g3=bwhitmiss(f,B5,B6);
170 subplot(224),imshow(g3);
171 title('結構數組3擊中擊不中的圖像');
172%擊中擊不中變換后圖像如下:
173
174 %%makelut
175 clc
176 clear
177
178 f=inline('sum(x(:))>=3');%inline是用來定義局部函數的
179 lut2=makelut(f,2)%為函數f構造一個接收2*2矩陣的查找表
180 lut3=makelut(f,3)
181
182 %% Conway生命游戲
183 clc
184 clear
185 lut=makelut(@conwaylaws,3);
186 bw1= [0 0 0 0 0 0 0 0 0 0
187 0 0 0 0 0 0 0 0 0 0
188 0 0 0 1 0 0 1 0 0 0
189 0 0 0 1 1 1 1 0 0 0
190 0 0 1 0 0 0 0 1 0 0
191 0 0 1 0 1 1 0 1 0 0
192 0 0 1 0 0 0 0 1 0 0
193 0 0 0 1 1 1 1 0 0 0
194 0 0 0 0 0 0 0 0 0 0
195 0 0 0 0 0 0 0 0 0 0 ];
196 subplot(221),imshow(bw1,'InitialMagnification','fit');
197 title('Generation 1');
198
199 bw2=applylut(bw1,lut);
200 subplot(222),imshow(bw2,'InitialMagnification','fit'),
201 title('Generation 2');
202
203 bw3=applylut(bw2,lut);
204 subplot(223),imshow(bw3,'InitialMagnification','fit');
205 title('Generation 3');
206
207 temp=bw1;
208 for i=2:100
209 bw100=applylut(temp,lut);
210 temp=bw100;
211 end
212 subplot(224),imshow(bw100,'InitialMagnification','fit')
213 title('Generation 100');
214%顯示Generation結果如下:
215
216 %% getsequence
217 clc
218 clear
219 se=strel('diamond',5)
220 decomp=getsequence(se)%getsequence函數為得到分解的strel序列
221 decomp(1)
222 decomp(2)
223
224 %% endpoints
225 clc
226 clear
227
228 f1=imread('.\images\dipum_images_ch09\Fig0914(a)(bone-skel).tif');
229 subplot(121),imshow(f1);
230 title('原始形態骨架圖像');
231
232 g1=endpoints(f1);
233 %set(gcf,'outerposition',get(0,'screensize'));%運行完后自動生成最大的窗口
234 subplot(122),imshow(g1);
235 title('骨架圖像的端點圖像');236 %骨架頭像端點檢測頭像如下:
237
238 f2=imread('.\images\dipum_images_ch09\Fig0916(a)(bone).tif');
239 figure,subplot(121),imshow(f2);
240 title('原始骨頭圖像');
241
242 g2=endpoints(f2);
243 subplot(122),imshow(g2);
244 title('骨頭圖像端點頭像');%結果是沒有端點
245%骨頭頭像端點檢測圖像如下:
246
247 %% bwmorph組合常見形態學之細化
248 clc
249 clear
250 f=imread('.\images\dipum_images_ch09\Fig0911(a)(noisy-fingerprint).tif');
251 subplot(221),imshow(f);
252 title('指紋圖像細化原圖');
253
254 g1=bwmorph(f,'thin',1);
255 subplot(222),imshow(g1);
256 title('指紋圖像細化原圖');
257
258 g2=bwmorph(f,'thin',2);
259 subplot(223),imshow(g2);
260 title('指紋圖像細化原圖');
261
262 g3=bwmorph(f,'thin',Inf);
263 subplot(224),imshow(g3);
264 title('指紋圖像細化原圖');
265%指紋圖像細化過程顯示如下:
266
267 %% bwmorph組合常見形態學之骨骼化
268 clc
269 clear
270 f=imread('.\images\dipum_images_ch09\Fig0911(a)(noisy-fingerprint).tif');
271 subplot(131),imshow(f);
272 title('指紋圖像骨骼化原圖');
273
274 fs=bwmorph(f,'skel',Inf);
275 subplot(132),imshow(fs);
276 title('指紋圖像骨骼化');
277
278 for k=1:5
279 fs=fs&~endpoints(fs);
280 end
281 subplot(133),imshow(fs);
282 title('指紋圖像修剪后骨骼話');
283%指紋圖像骨骼化過程顯示:
284
285 %% 使用函數bwlabel標注連通分量
286 clc
287 clear
288 f=imread('.\images\dipum_images_ch09\Fig0917(a)(ten-objects).tif');
289 imshow(f),title('標注連通分量原始圖像');
290%其結果顯示如下:
291
292 [L,n]=bwlabel(f);%L為標記矩陣,n為找到連接分量的總數
293 [r,c]=find(L==3);%返回第3個對象所有像素的行索引和列索引
294
295 rbar=mean(r);
296 cbar=mean(c);
297
298 figure,imshow(f)
299 hold on%保持當前圖像使其不被刷新
300 for k=1:n
301 [r,c]=find(L==k);
302 rbar=mean(r);
303 cbar=mean(c);
304 plot(cbar,rbar,'Marker','o','MarkerEdgeColor','k',...
305 'MarkerFaceColor','k','MarkerSize',10);%這個plot函數用法不是很熟悉
306 plot(cbar,rbar,'Marker','*','MarkerFaceColor','w');%其中的marker為標記
307 end
308 title('標記所有對象質心后的圖像');
309
310 %% 由重構做開運算
311 clc
312 clear
313 f=imread('.\images\dipum_images_ch09\Fig0922(a)(book-text).tif');
314 subplot(321),imshow(f);
315 title('重構原始圖像');
316
317 fe=imerode(f,ones(51,1));%豎線腐蝕
318 subplot(322),imshow(fe);
319 title('使用豎線腐蝕后的結果');
320
321 fo=imopen(f,ones(51,1));%豎線做開運算
322 subplot(323),imshow(fo);
323 title('使用豎線做開運算結果');
324
325 fobr=imreconstruct(fe,f);%fe做標記
326 subplot(324),imshow(fobr);
327 title('使用豎線做重構開運算');
328
329 ff=imfill(f,'holes');%對f進行孔洞填充
330 subplot(325),imshow(ff);
331 title('對f填充孔洞后的圖像');
332
333 fc=imclearborder(f,8);%清除邊界,2維8鄰接
334 subplot(326),imshow(fc);
335 title('對f清除邊界后的圖像');
336%圖像重構過程顯示如下:
337
338 %% 使用頂帽變換和底帽變換
339 clc
340 clear
341 f=imread('.\images\dipum_images_ch09\Fig0926(a)(rice).tif');
342 subplot(221),imshow(f);
343 title('頂帽底帽變換原始圖像');
344
345 se=strel('disk',10);%產生結構元素
346 %頂帽變換是指原始圖像減去其開運算的圖像
347 %而開運算可用於補償不均勻的背景亮度,所以用一個大的結構元素做開運算后
348 %然后用原圖像減去這個開運算,就得到了背景均衡的圖像,這也叫做是圖像的頂帽運算
349 f1=imtophat(f,se);%使用頂帽變換
350 subplot(222),imshow(f1);
351 title('使用頂帽變換后的圖像');
352
353 %底帽變換是原始圖像減去其閉運算后的圖像
354 f2=imbothat(imcomplement(f),se);%使用底帽變換,為什么原圖像要求補呢?
355 %f2=imbothat(f,se);%使用底帽變換
356 subplot(223),imshow(f2);
357 title('使用底帽變換后的圖像');
358
359 %頂帽變換和底帽變換聯合起來用,用於增加對比度
360 f3=imsubtract(imadd(f,imtophat(f,se)),imbothat(f,se));%里面參數好像不合理?
361 subplot(224),imshow(f3);
362 title('使用頂帽底帽聯合變換后圖像');
363%頂帽底帽變換過程圖像如下:
364
365 %%使用開運算和閉運算做形態學平滑
366 %由於開運算可以除去比結構元素更小的明亮細節,閉運算可以除去比結構元素更小的暗色細節
367 %所以它們經常組合起來一起進行平滑圖像並去除噪聲
368 clc
369 clear
370 f=imread('.\images\dipum_images_ch09\Fig0925(a)(dowels).tif');
371 subplot(221),imshow(f);
372 title('木釘圖像原圖');
373
374 se=strel('disk',5);%disk其實就是一個八邊形
375 fo=imopen(f,se);%經過開運算
376 subplot(222),imshow(f);
377 title('使用半徑5的disk開運算后的圖像');
378
379 foc=imclose(fo,se);
380 subplot(223),imshow(foc);
381 title('先開后閉的圖像');
382
383 fasf=f;
384 for i=2:5
385 se=strel('disk',i);
386 fasf=imclose(imopen(fasf,se),se);
387 end
388 subplot(224),imshow(fasf);
389 title('使用開閉交替濾波后圖像');
390%使用開運算和閉運算做形態學平滑結果如下:
391
392 %% 顆粒分析
393 clc
394 clear
395 f=imread('.\images\dipum_images_ch09\Fig0925(a)(dowels).tif');
396
397 sumpixels=zeros(1,36);
398 for k=0:35
399 se=strel('disk',k);
400 fo=imopen(f,se);
401 sumpixels(k+1)=sum(fo(:));
402 end
403
404 %可以看到,連續開運算之間的表面積會減少
405 plot(0:35,sumpixels),xlabel('k'),ylabel('surface area');
406 title('表面積和結構元素半徑之間的關系');
407%其運算結果如下:
408
409 figure,plot(-diff(sumpixels));%diff()函數為差分或者近似倒數,即相鄰2個之間的差值
410 xlabel('k'),ylabel('surface area reduction');
411 title('減少的表面積和結構元素半徑之間的關系');
412%其運算結果如下:
413
414 %% 使用重構刪除復雜圖像的背景
415 clc
416 clear
417 f=imread('.\images\dipum_images_ch09\Fig0930(a)(calculator).tif');
418 subplot(221),imshow(f);
419 title('灰度級重構原圖像');
420
421 f_obr=imreconstruct(imerode(f,ones(1,71)),f);
422 subplot(222),imshow(f_obr);
423 title('經開運算重構圖');
424
425 f_o=imopen(f,ones(1,71));
426 subplot(223),imshow(f_o);
427 title('經開運算后圖');
428
429 f_thr=imsubtract(f,f_obr);
430 subplot(224),imshow(f_thr);
431 title('頂帽運算重構圖')
432%使用重構刪除復雜圖像的背景1:
433
434 f_th=imsubtract(f,f_o)
435 figure,subplot(221),imshow(f_th);
436 title('經頂帽運算圖');
437
438 g_obr=imreconstruct(imerode(f_thr,ones(1,11)),f_thr);
439 subplot(222),imshow(g_obr);
440 title('用水平線對f_thr經開運算后重構圖');
441
442 g_obrd=imdilate(g_obr,ones(1,2));
443 subplot(223),imshow(g_obrd);
444 title('使用水平線對上圖進行膨脹');
445
446 f2=imreconstruct(min(g_obrd,f_thr),f_thr);
447 subplot(224),imshow(f2);
448 title('最后的重構結果');
449%使用重構刪除復雜圖像的背景2:
形態學這一章很有用,因為它還可以應用在圖像分割中。