漫谈《数字图像处理》之形状数的原理与计算方法
在数字图像处理的形状描述中,弗里曼链码虽能有效记录边界像素的方向信息,但存在旋转依赖性(边界旋转后链码改变)与起点依赖性(编码起点不同链码不同)两大问题,导致同一形状可能对应多个不同链码,无法实现唯一标识。而形状数(即最小幅度的一阶差分) 正是为解决这一矛盾而生 —— 其核心目标是通过对弗里曼链码的差分运算与序列优化,生成唯一、归一化的形状描述符,同时具备旋转不变性与起点不变性,成为形状匹配、目标识别的关键工具。
一、形状数的核心特性:解决两大依赖性问题
形状数的价值源于其对弗里曼链码的 “去依赖” 优化,具体通过两大特性实现:
- 旋转不变性:继承一阶差分的本质属性 —— 弗里曼链码的一阶差分描述的是 “相邻链码的方向差值”,而非绝对方向。无论边界如何旋转,相邻像素的方向相对关系始终不变,因此一阶差分序列(及后续的最小幅度序列)不会随旋转改变。
- 起点不变性:通过 “循环移位找最小值” 实现 —— 同一形状的弗里曼链码,即使编码起点不同,其对应的一阶差分序列也只是 “循环移位关系”(如序列 [A,B,C,D] 与 [B,C,D,A])。将所有移位序列转化为数值并选取最小者,即可消除起点差异,确保同一形状对应唯一的形状数。
二、计算前提:弗里曼链码的一阶差分如何求解?
形状数的计算需以 “一阶差分序列” 为基础,而一阶差分的核心是通过相邻链码的差值取模运算,消除旋转对链码的影响。以下分 “基础前提”“计算步骤”“实例演示” 三部分详细说明:
1. 明确基础前提
在计算一阶差分前,需先确定两个关键参数:
- 弗里曼链码的方向数(k):常用两种规格,需提前固定(后续计算需统一):
- 4 方向链码:方向值为 0(右)、1(上)、2(左)、3(下),k=4;
- 8 方向链码:在 4 方向基础上增加 4 个对角线方向(0 = 右、1 = 右上、2 = 上、3 = 左上、4 = 左、5 = 左下、6 = 下、7 = 右下),k=8。
- 闭合的原始链码序列:设边界的弗里曼链码为闭合序列\(C = [c_1, c_2, ..., c_n]\),其中\(c_i\)为第 i 个像素的方向值(4 方向 0-3,8 方向 0-7)。因边界闭合,需满足 “最后一个链码\(c_n\)与第一个链码\(c_1\)相邻”,即计算时需将序列视为 “首尾衔接” 的循环结构。
2. 一阶差分的核心计算步骤
一阶差分的本质是 “当前链码与下一个链码的方向相对差值”,需通过模 k 运算确保结果落在有效方向范围内(0~k-1),具体分两步:
1) 计算相邻链码的差值:对每个链码\(c_i\)(i 从 1 到 n),找到其 “下一个链码\(c_{i+1}\)”—— 若 i=n(最后一个链码),则下一个链码为\(c_1\)(因边界闭合),计算差值\(\Delta = c_{i+1} - c_i\)。
2) 对差值进行模 k 运算:由于差值可能为负数(如\(c_{i+1}=1\)、\(c_i=3\)时,\(\Delta=-2\)),需通过模 k 运算将结果转为 0~k-1 的正数范围,即:\(d_i = \Delta \mod k\) 其中\(d_i\)为第 i 个一阶差分,最终形成一阶差分序列\(D = [d_1, d_2, ..., d_n]\)。
3. 实例演示:4 方向链码的一阶差分计算
假设某闭合边界的 4 方向弗里曼链码为\(C = [0, 0, 1, 2, 2, 3, 0]\)(n=7,k=4),计算过程如下:
- \(c_1=0\):下一个链码\(c_2=0\),\(\Delta=0-0=0\),\(d_1=0 \mod 4 = 0\)
- \(c_2=0\):下一个链码\(c_3=1\),\(\Delta=1-0=1\),\(d_2=1 \mod 4 = 1\)
- \(c_3=1\):下一个链码\(c_4=2\),\(\Delta=2-1=1\),\(d_3=1 \mod 4 = 1\)
- \(c_4=2\):下一个链码\(c_5=2\),\(\Delta=2-2=0\),\(d_4=0 \mod 4 = 0\)
- \(c_5=2\):下一个链码\(c_6=3\),\(\Delta=3-2=1\),\(d_5=1 \mod 4 = 1\)
- \(c_6=3\):下一个链码\(c_7=0\),\(\Delta=0-3=-3\),\(d_6=-3 \mod 4 = 1\)(注:负数模运算规则为 “结果为非负且小于模”,\(-3 + 4 = 1\))
- \(c_7=0\):下一个链码\(c_1=0\),\(\Delta=0-0=0\),\(d_7=0 \mod 4 = 0\)
最终得到一阶差分序列:\(D = [0, 1, 1, 0, 1, 1, 0]\)。
三、核心步骤:如何计算最小幅度的一阶差分(形状数)?
形状数是 “一阶差分序列的最小幅度形式”,核心逻辑是:将一阶差分序列视为 “数字串”,通过循环移位生成所有可能序列,转化为数值后选取最小者。以下以 “4 方向链码的一阶差分序列” 为例,详解计算流程:
1. 前置步骤:获取原始一阶差分序列
首先按上述方法,计算出闭合边界对应的一阶差分序列\(D = [d_1, d_2, ..., d_n]\),其中 n 为序列长度,元素范围为 0~k-1(k 为方向数)。 示例基础:沿用前文的一阶差分序列\(D = [0, 1, 1, 0, 1, 1, 0]\)(n=7,k=4)。
2. 核心操作:生成循环移位序列并筛选最小值
这一步是实现 “起点不变性” 的关键,需通过 “移位→转数值→比大小” 三个环节完成:
1) 生成所有循环移位序列:将原始差分序列视为首尾衔接的循环结构,从第 1 个元素开始,依次将 “首元素移至末尾”,生成 n 个不同的移位序列(n 为序列长度)。 以上述示例为例(n=7),部分移位序列如下:
- 移位 1(原始序列):[0, 1, 1, 0, 1, 1, 0]
- 移位 2(首元素 0 移至末尾):[1, 1, 0, 1, 1, 0, 0]
- 移位 3(首元素 1 移至末尾):[1, 0, 1, 1, 0, 0, 1]
- 移位 4(首元素 1 移至末尾):[0, 1, 1, 0, 0, 1, 1]
- ...(共生成 7 个移位序列,覆盖所有可能的起点)
2) 将移位序列转化为自然数:将每个移位序列当作 “无符号整数”(序列元素按顺序构成数字的各位),转化为十进制数值,确保不同序列可直接比较大小。 示例转化:
- 移位 1 序列 [0,1,1,0,1,1,0] → 数字 “0110110” → 十进制 54;
- 移位 2 序列 [1,1,0,1,1,0,0] → 数字 “1101100” → 十进制 108;
- 移位 3 序列 [1,0,1,1,0,0,1] → 数字 “1011001” → 十进制 89;
- 显然,移位 1 对应的数值(54)小于其他序列。
3) 筛选最小数值对应的序列:比较所有移位序列的十进制数值,数值最小的序列即为 “最小幅度的一阶差分序列”,也就是该边界的形状数。 示例结论:原始序列 [0,1,1,0,1,1,0] 是所有移位序列中数值最小的,因此它就是该边界的形状数。
3. 关键规则:确保形状数的唯一性
- 若存在多个移位序列数值相同(极少见,多出现于对称形状如正方形、圆形),默认选取 “首个出现的序列” 即可,不影响形状标识的唯一性;
- 计算全程需固定方向数 k(4 方向或 8 方向):不同 k 对应的元素范围(0~3 或 0~7)不同,若中途改变 k,会导致数值比较偏差,破坏形状数的一致性。
四、总结:形状数的价值与应用场景
形状数通过 “一阶差分消除旋转依赖”“循环移位找最小值消除起点依赖”,完美解决了弗里曼链码的局限性,其核心价值在于:
- 归一化标识:同一形状无论旋转、编码起点如何变化,始终对应唯一的形状数,为 “形状是否相同” 提供客观判断标准;
- 低冗余性:序列长度与弗里曼链码一致,仅记录方向相对关系,兼顾描述精度与数据简洁性。
在实际应用中,形状数广泛用于形状匹配(如零件缺陷检测中 “标准形状与待检形状的形状数对比”)、目标识别(如字符识别中通过形状数区分不同字符)、图像检索(如按形状特征筛选相似图像)等场景,是连接 “边界描述” 与 “形状分析” 的关键桥梁。