在实际的应用场景中,为了是检测的范围缩小,将感兴趣的局部区域从图像背景中分离出来,使关键的特征便于辨识和分析,图像分割就是用来处理这种情况。图像的大小、灰度、编辑、形状、颜色和纹理都可以作为图像分割的标准。
一、阈值处理
在实际应用中,选择检测目标的特征进行测量、识别和定位,是常用的图像分割方法,特别适用于检测目标与图像背景有明显区别的情况。
1.1 灰度范围分割
灰度范围分割是最常用的分割方法,假设将灰度范围设置为100~200,则分割算法会将100~200的所有像素分离出来组成一个区域,该区域的像素灰度就在100~200范围内。
当检测目标的图像灰度与目标背景图像灰度有明显差异可以,可以利用该分割方法来分割图像。
read_image(Image,'mvtec_logo.png')
*灰度范围0~100
threshold (Image, Region, 0, 100)
connection (Region, ConnectedRegions)
select_shape(ConnectedRegions,Edges,'area','and',10,1000000)
1.2 直方图自动分割
在实际的应用场景中,产品自身的颜色,灯光的强弱都会影响图像的灰度值,所以手动设置灰度范围是不可靠的,并且我们不能直接获得图像的灰度范围,需要测试范围。
而直方图能够自适应图像的变化,生成相应的灰度范围,直方图是将图像中0~255的像素做数量统计,通过直方图可以得到图像的灰度值分布,在图像单一的情况下,甚至可以计算得到目标的面积和结构。下图就是1.1节中测试图像的灰度直方图。
在halcon中用auto_threshold来处理直方图分割,该算子可以对单通道图像进行多重阈值分割。分割原理是以灰度直方图中出现的波谷为分割点,分割出一个个波峰,因此有多少个波峰就有多少个区域。以下是测试结果
read_image(Image,'mvtec_logo.png')
*第3个参数是平滑因子,值越大,波峰越平滑
auto_threshold (Image, autoRegion, 2)
第三个参数的值越大,可以使波峰变得平滑,减少波峰数量,分割的区域也将减少。
1.3 自动全局阈值分割
binary_threshold算子自动对直方图波峰图像进行自动阈值分割,该算子对于在均匀照明背景下分割字符非常有用。
最后得到的阈值由方法中给出的方法确定,即“最大可分离性”和“平滑组织”,这两种方法都只能用于具有双峰直方图的图像。
read_image (Image, 'ocr/article_label_03.png')
binary_threshold (Image, Region, 'max_separability', 'dark', UsedThreshold)
第4个参数表示对图像的暗部分进行分割,最后一个参数是得到的阈值。
1.4 局部阈值分割
有时候实际的情况得到的图像无法用某一阈值进行分割,比如目标区域的灰度变化太大,有点部分暗,有的部分亮。而dyn_threshold算子可以对邻域进行灰度对比,找到合适的方法进行分割。以下是一个例子。
read_image (Image, 'text.bmp')
*由于图像对比度比较低,对图像进行相乘,增强对比度
mult_image (GrayImage, GrayImage, ImageResult, 0.005, 0)
*使用平滑滤波器对原始图像进行适当平滑
mean_image (ImageResult, ImageMean, 50,50)
*动态阈值分割,提取字符区域
dyn_threshold (ImageResult, ImageMean, RegionDynThresh, 4, 'not_equal')
*开运算,去除无意义的小的杂点
opening_circle (RegionDynThresh, RegionOpening, 1.5)
使用该算子前通常先进行平湖滤波,然后该算子比较原始图像与均值处理后的图像作对比,从而将差异大的点提取出来。
算子的第1个参数是原始图像,第2个参数是预处理后的图像,这里使用均值图像,用于局部对比。第3个参数是阈值区域,第4个参数是offset值,将原图与均值作对比后设定的值,灰度差异大于该值的区域被提取出来。第5个参数决定了提取的是哪部分区域。
- light:表示原图中大于等于预处理图像像素点值加上 offset值的像素被选中。
- dark:表示原图中小于等于预处理图像像素点值减去offset值的像素被选中。
- equal:表示原图中像素点大于预处理图像像素点值减去 offset值,小于预处理图像像素点值加上 offset值的点被选中。
- not_equal:表示与equal相反,它的提取范围在 equal范围以外。
1.5 字符动态全局分割
char_threshold适用于在亮背景上的暗字符的提取,该算子主要根据Sigma来平滑直方图,最后将前景后背景区分开来。
分割的阈值取决于直方图中的最大值,如果选择的是95%,灰度阈值将设定为为5%左右的区域,因为该算子默认图像为亮背景暗字符。例子如下。
read_image (Alpha1, 'alpha1')
char_threshold (Alpha1, Alpha1, Characters, 6, 95, Threshold)
gray_histo (Alpha1, Alpha1, AbsoluteHisto, RelativeHisto)
二、区域生长法
如果想要获得具有相似灰度的相连区域,可以使用区域生长法寻找相邻的符合条件的像素。区域生长法的基本思想是,在图像上选定一个“种子”像素或“种子”区域,然后从“种子”的邻域像素开始搜索,将灰度或者颜色相近的像素附加在“种子”上,最终将代表同一物体的像素全部归属于同一“种子”区域,达到将目标物体分割出来的目的。
区域生长法的算法执行速度非常快,适用于对检测速度要求高的情况。
2.1 regiongrowing
regiongrowing(Image : Regions : RasterHeight, RasterWidth, Tolerance, MinSize : )
- Image:输入的单通道图像。
- Regions:输出的一组区域。
- Row和Column:分别为矩形区域的宽和高,需要是奇数,以便计算中心点坐标。
- Tolerance:为灰度差值的分割标准。如果另一个点的灰度与种子区域的灰度差值小于 Tolerance,则认为它们可以合并为同一区域。
- MinSize:表示输出区域的最小像素数。
该算子工作步骤如下。
- 设定一个尺寸为Row*Column的卷积核,以及一个作为分界依据的像素灰度差值Tolerance。
- 使用上述指定尺寸的卷积核在原图上进行扫描,并计算卷积核内矩形图像的中心点灰度与邻域矩形图像的中心点灰度差。如果差值小于Tolerance,则将这两个矩形区域合并为同一个。
- 对合并后的区域进行判断,如果该区域包含的像素数大于设定的MineSize,则输出结果区域。
注意:卷积核默认为1*1,一般长宽都为奇数。如果大于1*1,需要先对图像进行平滑处理,平滑的卷积核大小至少为Row*Colum,这是为了使矩形中心更突出。如果图像上的噪点比较多并且卷积核比较小,也可以省略平滑这一步骤,以减少误判。
以下为测试例子:
read_image(Image,'test2.jpg')
*对原图进行了均值处理,选用了5*5的滤波器
mean_image(Image,Mean,5,5)
*使用了区域生长算子寻找颜色相似的邻域
regiongrowing(Mean,Regions,1,1,3.0,1000)
*对提取区域做了形态学处理,使区域更加平滑和完整
closing_circle (Regions, RegionClosing, 3.5)
2.2 regiongrowing_mean
regiongrowing_mean(Image : Regions : StartRows, StartColumns, Tolerance, MinSize : )
其中各参数的含义如下。
- Image:为输入的单通道图像。
- Regions:为输出的一组区域。
- StartRows和StartColumns分别为起始生长点的坐标。
- Tolerance:为灰度差值的分割标准。如果另一个点的灰度与种子区域的灰度差值小于Tolerance,则认为它们可以合并为同一区域。
- MinSize:为输出区域的最小像素数。
该算子指明了开始进行区域生长算法的点(x, y)的坐标,并以指定的点为中心,不断搜索其邻域,寻找符合设定条件的区域。这里的条件有两种,一是区域边缘的灰度值与当前均值图中对应的灰度值的差小于Tolerance参数的值,二是区域包含的像素数应大于 MinSize参数的值。测试例子如下:
read_image(Image,'test2.jpg')
*对原图进行了均值处理,选用了“circle”类型的中值滤波器
median_image (Image, ImageMedian, 'circle', 2, 'mirrored')
*使用了区域生长算子寻找颜色相似的邻域
regiongrowing (ImageMedian, Regions, 1, 1, 3, 500)
*对图像进行粗略的区域分割,提取满足条件的各个独立区域
shape_trans (Regions, Centers, 'inner_center')
connection (Centers, SingleCenters)
*对初步提取的区域计算出了中心点坐标
area_center (SingleCenters, Area, Row, Column)
*以均值灰度图像为输入,进行区域生长计算,计算的起始坐标为上一步的各区域中心
regiongrowing_mean (ImageMedian, RegionsMean, Row, Column, 50, 500)
三、分水岭算法
分水岭算法是一种典型的基于边缘的图像分割算法,通过寻找区域之间的分界线,对图像进行分割。“分水岭”这个名字与一种地貌特点有关,它的思想是,把图像的灰度看作一张地形图,其中像素的灰度表示该地点的高度。灰度值低的区域是低地,灰度值越高,地势越高。
低地聚集的地方如同一块盆地,如果模拟向整片区域注水,那么每块盆地将成为一个单独的积水区,即图像上的分割区域,盆地与盆地之间的边界就是区域的边界。随着注水的量越来越多,盆地的积水面积会不断扩大,边界区域则会越来越小,最后形成的分割边界就是分水岭。
分水岭算法能较好地适用于复杂背景下的目标分割,特别是具有蜂窝状结构的画面的内容分割。Halcon中使用 watersheds 算子提取图像的分水岭。
read_image (Image, 'woodboard.jpg')
*将原始图转化为灰度图。便与后续的平滑处理
rgb1_to_gray (Image, GrayImage)
*对单通道图像进行高斯平滑处理,以去除噪声
gauss_filter (GrayImage, ImageGauss, 11)
*对高斯平滑后的图像进行分水岭处理,阈值分割,提取出盆地区域
watersheds (ImageGauss, Basins1, Watersheds)
watersheds_threshold(ImageGauss, Basins, 50)
最后得到的就是图像谷底区域。