OpencvSharp 算子学习教案之 - Cv2.ConvexHullIndices 重载2
大家好,Opencv在很多工程项目中都会用到,而OpencvSharp则是以C#开发与实现的Opencv操作库,对.NET开发人员友好,但很多API的中文资料、应用场景及常见坑点等缺乏系统性归纳,因此这系列博客将给大家带来Cv2及Mat对象全系列算子学习教案,供大家参考学习。
Cv2.ConvexHullIndices
- 教案版本:V1.0
- 面向对象:OpenCvSharp 初学者
- 所属模块:imgproc
- 源码位置:OpenCvSharp/Cv2/Cv2_imgproc.cs:3619 / 3642
摘要:本页演示ConvexHullIndices(IEnumerable<Point2f>)如何返回浮点轮廓的凸包索引,并说明这些索引仍然是 0-based 的整数编号。
1. 函数名称(带参数签名)
publicstaticint[]ConvexHullIndices(IEnumerable<Point2f>points,boolclockwise=false)2. 函数用途
Cv2.ConvexHullIndices(...)用来求一组点的凸包索引。
这个重载最适合浮点点集:
- 可以保留轮廓的亚像素精度。
- 返回值仍然是整数索引。
- 特别适合高精度分析后的反查步骤。
它常用于:
- 先求凸包索引,再做
ConvexityDefects。 - 把索引映射回原始浮点点集。
- 需要高精度坐标却又想保留索引链路的场景。
- 教学中展示“索引”和“坐标”的区别。
3. 函数公式
可以把这个结果理解为:
h i = ConvexHullIndices ( P ) i , p i = P [ h i ] h_i = \operatorname{ConvexHullIndices}(P)_i, \quad p_i = P[h_i]hi=ConvexHullIndices(P)i,pi=P[hi]
其中P PP是原始浮点点集,h i h_ihi是凸包第i ii个顶点在原始点集中的索引,p i p_ipi是映射回来的浮点坐标。
4. 函数原理说明
它和整数版本的区别只在输入精度,不在算法语义。
对初学者来说,可以这样理解:
- 索引还是整数。
- 坐标可以是浮点。
- 索引能把高精度点集和后续分析结果连接起来。
这让它在几何管线里非常实用。
5. 参数含义解析
| 参数名 | 类型 | 必填 | 含义 |
|---|---|---|---|
| points | IEnumerable | 是 | 输入浮点点集 |
| clockwise | bool | 否 | 输出索引对应的点序是否按顺时针排列 |
补充说明:
- 索引依然是 0-based。
- 需要点坐标时,直接用索引回查即可。
- 如果点集来自拟合或变换,这个版本更适合保留精度。
6. 应用场景列表
| 场景名 | 场景说明 | 典型用途 |
|---|---|---|
| 场景A:高精度回查 | 通过索引找回浮点点坐标 | 轮廓分析 |
| 场景B:缺陷分析 | 作为 ConvexityDefects 的输入 | 手势/形状识别 |
| 场景C:高亮显示 | 把索引对应的浮点点高亮出来 | 可视化 |
| 场景D:教学入门 | 理解“索引”和“坐标”的分工 | OpenCvSharp 入门 |
7. 函数使用示例(与 WPF 场景一一对应)
说明:下面示例对应 WPF 场景 B。它演示浮点轮廓的索引同样可以反查回原始点集。
usingSystem;usingSystem.Globalization;usingOpenCvSharp;internalstaticclassProgram{privatestaticvoidMain(){// 这组浮点点集保留了小数,方便对比高精度轮廓分析的结果。Point2f[]contourPoints={newPoint2f(92.0f,232.0f),newPoint2f(118.0f,126.0f),newPoint2f(146.0f,88.0f),newPoint2f(164.0f,146.0f),newPoint2f(190.0f,72.0f),newPoint2f(216.0f,148.0f),newPoint2f(242.0f,92.0f),newPoint2f(268.0f,126.0f),newPoint2f(300.0f,232.0f),newPoint2f(300.0f,252.0f),newPoint2f(92.0f,252.0f),};int[]hullIndices=Cv2.ConvexHullIndices(contourPoints,clockwise:false);for(varindex=0;index<hullIndices.Length;index++){varpointIndex=hullIndices[index];varpoint=contourPoints[pointIndex];Console.WriteLine($"HullIndex{index+1}={pointIndex}, Point = ({point.X:F1},{point.Y:F1})");}Console.WriteLine($"ContourCount ={contourPoints.Length}");Console.WriteLine($"HullIndexCount ={hullIndices.Length}");Console.WriteLine($"ContourArea ={Math.Abs(Cv2.ContourArea(contourPoints)).ToString("F2",CultureInfo.InvariantCulture)}");varhullPoints=newPoint2f[hullIndices.Length];for(varindex=0;index<hullIndices.Length;index++){hullPoints[index]=contourPoints[hullIndices[index]];}Console.WriteLine($"HullArea ={Math.Abs(Cv2.ContourArea(hullPoints)).ToString("F2",CultureInfo.InvariantCulture)}");Console.WriteLine($"HullPerimeter ={Cv2.ArcLength(hullPoints,true).ToString("F2",CultureInfo.InvariantCulture)}");Console.WriteLine($"HullIsConvex ={Cv2.IsContourConvex(hullPoints)}");// 这一行是本例的核心:索引本身不画图,但能准确对应回浮点坐标。Console.WriteLine("ConvexHullIndices 的结果可以直接映射回原始浮点轮廓。\n");}}8. 常见错误与避坑
- 误把索引当作坐标直接使用。
- 忘记浮点点集返回的也是整数索引。
- 没有先保留原始轮廓,导致无法回查点坐标。
- 把
ConvexHullIndices和ConvexHull的返回值混淆。
9. 进阶扩展
- 可以把浮点索引和原始点一起显示在图上。
- 可以把这些索引直接传给
ConvexityDefects。 - 可以比较整数和浮点轮廓的索引结果。
- 可以在变换后的轮廓上观察索引是否稳定。
10. 小结
Cv2.ConvexHullIndices(...)的IEnumerable<Point2f>重载返回的是整数索引,不是浮点坐标。
理解这一点后,就能很自然地过渡到ConvexityDefects。
11. 相关链接
- WPF 教学控件:Cv2ConvexHullIndicesControl.xaml.cs
- 样例实现:ConvexHullIndicesPoint2fEnumerableSample.cs
- 官方文档源码位置:OpenCvSharp/Cv2/Cv2_imgproc.cs
- 另一个重载源码位置:OpenCvSharp/Cv2/Cv2_imgproc.cs