轮廓线扫描算法:Theo Pavlidis' Algorithm

轮廓线扫描算法:Theo Pavlidis' Algorithm

在介绍Pavlidis算法之前,先介绍个网址:http://www.imageprocessingplace.com/downloadsV3/rootdownloads/tutorials/contourtracingAbeerGeorgeGhuneim/index.html这个网站详细介绍了现有常见的几种Contour Tracing算法,英文好的同学直接浏览那边的文章吧。这里引用他们的作为解释。

先介绍下Pavlidis的几个关键定义:当前像素位置,当前方向,P1,P2,P3三个像素点:

  • 当前像素位置:

    任意一个左边像素为背景的前景边界像素都可以作为起始像素,由算法来决定移动的下个位置。

  • 当前方向

    当前像素有4个方向,左,上,右,下。每次移动后方向可能会改变,例如从(i,j)移动到(i,j+1),那么方向就变成了下。

  • P1,P2,P3像素

    有了当前像素和方向,P1,P2,P3像素的定义如下图所示:

    Alt text

    在Figure 1中,当前方向为上,如果当前方向为左,那么P1,P2,P3就会变成左下像素,左边像素以及左上像素。总之从当前方向的视角看出,P1,P2,P3是与上图一致的。补充几张图:

    Alt textAlt textAlt text

有了以上定义,算法的步骤如下:

  1. 找到一个初始起点,并设置其方向为上(TOP)
  2. 如果P1是前景,那么移动到P2,再移动到P1。

    Alt text

  3. 如果P1不是前景,那么判断P2是否是前景。如果P2是前景,移动到P2。

    Alt text

  4. 如果P1,P2都不是前景,那么判断P3是否为前景,如果是,那么先右转,再移动到P3。

    Alt text

  5. 回到第2步,直到在同一个位置右转3次以上或者返回起始点3次以上结束。

算法标准实现可参考:

https://github.com/UnilVision/visionbase/tree/master/binary/contour tracing/Pavlidis

参考结果:

Alt text

[原创文章,转载请注明出处:http://blog.csdn.net/unilvision/article/details/8687698

### 维轮廓偏置算法的实现原理 维轮廓偏置算法通常涉及对给定的几何形状或边界进行扩展或收缩操作。这种技术广泛应用于计算机图形学、图像处理以及CAD/CAM领域。其核心思想是对原始轮廓上的每一点沿法线方向移动一定距离,从而形成新的轮廓。 #### 原理概述 1. **获取轮廓点集**:假设有一个由离散点组成的闭合轮廓 \( C = \{(x_1, y_1), (x_2, y_2), ..., (x_n, y_n)\} \),这些点按顺序排列并构成多边形。 2. **计算法向量**:对于每个点 \( P_i(x_i, y_i) \),需要找到该点处的单位法向量 \( N_i \)。可以通过相邻两点的方向矢量来估计切向量,并进一步求得法向量[^6]。 3. **应用偏置距离**:设偏置距离为 \( d \),则新点的位置可通过如下公式计算: \[ P'_i = P_i + d \cdot N_i \] 4. **处理自相交情况**:当偏置较大时,可能会导致轮廓发生自相交现象。此时需采用布尔运算或其他方法解决拓扑结构变化问题[^7]。 以下是基于Python的一个简单实现示例: ```python import numpy as np from shapely.geometry import Polygon from matplotlib import pyplot as plt def offset_polygon(polygon_coords, distance): """ 对多边形执行偏置操作 参数: polygon_coords: list of tuples [(x1,y1),(x2,y2)...] 表示原有多边形顶点坐标列表 distance: float 正表示外扩;负表示内缩 返回: 新的偏置后的多边形顶点坐标列表 """ poly = Polygon(polygon_coords) buffered_poly = poly.buffer(distance, resolution=16, join_style=2) if isinstance(buffered_poly.boundary, Polygon): result = list(buffered_poly.exterior.coords) else: result = [] for geom in buffered_poly.geoms: result.extend(list(geom.exterior.coords)) return result if __name__ == "__main__": original_points = [ (-5,-5), (+5,-5), (+5,+5), (-5,+5)] offsets = [-2, -1, 0, 1, 2] colors = ['red', 'orange', 'yellow', 'green', 'blue'] fig, ax = plt.subplots() for i,delta in enumerate(offsets): new_points = offset_polygon(original_points, delta*1.) xs, ys = zip(*new_points) ax.fill(xs,ys,color=colors[i],alpha=.5,label=f'd={delta}') ax.legend(loc='upper left') plt.axis('equal') plt.show() ``` 上述代码片段展示了如何利用Shapely库完成基本的维轮廓偏置功能[^8]。 #### 注意事项 - 当 `distance` 取正时表示向外扩张,取负时表示向内缩减。 - 如果输入的是凹多边形,则可能因内部区域消失而返回空集合的情况需要注意处理。 - 使用高分辨率参数可获得更平滑的结果,但也增加了计算成本。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值