本文最后更新于:2025年4月30日 下午
平面细分(Subdiv2D)是OpenCV中一个强大的类,用于在平面上进行细分操作,并提供了一系列函数来管理和操作这些三角形。在本文中,我们将详细介绍Subdiv2D类的使用方法,并提供相关的源代码。
简介
Subdiv2D 类用于对一组 2D 点(表示为 Point2f 向量)执行各种平面细分。OpenCV 使用 Delaunay 算法对平面进行三角剖分,该算法对应于 Voronoi 图的偶图。在下图中,Delaunay 三角剖分用黑线标记,Voronoi 图用红线标记。

Delaunay 三角剖分(黑色)和 Voronoi(红色)
使用方法
实例化对象 - Subdiv2D
1 | |
这里的 rect = [x_min, y_min, x_max, y_max]
表示这个 subdiv 对象仅在这个矩形范围内有效。
-
示例代码:
创建一个 500x500 的平面空间对象
1 | |
插入数据 - insert
将单个点插入到Delaunay三角剖分中。
1 | |
- 示例代码:
1 | |
也可以插入多个点到 Delaunay 三角剖分中。
1 | |
查找目标最近点 - findNearest
该函数是另一个用于在子划分中定位输入点的函数。它找到与输入点最近的一个子划分顶点。
1 | |
| 返回变量 | 含义 |
|---|---|
| pt | query 点 |
| retval | 返回点 ID |
| nearestPt | 最近点 |
- 示例代码:
1 | |
注意:我在使用这个函数的时候出现了返回点 nearestPt 坐标均为 0 的情况,个人怀疑是这个函数的 bug (opencv 4.9.0.80) ,所以碰到需要使用 nearestPt 信息的时候建议不要直接用这个函数返回的 nearestPt,而是结合 getVertex() 函数共同使用。
1 | |
这套代码我在使用时没出过问题。
返回顶点位置 - getVertex
根据顶点 ID 返回顶点位置。
1 | |
- 参数含义:
| 返回变量 | 含义 |
|---|---|
| vertex | 顶点 ID。 |
| nearestPt | 最近点 |
| firstEdge | 可选。连接到顶点的第一个边ID。 |
- 示例代码:
1 | |
边的终点 - edgeDst
1 | |
- 参数含义:
| 变量 | 含义 |
|---|---|
| edge | 分划边 ID。 |
| retval | 点 ID |
| dstpt | 边终点位置。 |
- 示例代码:
1 | |
边的起点 - edgeOrg
返回边的起点。
1 | |
- 参数含义:
| 变量 | 含义 |
|---|---|
| edge | 分划边 ID。 |
| retval | 点 ID |
| dstpt | 边起点位置。 |
- 示例代码:
1 | |
获取边 - getEdge
返回与给定边相关的边之一。
1 | |
-
nextEdgeType
-
NEXT_AROUND_ORG 线原点周围(如果e是输入边,则图片下的 eOnext)
-
NEXT_AROUND_DST 边顶点周围(eDnext)
-
PREV_AROUND_ORG 线原点周围(eRnext的反转)
-
PREV_AROUND_DST 边终点周围(eLnext的反转)
-
NEXT_AROUND_LEFT 左面周围(eLnext)
-
NEXT_AROUND_RIGHT 右面周围(eRnext)
-
PREV_AROUND_LEFT 左面周围(eOnext的反转)
-
PREV_AROUND_RIGHT 右面周围(eDnext的反转)
-

- 示例代码:
1 | |
返回边列表 - getEdgeList
返回所有边的列表。
1 | |
- 示例代码:
1 | |
1 | |
返回所有三角形 - getTriangleList
返回所有三角形的列表。
1 | |
- 示例代码:
1 | |
1 | |
返回沃罗诺伊图 - getVoronoiFacetList
返回所有沃罗诺伊面元的列表。
1 | |
- 参数列表:
| 变量 | 含义 |
|---|---|
| idx | 要考虑的顶点ID向量。对于所有顶点,您可以通过空向量传递。 |
| facetList | 输出向量包含Voronoi面。 |
| facetCenters | 输出向量包含Voronoi面的中心点。 |
- 示例代码:
1 | |
1 | |
初始化 - Delaunay
创建一个新的空Delaunay细分。
1 | |
-
参数说明:
变量 含义 rect 包含所有要添加到分划中的二维点的矩形。 -
示例代码:
1 | |
定位 - locate
返回点在Delaunay三角剖分中的位置。
该函数在细分中定位输入点,并给出一个三角形边或顶点。
1 | |
-
参数说明:
变量 含义 pt 要定位的点。 edge 输出点所属的边或位于其右侧的边。 vertex 可选输出顶点,如果输入点与该顶点重合。 -
示例代码:
1 | |
-
返回:
一个整数,指定以下五种位置情况之一点位置
- 点落在某个面片内。此函数返回
PTLOC_INSIDE,且edge将包含面片的边之一。 - 点落在边上。此函数返回
PTLOC_ON_EDGE,且edge将包含此边。 - 点与细分的一个顶点重合。此函数返回
PTLOC_VERTEX,且vertex将包含顶点的指针。 - 点位于细分参考矩形外部。此函数返回
PTLOC_OUTSIDE_RECT,不会填充任何指针。 - 一个输入参数无效。将引发运行时错误,或者如果选择静默或“父”错误处理模式,则返回
PTLOC_ERROR。
- 点落在某个面片内。此函数返回
获取下一个边 - nextEdge
返回以边缘为起点的下一边缘。
1 | |
-
参数说明:
变量 含义 retval 下一个边缘的 ID。 edge 输出点所属的边或位于其右侧的边。 -
示例代码:
1
next_edge = subdiv.nextEdge(10)
旋转边缘 - rotateEdge
返回同一四边形的另一个边缘。
1 | |
-
参数说明:
变量 含义 edge 分划边 ID。 rotate 指定返回与输入quad-edge相同的边的参数。 -
0 - 输入边(如果 e 是输入边,则下图中的 e)
-
1 - 旋转边( eRot )
-
2 - 反转边(绿色显示的反转e)
-
3 - 反转旋转边(绿色显示的反转eRot)

-
-
示例代码:
1
subdiv.rotateEdge(2, 0)
Vornoni 示例
1 | |


参考资料
- https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#a3ec256af000e129e08eb5f269ccdeb0f
- https://docs.opencv.ac.cn/4.10.0/df/dbf/classcv_1_1Subdiv2D.html#a3ec256af000e129e08eb5f269ccdeb0f
文章链接:
https://www.zywvvd.com/notes/study/image-processing/opencv/subdiv2d/subdiv2d/
“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”
微信支付
支付宝支付