1. 思路
假设我们有这样一幅图像, 想要提取中间白框的边缘.
使用常用的基于灰度梯度的算子容易把噪声边缘误判为目标边缘, 也有可能使得白框边缘不连续.
首先观察图像特征:
1. 目标边缘, 也就是白框的边缘比较规则, 而且体积较大.
2. 噪声边缘不规则, 在白框内外都有, 而且体积较小.
那么要区分两者, 可以从体积上来区分.
我们知道, 开运算和闭运算可以将较小的目标从图像上”抹掉”.
开运算可以”削峰”, 闭运算可以”填坑”.
我们可以分两步走:
1. 先开运算, 把白框外的白块(“峰”)削平.在选择结构元素SE时, 需要选的足够大, 能覆盖得了每一个想要抹去的对象才可以.
2. 再闭运算, 把白框内的黑块(“坑”)填平. SE同第1步的SE.
3. 对2的结果, 膨胀减去腐蚀. SE可以选的小一些.
2. 实现
a. 先开后闭
%% 问题 9.17
clear;close all;clc;
image=imread('Figp0917.tif');
image(590:end,590:end)=0;
imwrite(image,'917.jpg','jpg');
figure;
subplot(231);imshow(image,[]);title('原图');
SE = strel('disk', 15, 4);
image_erode=imerode(image,SE);
subplot(232);imshow(image_erode,[]);title('腐蚀');
image_open=imdilate(image_erode,SE);
subplot(233);imshow(image_open,[]);title('开');
image_o_d=imdilate(image_open,SE);
subplot(234);imshow(image_o_d,[]);title('开后膨胀');
image_o_c=imerode(image_o_d,SE);
subplot(235);imshow(image_o_c,[]);title('开后闭');
SE2=strel('disk',4,4);
image_grad=imdilate(image_o_c,SE2)-imerode(image_o_c,SE2);
image_grad(image_grad<0)=0;
subplot(236);imshow(image_grad,[]);title('形态梯度');
输出:
b. 先闭后开
那先闭后开呢?
clear;close all;clc;
image=imread('Figp0917.tif');
image(590:end,590:end)=0;
SE = strel('disk', 15, 4);
SE2=strel('disk',4,4);
% 先闭后开
image_dilate=imdilate(image,SE);
image_close=imerode(image_dilate,SE);
image_c_e=imerode(image_close,SE);
image_c_o=imdilate(image_c_e,SE);
image_grad=imdilate(image_c_o,SE2)-imerode(image_c_o,SE2);
figure;
subplot(231);imshow(image,[]);title('原图');
subplot(232);imshow(image_dilate,[]);title('膨胀');
subplot(233);imshow(image_close,[]);title('闭');
subplot(234);imshow(image_c_e,[]);title('先闭后腐蚀');
subplot(235);imshow(image_c_o,[]);title('先闭后开');
subplot(236);imshow(image_grad,[]);title('形态梯度');
输出:
先闭后开算法提取的边缘不如先开后闭提取的边缘规则.
因为:
闭的结果造成了白框外噪声块和白框的粘连, 之后的腐蚀没有恢复出直线的边缘.