本章的练习主要是形态学的一些基本概念和技术,这些构成了一组提取图像特征的有力工具,针对二值图像和灰度图像的腐蚀、膨胀和重构的基本操作可以组合使用,以执行非常宽泛的任务。其练习代码和结果如下:
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);
全部评论
请发表评论