提示:
如其他答案所述,发射轮廓像素列表可以实现为扫描线过程,在此期间检查运行端点的3x3邻域。
此过程将以混乱的方式发出像素,作为需要存储和重新排序的直接和反向弧序列。
另一种选择是基于实现标准Moore邻域算法的想法,该算法具有按所需顺序枚举轮廓像素的优点。
此过程需要知道当前像素周围的8个邻域配置,并且想法是在移动到另一个像素时更新此邻域:我们维护包含当前像素的运行的索引以及上下行中两个面对的运行的索引。
在移动到另一个像素时,我们需要更新这三个索引,这将涉及对排序运行列表进行短顺序搜索。这可以看作是对像素的伪随机访问机制,考虑到连续访问是强烈局部的并且可以被某种方式缓存。
更新:
在我使用的游程编码表示中,只有黑色行被编码为三元组(X, Y, L)
。这些行按从上到下的行顺序排序,然后按每行从左到右的顺序排列。
为了方便起见,我们可以切换到“线性寻址”方案,就好像所有图像行都已经连接在一起,每个像素由单个数字Z = X + Y.Nx
(其中Nx
是图像宽度)指定。
因此,我们有一个黑色行的列表,白色行隐含在两个相邻的黑色行之间。
在处理过程中,我们可以始终记住立即在当前像素之前或之上开始的行的索引(R[I].Z <= Z < R[I+1].Z
)。我们可以通过检查是否在行内或在行和下一行之间来确定像素的颜色(Z < R[I].Z + R[I].L
)。
如果我们向左移动一个位置,Z
减少1
,我们可能需要选择前一个行(I--
)。
如果我们向上移动一个位置,Z
会减少 Nx
,我们可能需要回溯若干次(I--
直到 R[I].Z <= Z
再次成立)。
该图片展示了当前像素及其四个相邻像素,以及黑色行的“影响区域”。我们可以类似地处理所有八个位移方向。
正如我们所看到的,每次移动最多需要一行中运行的数量的操作,被认为是一个小值。利用这个概念,我们可以以合理的代价遍历RLC表示,而无需重建整个位图。
由于Moore邻域算法的时间复杂度与轮廓长度成线性关系,基于这种线性运行寻址的实现也将花费线性时间(对于每行有限数量的运行)。