腐蚀和膨胀是数学形态学上的名词,如果用于图像处理上则就称为图像二值形态学。
形态学主要是为了获取物体的拓扑和结构信息,通过物体和结构元素相互作用的某些运算,得到物体更本质的形态。当形态学运用到图像处理中,它的主要作用是利用形态学的基本运算,如腐蚀和膨胀运算,对图像进行观察和处理,从而达到改善图像质量的目地;描述和定义图像的各种几何参数和特征。
二值图像的腐蚀和膨胀操作具体如下:
腐蚀的具体操作:用一个结构元素(也可以说成操作数矩阵)一般为3×3大小的,也可以看成一个卷积模板它们的区别就在于卷积模板是以算术运算为基础的,而结构元素是以集合运算为基础的,扫描图像中的每一个像素(关于图像边缘的处理见下面详细分析),用操作数矩阵扫描图像中的每一个像素,操作数矩阵中每一个像素与覆盖的像素做“与”操作,如果全部为1,则图像中的该像素为1,反之为0,
而膨胀操作正好相反,全部为0时,则图像素中的该像素为0,反之为1。
腐蚀的作用是消除物体的边界点,使目标缩小,这个根据操作的过程可以显然的想到,物体的边界处像素值肯定是有0和1,腐蚀操作后这些紧邻着为1的像素点都会变成0,所以腐蚀操作会消除那些小的且无意义的物体,使边界向内部收缩的过程。
相反,膨胀的作用当然是使目标增大,填充物体内细小的空洞,并且平滑物体的边界,边界向外部扩张的作用。
开运算是先腐蚀后膨胀的过程,可以消除图像上细小的噪声,并平滑物体的边界。使对象的轮廓变得光滑,断开狭窄的间断和消除细的突出物 。
imopen函数:该函数功能是对灰度图像执行形态学开运算,即使用同样的结构元素先对图像进行腐蚀操作后进行膨胀操作。调用格式为:
IM2=imopen(IM,SE)
IM2=imopen(IM,NHOOD)
闭运算是先膨胀后腐蚀的过程,可以填充物体内细小的空洞,并平滑物体边界,可使轮廓线更光滑,但与开操作相反的是,闭操作通常消弥狭窄的间断和长细的鸿沟,消除小的空洞,并填补轮廓线中的断裂
imclose函数:该函数功能是对灰度图像执行形态学闭运算,即使用同样的结构元素先对图像进行膨胀操作后进行腐蚀操作。调用格式为:
IM2=imclose(IM,SE)
IM2=imclose(IM,NHOOD)
通常,由于噪声的影响,图象在阈值化后所得到边界往往是很不平滑的,物体区域具有一些噪声孔,背景区域上散布着一些小的噪声物体。连续的开和闭运算可以有效地改善这种情况。有时需要经过多次腐蚀之后再加上相同次数的膨胀,才可以产生比较好的效果。
腐蚀操作会去掉物体的边缘点,细小物体所有的点都会被认为是边缘点,因此会整个被删去。再做膨胀时,留下来的大物体会变回原来的大小,而被删除的小物体则永远消失了。
腐蚀操作: 腐蚀就是使用算法,将图像的边缘腐蚀掉。作用就是将目标的边缘的“毛刺”剔除掉。
erode 函数:该函数能够实现二值图像的腐蚀操作,有以下形式:
BW2= erode(BW1,SE)
BW2= erode(BW1,SE,…,n)
其中:BW2= erode(BW1,SE)表示使用二值结构要素矩阵SE队图像数据矩阵BW1执行腐蚀操作。输入图像BW1的类型为double或unit8,输出图像BW2的类型为unit8。BW2= erode(BW1,SE,…,n)表示执行腐蚀操作n次。
膨胀操作会使物体的边界向外扩张,如果物体内部存在小空洞的话,经过膨胀操作这些洞将被补上,因而不再是边界了。再进行腐蚀操作时,外部边界将变回原来的样子,而这些内部空洞则永远消失了。
膨胀操作:膨胀就是使用算法,将图像的边缘扩大些。作用就是将目标的边缘或者是内部的坑填掉。
dilate函数:该函数能够实现二值图像的膨胀操作,有以下形式:
BW2=dilate(BW1,SE)
BW2=dilate(BW1,SE,…,n)
其中:BW2=dilate(BW1,SE)表示使用二值结构要素矩阵SE队图像数据矩阵BW1执行膨胀操作。输入图像BW1的类型为double或unit8,输出图像BW2的类型为unit8。BW2=dilate(BW1,SE,…,n)表示执行膨胀操作n次。
注:结构元素在扫描图像中的每个像素时,结构元素的邻域有部分会在图像外面。比如当结构元素扫描图像上方第一行像素值(这里默认结构元素为3×3),结构元素会有部分在图像的外面,此时,为了有效处理边界像素,进行形态学运算的函数通常都会给出超出图像、未指定数值的像素指定一个数值,这样就类似于函数给图像填充了额外的行和列。对于膨胀和腐蚀操作,它们对像素进行填充的值是不同的。规则如下:
腐蚀和膨胀填充图像规则表
通过对膨胀操作使用最小值填充和对腐蚀操作使用最大值填充,可以有效地消除边界效应(输出图像靠近边界处的区域与图像其它部分不连续)。否则,如果腐蚀操作使用最小值进行填充,则进行腐蚀操作后,输出图像会围绕着一个黑色边框。(此处根据腐蚀和膨胀的具体操作过程应该不难理解,因为当图像边缘都是白色时也就是像素值全为1,此时如果图像边缘外面的像素值填充为最小值,如果二值图像的话则像素值为0,根据腐蚀操作,相与后肯定为0,这时图像边缘处便会成为黑色)
结构元素:膨胀和腐蚀操作的最基本组成部分,用于测试输出图像,通常要比待处理的图像小的多。二维平面结构元素由一个数值为0或1的矩阵组成。结构元素的原点指定了图像中需要处理的像素范围,结构元素中数值为1的点决定结构元素的邻域像素在进行膨胀或腐蚀操作时是否需要参与计算。三维或非平面的结构元素使用0,1定义结构元素在x和y平面上的范围,第三维z定义高度。
关于图像腐蚀和膨胀的实现:
matlab和openCV都可以实现
matlab语言中自带了关于腐蚀和膨胀的函数,如果想要看实现效果,则可以直接调用,imerode(输入图像,结构元素)和imdilate(输入图像,结构元素),结构元素对象可以是strel函数返回的对象,也可以是一个自己定义的表示结构元素邻域的二进制矩阵。
常用形态学操作函数
可以使用imdilate函数进行图像膨胀,imdilate函数需要两个基本输入参数,即待处理的输入图像和结构元素对象。结构元素对象可以是strel函数返回的对象,也可以是一个自己定义的表示结构元素邻域的二进制矩阵。此外,imdilate还可以接受两个可选参数:PADOPT(padopt) ——影响输出图片的大小、PACKOPT(packopt).——说明输入图像是否为打包的二值图像(二进制图像)。举个实例如下:
步骤1,首先创建一个包含矩形对象的二值图像矩阵。
>> BW=zeros(9,10);
>> BW(4:6,4:7) =1
BW =
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
步骤2,使用一个3×3的正方形结构元素对象对创建的图像进行膨胀。
>> SE=strel('square',3)
SE =
Flat STREL object containing 9 neighbors.
Neighborhood:
1 1 1
1 1 1
1 1 1
步骤3,将图像BW和结构元素SE传递给imdilate函数。
>> BW2=imdilate(BW,SE)
BW2 =
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
步骤4,显示结果。
>> imshow(BW,'notruesize')
>> imshow(BW2,'notruesize')
可以使用imerode函数进行图像腐蚀。imerode函数需要两个基本输入参数:待处理的输入图像以及结构元素对象。此外,imerode函数还可以接受3个可选参数:PADOPT(padopt) ——影响输出图片的大小、PACKOPT(packopt).——说明输入图像是否为打包的二值图像(二进制图像)。M——指定原始图像的行数。
以下程序示例说明了如何对某一副具体图像进行腐蚀操作,腐蚀前后的效果对比如图末。
步骤1,读取图像cameraman.tif (该图像是Matlab当前目录下自带的图片)
>> BW1=imread('cameraman.tif');
步骤2,创建一个任意形状的结构元素对象
>> SE=strel('arbitrary',eye(5));
步骤3,以图像BW1和结构元素SE为参数调用imerode函数进行腐蚀操作。
>> BW2=imerode(BW1,SE);
步骤4,显示操作结果
>> imshow(BW1)
>> figure,imshow(BW2)
bwmorph函数
该函数的功能是: 对二值图像进行数学形态学(Mathematical Morphology)运算。
语法格式: (1) BW2 = bwmorph(BW,operation) 对二值图像进行指定的形态学处理。
(2)BW2 = bwmorph(BW,operation,n) 对二值图像进行n次指定的形态学处理。
其中:对于格式①,bwmorph函数可对二值图像BW1采用指定的形态学运算;对于格式②,bwmorph函数可对二值图像BW1采用指定的形态学运算n次。n可以是Inf(无穷大),这意味着将一直对该图像做同样的形态学处理直到图像不再发生变化。operation是一个字符串, 用于指定进行的形态学处理类型。
operation可以为以下值:
‘clean’:去除图像中孤立的亮点,比如, 一个像素点, 像素值为1, 其周围像素的像素值全为0, 则这个孤立的亮点将被去除;
‘close’:进行形态学闭运算(即先膨胀后腐蚀);
‘dilate’:使用结构元素ones(3)对图像进行膨胀运算;
‘erode’:使用结构元素ones(3)对图像进行腐蚀运算;
'bothat':进行“bottom hat”形态学运算,即返回闭运算减去源图像的图像;
'branchpoints':找到骨架中的分支点;
'bridge':进行像素连接操作;
'diag': 采用对角线填充, 去除八邻域的背景;
'endpoints':找到骨架中的结束点;
'fill':填充孤立的黑点, 比如3*3的矩阵, 除了中间元素为0外, 其余元素全部为1, 则这个0将被填充为1;
'hbreak':断开图像中的H型连接;
'majority':如果一个像素的8邻域中有等于或超过5个像素点的像素值为1, 则将该点像素值置1;
'open':进行形态学开运算(即先腐蚀后膨胀);
'remove':如果一个像素点的4邻域都为1, 则该像素点将被置0;该选项将导致边界像素上的1被保留下来;
'skel':在这里n = Inf,骨架提取但保持图像中物体不发生断裂;不改变图像欧拉数;
'spur':去除小的分支, 或引用电学术语“毛刺”;
'thicken':在这里n = Inf, 通过在边界上添加像素达到加粗物体轮廓的目的;
'thin':在这里n = Inf,进行细化操作;
'tophat':进行“top hat”形态学运算, 返回源图像减去开运算的图像。
基于膨胀与腐蚀的形态操作——骨架化和边缘检测
(1)骨架化:
某些应用中,针对一副图像,希望对图像中所有对象简化为线条,但不修改图像的基本结构,保留图像基本轮廓,这个过程就是所谓的骨架化。提供了专门的函数bwmorph,可以实现骨架化操作。
>> clear;close all
>> BW1=imread('circbw.tif');
>> BW2=bwmorph(BW1,'skel',Inf);
>> imshow(BW1)
>> figure,imshow(BW2)
(2)边缘检测
对于一副灰度二进制图像,如果图像像素值为1,则该像素的状态为ON,如果其像素值为0,则该像素的状态为OFF。在一副图像中,如果图像某个像素满足以下两个条件:
1.该像素状态为ON,
2.该像素邻域中有一个或多个像素状态为OFF。
则认为该像素为边缘像素。
Matlab中提供了专门的函数bwperim,可以用于判断一副二进制图像中的哪些像素为边缘像素。
以下程序代码示例就是利用bwperim函数,对图像circbw.tif进行边缘检测,其边缘像素检测效果如尾图。
>> clear;close all
>> BW1=imread('circbw.tif');
>> BW2=bwperim(BW1);
>> imshow(BW1)
>> figure,imshow(BW2)
基于腐蚀和膨胀的形态操作函数如下:
bwhitmiss 图像逻辑"与"操作,该函数使用一个结构元素对图像进行腐蚀操作后,再使用第二个结构元素对图像进行腐蚀操作
imbothat 从原始图像中减去经过形态关闭后的图像,该函数可用来寻找图像中的灰度槽
imtophat 从原始图像中减去形态开启后的图像,可以用来增强图像的对比度