這一章中主要是用數字圖像處理技術對圖像進行分割。因為圖像分割是個比較難的課題。這里練習的是比較基本的。包過點、線和邊緣的檢測,hough變換的應用,閾值處理,基於區域的分割以及基於分水嶺方法的分割。
其練習代碼和結果如下:
1 %% 圖像分割
2
3 %% 點檢測
4 clc
5 clear
6 f=imread('.\images\dipum_images_ch10\Fig1002(a)(test_pattern_with_single_pixel).tif');
7 subplot(121),imshow(f),title('點檢測原圖');
8
9 w=[-1,-1,-1;
10 -1,8,-1;
11 -1,-1,-1]
12 g=abs(imfilter(double(f),w));
13 subplot(122),imshow(g),title('點檢測結果');
14%點檢測圖結果如下:

15
16 %% 非線性濾波點檢測
17 clc
18 clear
19 f=imread('.\images\dipum_images_ch10\Fig1002(a)(test_pattern_with_single_pixel).tif');
20 subplot(121),imshow(f),title('非線性濾波點檢測原圖');
21
22 m=3;
23 n=3;
24 %ordfilt2(f,order,domin)表示的是用矩陣domin中為1的地方進行排序,然后選擇地order個位置的值代替f中的值,屬於非線性濾波
25 g=imsubtract(ordfilt2(f,m*n,ones(m,n)),ordfilt2(f,1,ones(m,n)));%濾波鄰域的最大值減去最小值
26 T=max(g(:));
27 g2=g>=T;
28 subplot(122),imshow(g2);
29 title('非線性濾波點檢測后圖');
30%運行結果如下:

31
32 %% 檢測指定方向的線
33 clc
34 clear
35 f=imread('.\images\dipum_images_ch10\Fig1004(a)(wirebond_mask).tif');
36 subplot(321),imshow(f);
37 title('檢測指定方向線的原始圖像');
38
39 w=[2 -1 -1;
40 -1 2 -1;
41 -1 -1 2];%矩陣用逗號或者空格隔開的效果是一樣的
42 g=imfilter(double(f),w);
43 subplot(322),imshow(g,[]);
44 title('使用-45度檢測器處理后的圖像');
45
46 gtop=g(1:120,1:120);%取g的左上角圖
47 gtop=pixeldup(gtop,4);%擴大4*4倍的圖
48 subplot(323),imshow(gtop,[]);
49 title('-45度檢測后左上角放大圖');
50
51 gbot=g(end-119:end,end-119:end);%取右下角圖
52 gbot=pixeldup(gbot,4);%擴大16倍的圖
53 subplot(324),imshow(gbot,[]);
54 title('-45度檢測后右下角后放大圖');
55
56 g=abs(g);
57 subplot(325),imshow(g,[]);
58 title('-45度檢測后的絕對值圖');
59
60 T=max(g(:));
61 g=g>=T;
62 subplot(326),imshow(g);
63 title('-45度檢測后取絕對值最大的圖')
64%檢測指定方向的線過程如下:

65
66 %% sobel檢測器檢測邊緣
67 clc
68 clear
69 f=imread('.\images\dipum_images_ch10\Fig1006(a)(building).tif');
70 subplot(321),imshow(f);
71 title('sobel檢測的原始圖像');
72
73 [gv,t]=edge(f,'sobel','vertical');%斜線因為具有垂直分量,所以也能夠被檢測出來
74 subplot(322),imshow(gv);
75 title('sobel垂直方向檢測后圖像');
76
77 gv=edge(f,'sobel',0.15,'vertical');
78 subplot(323),imshow(gv);
79 title('sobel垂直檢測0.15閾值后圖像');
80
81 gboth=edge(f,'sobel',0.15);
82 subplot(324),imshow(gboth);
83 title('sobel水平垂直方向閾值0.15后圖像');
84
85 w45=[-2 -1 0
86 -1 0 1
87 0 1 2];%相當於45度的sobel檢測算子
88 g45=imfilter(double(f),w45,'replicate');
89 T=0.3*max(abs(g45(:)));
90 g45=g45>=T;
91 subplot(325),imshow(g45);
92 title('sobel正45度方向上檢測圖');
93
94 w_45=[0 -1 -2
95 1 0 -1
96 2 1 0];
97 g_45=imfilter(double(f),w_45,'replicate');
98 T=0.3*max(abs(g_45(:)));
99 g_45=g_45>=T;
100 subplot(326),imshow(g_45);
101 title('sobel負45度方向上檢測圖');
102%sobel檢測過程如下:

103
104 %% sobel,log,canny邊緣檢測器的比較
105 clc
106 clear
107 f=imread('.\images\dipum_images_ch10\Fig1006(a)(building).tif');
108
109 [g_sobel_default,ts]=edge(f,'sobel');%
110 subplot(231),imshow(g_sobel_default);
111 title('g sobel default');
112
113 [g_log_default,tlog]=edge(f,'log');
114 subplot(233),imshow(g_log_default);
115 title('g log default');
116
117 [g_canny_default,tc]=edge(f,'canny');
118 subplot(235),imshow(g_canny_default);
119 title('g canny default');
120
121 g_sobel_best=edge(f,'sobel',0.05);
122 subplot(232),imshow(g_sobel_best);
123 title('g sobel best');
124
125 g_log_best=edge(f,'log',0.003,2.25);
126 subplot(234),imshow(g_log_best);
127 title('g log best');
128
129 g_canny_best=edge(f,'canny',[0.04 0.10],1.5);
130 subplot(236),imshow(g_canny_best);
131 title('g canny best');
132%3者比較的結果如下:

133
134 %% hough變換說明
135 clc
136 clear
137 f=zeros(101,101);
138 f(1,1)=1;
139 f(101,1)=1;
140 f(1,101)=1;
141 f(51,51)=1;
142 f(101,101)=1;
143 imshow(f);title('帶有5個點的二值圖像');
144%顯示如下:

145
146 H=hough(f);
147 figure,imshow(H,[]);
148 title('不帶標度的hough變換');
149%不帶標度的hough變換結果如下:

150
151 [H,theta,rho]=hough(f);
152 figure,imshow(theta,rho,H,[],'notruesize');%為什么顯示不出來呢
153 axis on,axis normal;
154 xlabel('\theta'),ylabel('\rho');
155
156 %% 計算全局閾值
157 clc
158 clear
159 f = imread('.\images\dipum_images_ch10\Fig1013(a)(scanned-text-grayscale).tif');
160 imshow(f);
161 title('全局閾值原始圖像')
162%其圖片顯示結果如下:

163
164 T=0.5*(double(min(f(:)))+double(max(f(:))));
165 done=false;
166 while ~done
167 g=f>=T;
168 Tnext=0.5*(mean(f(g))+mean(f(~g)));
169 done=abs(T-Tnext)<0.5
170 T=Tnext;
171 end
172 g=f<=T;%因為前景是黑色的字,所以要分離出來的話這里就要用<=.
173 figure,subplot(121),imshow(g);
174 title('使用迭代方法得到的閾值處理圖像');
175
176
177 T2=graythresh(f);%得到的是0~1的小數?
178 g=f<=T2*255;
179 subplot(122),imshow(g);
180 title('使用函數graythresh得到的閾值處理圖像');
181%閾值處理后結果如下:

182
183 %% 焊接空隙區域生長
184 clc
185 clear
186 f = imread('.\images\dipum_images_ch10\Fig1014(a)(defective_weld).tif');
187 subplot(221),imshow(f);
188 title('焊接空隙原始圖像');
189
190 %函數regiongrow返回的NR為是不同區域的數目,參數SI是一副含有種子點的圖像
191 %TI是包含在經過連通前通過閾值測試的像素
192 [g,NR,SI,TI]=regiongrow(f,255,65);%種子的像素值為255,65為閾值
193
194 subplot(222),imshow(SI);
195 title('焊接空隙種子點的圖像');
196
197 subplot(223),imshow(TI);
198 title('焊接空隙所有通過閾值測試的像素');
199
200 subplot(224),imshow(g);
201 title('對種子點進行8連通分析后的結果');
202%焊接空隙區域生長圖如下:

203
204 %% 使用區域分離和合並的圖像分割
205 clc
206 clear
207 f = imread('.\images\dipum_images_ch10\Fig1017(a)(cygnusloop_Xray_original).tif');
208 subplot(231),imshow(f);
209 title('區域分割原始圖像');
210
211 g32=splitmerge(f,32,@predicate);%32代表分割中允許最小的塊
212 subplot(232),imshow(g32);
213 title('mindim為32時的分割圖像');
214
215 g16=splitmerge(f,16,@predicate);%32代表分割中允許最小的塊
216 subplot(233),imshow(g16);
217 title('mindim為32時的分割圖像');
218
219 g8=splitmerge(f,8,@predicate);%32代表分割中允許最小的塊
220 subplot(234),imshow(g8);
221 title('mindim為32時的分割圖像');
222
223 g4=splitmerge(f,4,@predicate);%32代表分割中允許最小的塊
224 subplot(235),imshow(g4);
225 title('mindim為32時的分割圖像');
226
227 g2=splitmerge(f,2,@predict);%32代表分割中允許最小的塊
228 subplot(236),imshow(g2);
229 title('mindim為32時的分割圖像');
230
231 %% 使用距離和分水嶺變換分割灰度圖像
232 clc
233 clear
234 f = imread('.\images\dipum_images_ch10\Fig0925(a)(dowels).tif');
235 subplot(231),imshow(f);title('使用距離和分水嶺分割原圖');
236
237 g=im2bw(f,graythresh(f));
238 subplot(232),imshow(g),title('原圖像閾值處理后的圖像');
239
240 gc=~g;
241 subplot(233),imshow(gc),title('閾值處理后取反圖像');
242
243 D=bwdist(gc);
244 subplot(234),imshow(D),title('使用距離變換后的圖像');
245
246 L=watershed(-D);
247 w=L==0;
248 subplot(235),imshow(w),title('距離變換后的負分水嶺圖像');
249
250 g2=g & ~w;
251 subplot(236),imshow(g2),title('閾值圖像與分水嶺圖像相與圖像');
252%使用距離分水嶺圖像如下:

253
254 %% 使用梯度和分水嶺變換分割灰度圖像
255 clc
256 clear
257 f = imread('.\images\dipum_images_ch10\Fig1021(a)(small-blobs).tif');
258 subplot(221),imshow(f);
259 title('使用梯度和分水嶺變換分割灰度圖像');
260
261 h=fspecial('sobel');
262 fd=double(f);
263 g=sqrt(imfilter(fd,h,'replicate').^2+imfilter(fd,h','replicate').^2);
264 subplot(222),imshow(g,[]);
265 title('使用梯度和分水嶺分割幅度圖像');
266
267 L=watershed(g);
268 wr=L==0;
269 subplot(223),imshow(wr);
270 title('對梯度復制圖像進行二值分水嶺后圖像');
271
272 g2=imclose(imopen(g,ones(3,3)),ones(3,3));
273 L2=watershed(g2);
274 wr2=L2==0;
275 f2=f;
276 f2(wr2)=255;
277 subplot(224),imshow(f2);
278 title('平滑梯度圖像后的分水嶺變換');
279%使用梯度和分水嶺變換分割灰度圖像結果如下:

280
281 %% 控制標記符的分水嶺分割
282 clc
283 clear
284 f = imread('.\images\dipum_images_ch10\Fig1022(a)(gel-image).tif');
285 imshow(f);
286 title('控制標記符的分水嶺分割原圖像');

287
288 h=fspecial('sobel');
289 fd=double(f);
290 g=sqrt(imfilter(fd,h,'replicate').^2+imfilter(fd,h','replicate').^2);
291 L=watershed(g);
292 wr=L==0;
293 figure,subplot(231),imshow(wr,[]);
294 title('控制標記符的分水嶺分割幅度圖像');
295
296 rm=imregionalmin(g);%梯度圖像有很多較淺的坑,造成的原因是原圖像不均勻背景中灰度細小的變化
297 subplot(232),imshow(rm,[]);
298 title('對梯度幅度圖像的局部最小區域');
299
300 im=imextendedmin(f,2);%得到內部標記符
301 fim=f;
302 fim(im)=175;
303 subplot(233),imshow(f,[]);
304 title('內部標記符');
305
306 Lim=watershed(bwdist(im));
307 em=Lim==0;
308 subplot(234),imshow(em,[]);
309 title('外部標記符');
310
311 g2=imimposemin(g,im | em);
312 subplot(235),imshow(g2,[]);
313 title('修改后的梯度幅度值');
314
315 L2=watershed(g2);
316 f2=f;
317 f2(L2==0)=255;
318 subplot(236),imshow(f2),title('最后分割的結果');
319%控制標記符的分水嶺分割過程如下:

圖像分割中處理涉及到很多參數都需要自己根據具體問題不斷調試,直到選出最好的參數組合為止。
