假设输入图像为 $F= f_(i j)$，将初始 NBD（Next Boundary
Descriptor）设为 1（将 F
的#strong[框架];看作第一个边界）。使用光栅扫描法扫描图像
F，当扫描到某个像素点 $(i , j)$ 的灰度值 $f_(i j) eq.not 0$
时执行下面的步骤。每次当我们扫描到图像的新行的起始位置时，将
#strong[LNBD];（Last Next Boundary Descriptor）重置为 1。

+ 根据以下情况选择一种操作：

  - 如果 $f_(i j) = 1$ 并且 $f_(i , j - 1) = 0$，则 $(i , j)$
    是#strong[外边界的开始点];，NBD 增加 1，并且将
    $(i_2 , j_2) arrow.l (i , j - 1)$。

  - 如果 $f_(i j) gt.eq 1$ 并且 $f_(i , j + 1) = 0$，则 $(i , j)$
    是#strong[孔边界的开始点];，NBD 增加 1，并且将
    $(i_2 , j_2) arrow.l (i , j + 1)$。如果 $1 < f_(i j)$，则
    $L N B D arrow.l f_(i j)$。

  - 其他情况，跳到步骤 4。

+ 根据上一个边界 $B prime$ 和当前新遇到边界 $B$ 的类型，选择 B
  的父边界。

+ 从#strong[边界开始点] $(i , j)$ 开始，按以下步骤进行边界跟踪：

  - 以 $(i , j)$ 为中心，$(i_2 , j_2)$ 为起始点，按顺时针方向查找
    $(i , j)$ 的 4（或
    8）邻域是否存在非零像素点。如果找到非零像素点，则令 $(i_1 , j_1)$
    是顺时针方向的第一个非零像素点；否则令 $f_(i j) = - N B D$，跳到步骤
    4。

  - 更新
    $(i_2 , j_2) arrow.l (i_1 , j_1)$，$(i_3 , j_3) arrow.l (i , j)$。

  - 以 $(i_3 , j_3)$ 为中心，从 $(i_2 , j_2)$
    的下一个点开始，按逆时针方向查找 $(i_3 , j_3)$ 的 4（或
    8）邻域是否存在非零像素点。找到的第一个非零像素点为 $(i_4 , j_4)$。

  - 更新 $f_(i_3 , j_3)$ 的值：

    - 如果 $(i_3 , j_3 + 1)$ 是在上述步骤中已经检查过的像素点并且是 0
      像素点，则 $f_(i_3 , j_3) arrow.l - N B D$。

    - 如果 $(i_3 , j_3 + 1)$ 不是上述步骤中已经检查过的 0 像素点，并且
      $f_(i_3 , j_3) = 1$，则 $f_(i_3 , j_3) arrow.l N B D$。

    - 其他情况，不改变 $f_(i_3 , j_3)$。

  - 如果 $(i_4 , j_4) = (i , j)$ 并且
    $(i_3 , j_3) = (i_1 , j_1)$（即回到了边界开始点），跳到步骤
    4；否则更新
    $(i_2 , j_2) arrow.l (i_3 , j_3)$，$(i_3 , j_3) arrow.l (i_4 , j_4)$，返回上述步骤。

+ 如果 $f_(i j) eq.not 1$，则 $L N B D arrow.l lr(|f_(i j)|)$。继续从点
  $(i , j + 1)$ 进行光栅扫描。当扫描到图像的右下角顶点时结束。
