形态学处理:利用数学形态学作为工具从图像中提取对于表达和描述区域形状有用的图像分量。
数学形态学的语言:二值图像的集合论。显示时黑色表示为1,白色表示为0!
基本处理:
1.扩张/膨胀dilation
将模板中心(结构原点)对准待处理像素,逐点扫描模板下的像素,如果模板中的像素有一点以上和模板下的对应像素的1点相同,则待处理像素为1,否则为0;
2.腐蚀erosion
将模板中心(结构原点)对准待处理像素,逐点扫描模板下的像素,如果模板中的所有1点像素都和模板下的对应像素相同,则待处理像素为1,否则为0;
3.开变换open
先腐蚀再扩张,断开狭窄的连接和消除细小的突出物,平滑较大物体边界的同时而不明显改变其面积。开变换可以去除面积较小的并噪声。
4.闭变换close
先扩张再腐蚀,消除狭窄的间断和细小的鸿沟,填补轮廓线中的断裂。闭变换可以去除面积较小的差噪声。
5.击中击不中变换HIT-MISS
从图像A中探测结构元素B=(w,b)的位置,需要两个结构单元w和b,w探测图像内部,b探测图像外部。w对A腐蚀,b对A的补腐蚀,二者的结果相与,即可找到B的位置。
Matlab代码:
function f_dilate = dilate(f,se,origin)
% dilation operation on binary image
% f --binary image
% se --structure element
% origin --the origin of se
[h,w] = size(f);
[h_se,w_se] = size(se);
ox = origin(1);oy = origin(2);
% 假设模板的最大尺寸为5x5
f_ext = zeros(h+4,w+4); % 扩充背景
f_ext(3:h+2,3:w+2) = f;
f_ext = logical(f_ext);
f_dilate = logical(zeros(h,w)); % 初始化扩张后的图像
% 扫描像素,对每个像素进行处理
for i = 3:h+2
for j = 3:w+2
temp = f_ext(i-ox+1:i+h_se-ox,j-oy+1:j+w_se-oy)&se;
if sum(temp(:))>0
f_dilate(i-2,j-2) = 1;
else
f_dilate(i-2,j-2) = 0;
end
end
end
end
function f_erode = erode(f,se,origin)
% erosion operation on binary image
% f --binary image
% se --structure element
% origin --the origin of se
[h,w] = size(f);
[h_se,w_se] = size(se);
ox = origin(1);oy = origin(2);
% 假设模板的最大尺寸为5x5
f_ext = zeros(h+4,w+4); % 扩充背景
f_ext(3:h+2,3:w+2) = f;
f_ext = logical(f_ext);
f_erode = logical(zeros(h,w)); % 腐蚀后的图像
% 扫描图像,对每个像素进行处理
for i = 3:h+2
for j = 3:w+2
temp = f_ext(i-ox+1:i+h_se-ox,j-oy+1:j+w_se-oy)&se;
if temp==se
f_erode(i-2,j-2) = 1;
else
f_erode(i-2,j-2) = 0;
end
end
end
end
测试代码:
clc,clear
f = [0 0 0 0 0 0 0;
0 0 1 1 0 0 0;
0 0 0 1 0 0 0;
0 0 0 1 1 0 0;
0 0 1 1 1 1 0;
0 0 1 1 1 0 0;
0 1 0 1 0 1 0;
0 0 0 0 0 0 0];
f = logical(f);
se1 = [1 1 1];
se2 = [1 1;0 1];
f_dilate1 = dilate(f,se1,[1,1]);
f_erode1 = erode(f,se1,[1,1]);
figure;
subplot(1,3,1),imshow(~f),title('原图像');
subplot(1,3,2),imshow(~f_dilate1),title('扩张后的图像');
subplot(1,3,3),imshow(~f_erode1),title('腐蚀后的图像');
f_dilate2 = dilate(f,se2,[1,1]);
f_erode2 = erode(f,se2,[1,2]);
figure;
subplot(1,3,1),imshow(~f),title('原图像');
subplot(1,3,2),imshow(~f_dilate2),title('扩张后的图像');
subplot(1,3,3),imshow(~f_erode2),title('腐蚀后的图像');
f_open1 = dilate(f_erode1,se1,[1,1]); % 开变换,先腐蚀后扩张
f_close1 = erode(f_dilate1,se1,[1,1]); % 闭变换,先扩张后腐蚀
figure;
subplot(1,3,1),imshow(~f),title('原图像');
subplot(1,3,2),imshow(~f_open1),title('开变换后的图像');
subplot(1,3,3),imshow(~f_close1),title('闭变换后的图像');
f_open2 = dilate(f_erode2,se2,[1,2]); % 开变换,先腐蚀后扩张
f_close2 = erode(f_dilate2,se2,[1,2]); % 闭变换,先扩张后腐蚀
figure;
subplot(1,3,1),imshow(~f),title('原图像');
subplot(1,3,2),imshow(~f_open2),title('开变换后的图像');
subplot(1,3,3),imshow(~f_close2),title('闭变换后的图像');
运行结果:
结构元素为se1:
结构元素为se2: