形态学是图像处理中应用最为广泛的技术之一,主要用于从图像中提取对表达和描绘区域形状有意义的图像分量,使后续的识别工作能够抓住目标对象最为本质的形状特征,如边界和连通区域等。同时像细化、像素化和修剪毛刺等技术也常应用于图像的预处理和后处理中,成为图像增强技术的有力补充。
形态学的基本思想是利用一种特殊的结构元来测量或提取输入图像中相应的形状或特征,以便进一步进行图像分析和目标识别。
一、腐蚀与膨胀
在经阈值处理提取出目标区域的二值图像之后,区域边缘可能并不理想,这时可以使用腐蚀或膨胀操作对区域进行“收缩”或“扩张”。腐蚀和膨胀是两种最基本也是最重要的形态学运算, 它们是很多高级形态学处理的基础, 很多其他的形态学算法都是由这两种基本运算复合而成。
1.1 结构元素
结构元素在算子参数中的名称为 StructElement,在腐蚀与膨胀操作中都需要用到。结构元素是类似于“滤波核”的元素,或者说类似于一个“小窗”,在原图上进行“滑动”,这就是结构元素,
可以指定其形状和大小。结构元素一般由0和1的二值像素组成。结构元素的原点相当于“小窗”的中心,其尺寸由具体的腐蚀或膨胀算子指定,结构元素的尺寸也决定着腐蚀或者膨胀的程度。结构元素越大,被腐蚀消失或者被膨胀增加的区域也会越大。
结构元素的形状可以根据操作的需求进行创建,可以是圆形、矩形、椭圆形,甚至是指定的多边形等。可以通过gen_circle、gen_rectanglel,gen_ellipse,gen_region_polygon等算子创建需要的形状并指定尺寸。
1.2 图像腐蚀
腐蚀操作是对所选区域进行“收缩”的一种操作,可以用于消除边缘和杂点。腐蚀区域的大小与结构元素的大小和形状相关。其原理是使用一个自定义的结构元素,如矩形、圆形等,在二值图像上进行类似于“滤波”的滑动操作,然后将二值图像对应的像素点与结构元素的像素进行对比,得到的交集即为腐蚀后的图像像素。
经过腐蚀操作,图像区域的边缘可能会变得平滑,区域的像素将会减少,相连的部分可能会断开。即使如此,各部分仍然属于同一个区域。
Halcon中有许多与腐蚀操作相关的算子,比较常用的有erosion_circle算子和erosion_rectangle1算子。
erosion_circle算子使用圆形进行腐蚀操作,原型如下:
void ErosionCircle(const HObject& Region,
HObject* RegionErosion,
const HTuple& Radius)
其中各参数的含义如下。
- Region:为输入图像中的区域,该区域往往是由上一环节的某种分割操作得到的输出结果,如阈值处理提取的区域等。
- RegionErosion:为输出的腐蚀后的区域。
- Radius:为圆形结构元素的半径。其具体值取与想要被去除的杂点的大小有关。因为小于这个圆形结构元素的点都会被移除,而该圆形的直径一般是一个奇数,如3、5、7、9等,所以该半径取值一般会取1.5、2.5、3.5、4.5默认值是3.5。
用腐蚀算子去除毛刺。
read_image (Image, 'test.jpg')
threshold (Image, Region, 0, 10)
erosion_circle (Region, RegionErosion, 1)
Halcon其他腐蚀算子:
- erosion1:用一个自定义的结构元素对输入区域进行腐蚀操作。这个自足义的结构元素需要预先创建,可能具圆形、矩形、多边形,其至是点,等等。
- crosion2:使用一个参考点对输入区域进行腐蚀操作。这个算子中的结构元素有一个参考点,这个点与crosionl中的点不同,它可以是指定的任意一点。
- crosion_golay:使用的结构元素来自格雷字母表,通过定义结构元素对输入区域进行腐蚀操作。
- erosion_seq:与erosion_golay类似,使用格雷字母表中的元素对输入区域进行连续的腐蚀操作。
1.3 图像膨胀
与腐蚀相反,膨胀是对选区进行“扩大”的一种操作。其原理是使用一个自定义的结构元素,在待处理的二值图像上进行类似于“滤波”的滑动操作,然后将二值图像对应的像素点与结构元素的像素进行对比,得到的并集为膨胀后的图像像素。
经过膨胀操作,图像区域的边缘可能会变得平滑,区域的像素将会增加,不相连的部分可能会连接起来,这些都与腐蚀操作正好相反。即使如此,原本不相连的区域任然属于各自的区域,不会因为像素重叠就发生合并。
Halcon中有许多与膨胀操作相关的算子,比较常用的有dilation_circle算子和dilation_rectanglel算子,它们分别使用圆形与矩形结构元素对输入区域进行膨胀操作。这里以 dilationcircle算子为例进行说明。dilation_circle算子的原型如下:
void DilationCircle(const HObject& Region,
HObject* RegionDilation,
const HTuple& Radius)
其中各参数的含义如下。
- Region:为输入的区域。
- RegionDilation:为输出的膨胀后的区域。
- Radius:为圆形结构元素的半径,该半径的大小决定了膨胀的程度。其具体取值与待填补的空洞大小有关。该半径默认值依然是3.5。
下面例子通过膨胀来填补空洞区域。
read_image (Image, 'fingerprint.png')
threshold (Image, Region, 0, 150)
dilation_circle (Region, RegionDilation, 3.5)
Halcon其他膨胀算子:
- dilation1:用一个自定义的结构元素对输入区域进行膨胀操作。结构元素需要预先创建好,这个自定义的结构元素可能是圆形、矩形、多边形,甚至是点,等等。
- dilation2:使用一个参考点对输入区域进行膨胀操作。这个算子中的结构元素有一个参考点,这个点与dilation1中的点不同,这个参考点可以是指定的任意一点。
- dilation_golay:使用的结构元素来自格雷字母表,通过定义结构元素对输入区域进行膨胀操作。
- dilation_seq:与dilation_golay类似,使用格雷字母表中的元素对输入区域进行连续的膨胀操作。
二、开运算与闭运算
腐蚀与膨胀是形态学运算的基础,在实际检测的过程中,常常需要组合运用腐蚀与膨胀对图像进行处理。开运算与闭运算组合使用这两种操作,在保留图像主体部分的同时,处理图像中出现的各种杂点、空洞、小的间隙、毛糙的边缘等。合理地运用开运算与闭运算,能简化操作步骤,有效地优化目标区域,使提取出的范围更为理想。
2.1开运算
开运算的计算步骤是先腐蚀,后膨胀。通过腐蚀运算能去除小的非关健区域,也可以把离得很近的元素分隔开,再通过膨胀填补过度腐蚀留下的空隙。因此,通过开运算能去除孤立的、细小的点,平滑毛糙的边缘线,同时原区域面积也不会有明显的改变,类似于一种“去毛刺”的效果。
下面是通过圆形结构来消除毛刺。
read_image (Image, 'test.jpg')
threshold (Image, Region, 0, 150)
gen_circle (Circle, 6, 6, 7)
opening (Region, Circle, RegionOpening)
参数2是输入的结构元素,用改结构元素进行运算。Halcon其他开算子:
- opening circle:使用圆形结构元素对区域进行开运算处理。
- opening rectanglel:使用矩形结构元素对区域进行开运算处理。(3 ) opening golav:使用格雷字母表中的元素对区域进行开运算处理。
- opening seq:分隔重叠的区域。该算子一般是erosionl、connection和 dilation1算子的连续使用。如果重叠的区域小于结构元素,相交的两个区域将被分隔开来。
2.2闭运算
闭运算的计算步骤与开运算正好相反,为先膨胀,后腐蚀。这两步操作能将看起来很接近的元素,如区域内部的空洞或外部孤立的点连接成一体,区域的外观和面积也不会有明显的改变。通俗地说,就是类似于“填空隙”的效果。与单独的膨胀操作不同的是,闭运算在填空隙的同时,不会使图像边缘轮廓加粗。
如一下例子,填补空隙。
read_image (Image, 'pcb.png')
threshold (Image, Region, 0, 70)
gen_circle (Circle, 6, 6, 10)
closing (Region, Circle, RegionClosing)
三、灰度图像的形态学
以上介绍的各种算子都是基于区域的,输入的参数类型是Region,而如果要对灰度图像Image进行形态学操作,可以使用与灰度图像相关的算子。
3.1灰度图像与区域的区别
基于区域的形态学运算与基于灰度图像的形态学运算的根本区别在于,二者输入的对象不同。前者输入的是一些区域,并且这些区域是经过阈值处理的二值图像区域,而后者的输入则是灰度图像。
当输入对象是一些二值区域时,这些区域就成了算子的主要操作对象。区域的灰度是二值的,并不会发生变化。形态学运算改变的是这些区域的形状,如通过腐蚀使区域面积变小,或者通过膨胀使区域面积变大等。
而当输入对象是灰度图像时,形态学运算改变的则是像素的灰度,表现为灰度图像上的亮区域或暗区域的变化。
腐蚀运算是将图像中的像素点赋值为其局部邻域中灰度的最小值,因此图像整体灰度值减少,图像中暗的区域变得更暗,较亮的小区域被抑制。
膨胀运算是将图像中的像素点赋值为其局部邻域中灰度的最大值,经过膨胀处理后,图像整体灰度值增大,图像中亮的区域扩大,较暗的小区域消失。
3.2 灰度图像形态学
以下例子分别用腐蚀、膨胀、开运算和闭运算来处理灰度图像。
read_image (ImageColor, 'pcb.png')
rgb1_to_gray (ImageColor, Image)
*进行灰度图像腐蚀操作
gray_erosion_shape (Image, ImageMin, 11, 11, 'octagon')
*进行灰度图像膨胀操作
gray_dilation_shape (Image, ImageMax, 11, 11, 'octagon')
*进行灰度图像开运算操作
gray_opening_shape (Image, ImageOpening, 7, 7, 'octagon')
*进行灰度图像闭运算操作
gray_closing_shape (Image, ImageClosing, 7, 7, 'octagon')
- 灰度图像腐蚀:图像变暗了,这是因为图像中较亮的局部区域被收缩了,较暗的区域被扩大了,因而图像变暗了。
- 灰度图像膨胀:较亮的局部区域被“扩大”了,而较暗的区域被“收缩”了,图像整体变得更亮。
- 灰度图像开运算:图像中较亮的小细节消失。
- 灰度图像闭运算:图像中较暗的一些点消失了,类似于灰度图像中的“小孔隙”被填补了,同时较亮的区域的边缘更清晰了。
1.灰度图像的腐蚀运算算子:
- gray_erosion_rect :使用矩形的 mask进行腐蚀操作。
- gray_erosion_shape :使用选定的形状mask进行腐蚀操作。
2.灰度图像的膨胀运算算子:
- gray_dilation_rect :使用矩形的mask进行膨胀操作。
- gray_dilation_shape :使用选定的形状 mask进行膨胀操作。
3.灰度图像的开运算算子:
- gray_opening:对图像进行灰度值的开运算。
- gray_opening _rect :使用矩形的mask对图像进行灰度值的开运算。gray_opening _shape :使用选定的形状 mask对图像进行灰度值的开运算。
4.灰度图像的闭运算算子:
- gray closing :对图像进行灰度值的闭运算。
- gray_closing rect:使用矩形的mask对图像进行灰度值的闭运算。
- gray closing shape:使用选定的形状mask对图像进行灰度值的闭运算。