matlab实现形态学处理
形态学是提取图像特征的有力工具,针对二值图像和灰度图像的腐蚀、膨胀和重构的基本操作可以组合使用,以执行非常宽泛的任务。其练习代码和结果如下:
1 %% 第9章 形态学处理 2 3 %% imdilate膨胀 4 clc 5 clear 6 7 A1=imread(".imagesdipum_images_ch09Fig0906(a)(broken-text).tif"); 8 info=imfinfo(".imagesdipum_images_ch09Fig0906(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(".imagesdipum_images_ch09Fig0908(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(".imagesdipum_images_ch09Fig0910(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(".imagesdipum_images_ch09Fig0911(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(".imagesdipum_images_ch09Fig0913(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(".imagesdipum_images_ch09Fig0914(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(".imagesdipum_images_ch09Fig0916(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(".imagesdipum_images_ch09Fig0911(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(".imagesdipum_images_ch09Fig0911(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(".imagesdipum_images_ch09Fig0917(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(".imagesdipum_images_ch09Fig0922(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(".imagesdipum_images_ch09Fig0926(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(".imagesdipum_images_ch09Fig0925(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(".imagesdipum_images_ch09Fig0925(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(".imagesdipum_images_ch09Fig0930(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:
形态学这一章很有用,因为它还可以应用在图像分割中。
转载自:http://blog.csdn.net/yangyangyang20092010/article/details/8289572
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。