目录
一、表示
1.边界追踪
本章中的算法要求一个区域的边界上的点以顺时针(或逆时针)方向排序。首先是边界追踪算法,它的输出是排过序的点的序列。给定一个二值图像R或其边界,追踪R的边界或给定边界的算法的步骤为:
- 令起始点
为图像中左上角标记为1的点。
表示
西侧的邻点。从
开始按顺时针方向考察
的8个邻点。令
表示遇到的值为1的第一个邻点,并令
是序列中
之前的点。存储
和
的位置。
- 令b=
和c=
- 从c开始按顺时针方向行进,令b的8个邻点为
。找到标为1的第一个
- 令b=
和c=
- 重复3和4,直到b=
且找到下一个边界点
当上述算法结束之后,就可以找到排列后的边界点的集合。如果目的是找到一个区域中的空洞的边界,一个方法就是提取这些孔洞,并将它们作为0值背景上的1值区域来处理。
2.链码
链码用于表示由顺次连接的具有指定长度和方向的直线段组成的边界。这种表示基于线段的4连接或8连接(如下图),每个线段的方向使用数字编号方案编码,这种编码叫做佛雷曼编码。
数字图像通常是以一种网格形式来获取并处理的,网格中x和y方向的间距相等,所以链码可以通过追踪一个边界产生,但是这可能会导致(1)得到的链码太长(2)噪声或不完美分割沿边界引起的任何较小干扰都会导致编码的变化。解决的方法是选取一个较大的网格间距来对边界重取样。结果编码表示的精度取决于取样网格的间距。
边界的链码取决于起始点,链码可以通过一个简单的过程关于起始点归一化。其次也可以通过旋转归一化,方法就是使用链码的一次差分来替代链码本身,这个差分是通过计算链码中分隔两个相邻像素的方向变化的数得到的。
3.多边形近似
多边形近似的目的是使用尽可能少的线段来获取给定边界的基本形状,其中最有力的一种技术是使用最小周长多边形(MPP)来表示边界。
产生计算MMP的算法可以使用下图来进行解释:
将边界想象为橡皮筋,当其收缩时会受到内外边界的约束,最终产生一个最小周长的多边形,被限制在一个区域内。单元的大小多边形近似的精度。在一个给定应用中,目的是使用合适的最大可能单元大小,以最少的顶点数来产生MPP。只有内墙的凸顶点和外墙的凹顶点才能成为MPP的顶点。
单元组合体是围成一条数字边界的单元集合。MMP算法有如下的性质:
- 由简单连接的单元组合体为界的MMP是非自相交的
- MMP的每个凸顶点都是一个W(白)顶点,并非边界的每个W顶点都是MMP上的一个顶点
- MMP的每个镜像凹顶点都是一个B(黑)顶点,并非边界的每个B顶点都是MMP上的一个顶点
- 所有的B顶点要么在MMP上,要么在MMP外;W顶点也一样
- 单元组合体中包含的顶点序列的最左上角顶点,总是MMP的一个W顶点
其次还可以通过聚合方法来实现多边形近似,它是基于平均误差或其他准则的。一种方法是沿一条边界来聚合一些点,直到拟合这些点的直线的最小均方差超过一个预设的阈值。当条件出现时,存储该直线的参数,将误差设为0重复上述过程。沿边界聚合新的点,直到方差再次超过阈值。相邻线段的交点就是多边形的顶点。难点在于得到的近似顶点并不总是对应于原始边界中的形变。
另一种方法是分裂技术,它将线段不断细分为两部分,直到满足规定的准则为止。其下为一个对应实验,代码为:
import cv2
from matplotlib import pyplot as plt
import numpy as np
# 读取图像
image = cv2.imread(r'D:\test\bian.png', cv2.IMREAD_GRAYSCALE)
_, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV)
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contour = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(contour)
epsilon = 0.01 * cv2.arcLength(contour, True)
approx_polygon = cv2.approxPolyDP(contour, epsilon, True)
result_image = cv2.cvtColor(binary_image, cv2.COLOR_GRAY2BGR)
cv2.drawContours(result_image, [approx_polygon], -1, (0, 255, 0), 2)
cv2.drawContours(result_image, [contour], -1, (255, 0, 0), 1)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(131), plt.imshow(cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)), plt.title('原始图像'), plt.axis('off')
plt.subplot(132), plt.imshow(binary_image, plt.cm.gray), plt.title('灰度图像'), plt.axis('off')
plt.subplot(133), plt.imshow(result_image, plt.cm.gray), plt.title('MMP结果'), plt.axis('off')
plt.show()
结果为:
该程序先对图像进行二值化处理将其转化为二值图像,然后就是使用 findContours函数来查找轮廓之后在其二值图像上面绘制出轮廓图像。
4.标记图
标记图是边界的一维函数表示,可以使用各种方式来生成。最简单的方法是以角度的函数形式画出质心到边界的距离。其基本概念都是将边界表示简化为描述起来可能比原始二维边界更简单的一维函数。
可以通过一种选取相同起始点来生成标记图的方法,实现关于旋转的归一化,而不用考虑形状的方向。一种方法是将距质心最远的点选为起始点,假设该点对于我们感兴趣的每个形状而言是位移的,另一种方法是在本征轴上选取距质心最远的点。,还有一种方法就是获取该边界的链码,然后使用链码中的方法。
形状大小的变化会导致相应标记图的幅值变化,解决的方法一种为对所有函数进行缩放,使他们有相同的值域;另一种是将每个样本除以标记图的方差。两种方法的基本思想都是消除对尺寸的依赖性,同时保持波形的形状。
还可以通过沿着边界行进,并对应于边界上的每一个点,画出边界线在这点的切线和参考线之间的角度。
5.边界线段
将边界分解为线段可以降低边界的复杂性,简化描述过程。尤其是当边界线包含一个或多个携带形状信息的明细凹度时。按照下图而言,区域边界的分割的方法是追踪S的轮廓,并标记进入或者离开一个凸缺的变换点。
由于数字化、噪声和分割的变形的影响,数字边界一般是不规则的。可以通过在对边界分割前用前面的方法来平滑边界。一种方法为追踪边界,并使用一个像素沿该边界的k个相邻像素的平均坐标代替这个像素的坐标,适用于较小的不规则边界;另一种方法比较稳定,是在找到一个区域的凸缺前,先使用多边形近似。
6.骨架
表示一个平面区域的结构形状的一种重要方法是将它简化为图形,简化可以通过一种细化(骨架化)算法得到该区域的骨架来实现。细化过程在大范围的图像处理问题中其核心作用。一个区域的骨架可以用中轴变换(MAT)来定义。假定一个区域R的边界为B,对于R中的每个点p,在B中找到其最近的邻点,如果p有多个这样的邻点,那么p属于R的中轴(骨架)。
直接实现MAT的定义会耗费大量的时间,因此提出了一个迭代删除一个区域的边界点的细化算法,删除时的约束为:(1)不能删除端点(2)不能破坏连续性(3)不能导致区域的过度腐蚀。假定有两个步骤,步骤一为(a) (b)
(c)
(d)
;步骤二时步骤一中的(a)和(b)不变,c和d变为
和
。下图为细化所用的邻域像素排列。
细化算法的一次迭代为:(1)应用步骤一,标记将被删除的边界点;(2)删除做了标记的点;(3)应用步骤二来标记将被删除的剩余的边界点;(4)删除标记的点。一直重复上述过程直到没有可被删除的点,那么就生成了该区域的骨架。
二、边界描述子
1.简单的描述子
边界的长度时最简单的描述子之一,一条边界上的像素数量可以给出其长度的粗略估计。边界B的直径定义为。直径的值和连接组成该直径的连个端点的直线段(边界的长轴)的方向时边界的有用描述子。基本矩形是由边界与两个轴相交的4个外部点所组成的方框,长轴和短轴之比是边界的偏心率,也是一个有用的描述子。曲率是斜率的变化率。
2.形状数
下图为阶为4,6,8的全部形状和链码、差分以及形状数。已编码的边界取决于网格的方向。
3.傅里叶描述子
下图为一个xy平面内的一个K点数字边界,每个坐标可以当作一个复数来处理,即,x为复数序列的实轴,y为虚轴。它把二维问题简化成了一维问题。
s(k)的离散傅里叶变换为,复数系a(u)叫做边界的傅里叶描述子。傅里叶描述子并非直接的对平移,缩放等几何变化不敏感,这些参数的变化可能与描述子的简单变换是相关的。下表为经过变换之后的傅里叶描述子。
4.统计矩
边界线段(和标记图波形)的形状可以使用统计矩来定量描述。将幅度g视为一个离散随机变量v,并形成一个幅度直方图。则关于其均值v的第n阶矩为,m为v的均值。可以使用g(r)归一化为单位面积,则上式变为
。
直接和g(r)的形状相关。矩是最流行的方法,但不是用于将任务的描述简化为一维函数的描述的唯一描述子。它的优点是实现十分简单且携带了边界形状的物理解释。
三、区域描述子
1.简单的描述子
一个区域的面积定义为该区域中像素的数量,区域的周长是其边界的长度,面积和周长用于度量一个区域的致密性。还有一个致密性描述子是圆周率。此外还有一些别的简单的描述子比如灰度级的均值和中值、最小灰度值和最大灰度值以及其值高于或低于均值的像素数。
2.拓扑描述子
拓扑特性对于图像平面区域的整体描述很有用,拓扑学是研究未受任何变形影响的图形的性质,前提是该图像未被撕裂或粘连。拓扑学特性与距离或基于距离度量概念的任何特性无关。还有一个有用的拓扑学特性是连通分量的数量。
欧拉数E也是一个拓扑特性,可以使用图像中孔洞的数量H减去连通分量的数量C得到,它可以非常简单的解释由直线线段表示的区域(多边形网络)。如果用V表示顶点数,Q表示边数,F表示面数,那么可以得到如下的欧拉公式:
3.纹理
量化一个区域的纹理内容是描绘区域的一个重要的方法。纹理这种描述子提供了诸如平滑度、粗糙度和规律性等特性的度量。主要用统计方法、结构方法和频谱方法来描述区域纹理。
统计方法是描述纹理的最简方法之一,会生成诸如平滑、粗糙、粒状的等纹理特征。其方法就是使用一幅图像或一个区域的灰度级直方图的统计矩。二阶矩在纹理描述中特别重要,是灰度对比度的度量,可建立相对平滑度的描述子。三阶矩是直方图偏斜度的度量,四阶矩是直方图相对平坦度的度量。令Q是定义两个像素彼此相对位置的一个算子,并考虑一幅具有L个可能灰度级的图像f。令G为一个矩阵,其中元素是灰度
和
的像素对出现在f中由Q所指定的位置处的次数。这样生成的矩阵叫做灰度级共生矩阵。下图为矩阵特性的描述子及其公式:
结构技术处理图像像元的排列,如基于规则间距平行线的纹理描述。
频谱技术基于傅里叶频谱特性,主要用于检测图像中的全局周期性,方法是识别频谱中的高能量的窄波峰。傅里叶频谱适合描述图像中的二维周期或近似二维周期模式的方向性。这边主要考虑对纹理描述有用的三个特征:
- 频谱中突出的尖峰给出纹理模式的主要方向
- 频率平面中尖峰的位置给出模式的基本空间周期
- 采用滤波方法消除任何周期分量而留下非周期性图像元素,然后采用统计技术来描述
频谱特征的检测和描述可以使用极坐标表达来简化。用于定量表征频谱-能量描述的特征可以使用的典型描述子为最高值的位置、幅度和轴向变化的均值与反差以及该函数的均值和最高值之间的距离。
4.不变矩
大小为M*N的数字图像f(x,y)的二维(p+q)阶矩定义为。相对应的(p+q)阶中心矩定义为
。之后可以有二阶矩和三阶矩推出7个不变矩组,这些矩组对于平移、尺度变化、镜像和旋转是不变的。
四、使用主分量进行描绘
使用主分量进行描绘适用于边界和区域,也是描绘一组空间上已配准图像的基础,但这些已配准图像的对应像素值是不同的。向量总体协方差矩阵可以定义为,通过转化,可以将上式近似为
。
霍特林变换的表达式为。其得到的y向量的均值为0,其次它可以处理y重建x的问题。霍特林变换也被称为主分量变换,因为它使用了对应于最大特征值的特征向量的思想。
五、关系描绘子
关系描述子同样可以用来描述边界和区域,主要目的是以重写规则的形式来获取边界或区域中的基本重复模式。使用字符串描述图像的应用均是基于从感兴趣物体中提取连接线段的思想。一种方法是追踪一个物体的轮廓,并使用指定方向和/或长度的线段来对结果进行编码。另一种是使用有向线段来描述图像的各个部分。字符串描述最适合于应用中的基元连接性可以一种从头到尾的方式或其他连续方式来表达。
可以使用树描述子来处理类似纹理和其他描述子区域可能不连续的情况。树的末梢是树底端的节点集合,采用从左到右的顺序排列。树中有两种类型的关键信息:(1)关于节点的信息,是以描述节点的一组字来存储的(2)一个节点与其相邻节点相联系的信息,是以指向那些相邻节点的一组指针来存储的。第一类信息用于识别一幅图像子结构,第二类信息定义这个子结构与其他子结构间的物理关系。
总结
本章主要讲了如何将图像转化为可量化的特征,因为对于边界和区域的描述是图像处理中的前期步骤,这些描述将会构成图像处理下一步过程所需要的输入信息。需要通过这些可量化的特征来实现后续的功能。本章先讲了一些相关的技术的知识,然后讲了许多的描述子包括边界描述子和区域描述子,并对什么时候使用哪种描述子做出了讲解。