凸包算法应用

发布时间:2026/7/24 13:18:49
凸包算法应用 凸包算法一、技术背景凸包Convex Hull是包围点集的最小凸多边形。在SEM图像分析中凸包用于计算目标的密实度Solidity分析目标的形状复杂度检测目标的凹陷区域密实度定义为轮廓面积与凸包面积的比值反映目标填充凸包的程度是形状分析的重要指标。二、数学原理2.1 凸包定义凸包是包含点集所有点的最小凸多边形。凸多边形定义为任意两点连线都在多边形内部或边界上。数学表示点集SSS的凸包为Conv(S){∑i1nλipi∣pi∈S,λi≥0,∑λi1}Conv(S) \left\{ \sum_{i1}^{n} \lambda_i p_i \mid p_i \in S, \lambda_i \geq 0, \sum \lambda_i 1 \right\}Conv(S){i1∑n​λi​pi​∣pi​∈S,λi​≥0,∑λi​1}2.2 Graham Scan算法Graham Scan是经典的凸包算法找到y坐标最小的点起点按极角排序所有点依次处理每个点维护凸包栈若新点使栈顶形成右转弹出栈顶最终栈中点构成凸包时间复杂度O(nlog⁡n)O(n \log n)O(nlogn)2.3 Jarvis March算法Jarvis March礼品包装算法从最左点开始找到使所有点都在同一侧的点将该点加入凸包重复直到回到起点时间复杂度O(nh)O(nh)O(nh)其中hhh为凸包顶点数2.4 OpenCV实现OpenCV的ConvexHull函数根据输入点数自动选择算法点数较少使用Graham Scan点数较多可能使用优化的变体2.5 密实度计算密实度Solidity定义为SolidityAcontourAconvexHullSolidity \frac{A_{contour}}{A_{convexHull}}SolidityAconvexHull​Acontour​​其中AcontourA_{contour}Acontour​轮廓面积AconvexHullA_{convexHull}AconvexHull​凸包面积密实度范围[0,1][0, 1][0,1]接近1形状接近凸形接近0形状有大量凹陷三、代码实现3.1 MainForm中的凸包计算文件路径:e:\SEM\Forms\MainForm.cs// 报告导出中的凸包计算和密实度for(inti0;iinfo.contours.Length;i){varcontourinfo.contours[i];// 面积过滤doubleareaThreshold200*areaPixelToUm2;if(areaareaThreshold)continue;if(contour.Length5)continue;RotatedRectellipseCv2.FitEllipse(contour);doubleferetMath.Max(ellipse.Size.Width,ellipse.Size.Height)*umPerPixel;doubleminFeretMath.Min(ellipse.Size.Width,ellipse.Size.Height)*umPerPixel;doubleangleellipse.Angle;doubleaspectRatioferet/minFeret;doubleroundness4*Math.PI*area/(perimeter*perimeter);// 凸包计算与密实度doublesolidityarea/(Cv2.ContourArea(Cv2.ConvexHull(contour))*areaPixelToUm2);varrownewListstring{// ...aspectRatio.ToString(F2),roundness.ToString(F2),solidity.ToString(F2)};}3.2 凸包点获取// 获取凸包点集Point[]hullCv2.ConvexHull(contour);// 绘制凸包Cv2.Polylines(image,new[]{hull},true,newScalar(255,0,0),2);3.3 形状因子计算// 完整的形状因子计算doubleareaCv2.ContourArea(contour);doubleperimeterCv2.ArcLength(contour,true);doubleconvexHullAreaCv2.ContourArea(Cv2.ConvexHull(contour));// 圆度doublecircularity4*Math.PI*area/(perimeter*perimeter);// 密实度doublesolidityarea/convexHullArea;// 凸性doubleconvexityCv2.ArcLength(Cv2.ConvexHull(contour),true)/perimeter;四、参数调优4.1 凸包方向OpenCV的ConvexHull参数// clockwise: 凸包点是否按顺时针排列// returnPoints: 返回点还是索引Point[]hullCv2.ConvexHull(contour,clockwise:true,returnPoints:true);4.2 凸缺陷检测凸缺陷是轮廓与凸包之间的凹陷区域// 检测凸缺陷vardefectsnewMat();Cv2.ConvexityDefects(contour,Cv2.ConvexHullIndices(contour),defects);// 解析缺陷信息for(inti0;idefects.Rows;i){intstartIdx(int)defects.AtVec4i(i)[0];intendIdx(int)defects.AtVec4i(i)[1];intfarIdx(int)defects.AtVec4i(i)[2];doubledepthdefects.AtVec4i(i)[3]/256.0;// 深度// 绘制凹陷最深点Cv2.Circle(image,contour[farIdx],5,newScalar(0,255,0),-1);}4.3 形状指标阈值形状指标范围圆形值解释圆度[0, 1]1.0接近1为圆形密实度[0, 1]1.0接近1为凸形凸性[0, 1]1.0接近1为凸形五、常见问题Q1: 凸包与轮廓的区别对比项轮廓凸包形状可能凹陷严格凸形面积较小较大或相等点数通常多通常少用途边界检测形状分析Q2: 密实度的应用场景密实度在SEM分析中的应用孔隙形状分类区分圆形孔隙和不规则孔隙颗粒形态分析评估颗粒的圆整度缺陷检测识别有凹陷的目标Q3: 如何解释密实度值密实度范围形状特征0.95-1.0近凸形无明显凹陷0.85-0.95轻微凹陷0.70-0.85中等凹陷0.70严重凹陷不规则Q4: 凸包计算的性能时间复杂度O(nlog⁡n)O(n \log n)O(nlogn)优化建议先对轮廓进行降采样使用轮廓近似减少点数并行处理多个轮廓// 轮廓近似减少点数MatapproxnewMat();Cv2.ApproxPolyDP(contour,approx,0.01*Cv2.ArcLength(contour,true),true);Point[]hullCv2.ConvexHull(approx.ToArray());Q5: 如何计算凸包的缺陷深度凸缺陷深度表示凹陷的程度vardefectsnewMat();Cv2.ConvexityDefects(contour,Cv2.ConvexHullIndices(contour),defects);doublemaxDepth0;for(inti0;idefects.Rows;i){doubledepthdefects.AtVec4i(i)[3]/256.0;maxDepthMath.Max(maxDepth,depth);}// 深度单位转换像素 → μmdoublemaxDepth_ummaxDepth*umPerPixel;Q6: 凸包面积与轮廓面积的关系AconvexHull≥AcontourA_{convexHull} \geq A_{contour}AconvexHull​≥Acontour​密实度计算SolidityAcontourAconvexHull≤1Solidity \frac{A_{contour}}{A_{convexHull}} \leq 1SolidityAconvexHull​Acontour​​≤1当轮廓本身为凸形时密实度等于1。