C#:轮廓的层次结构
2025-04-18 本文已影响0人
大龙10
- 在OpenCvSharp中,Cv2.FindContours() 是用于检测图像轮廓的核心函数。
一、函数参数
void Cv2.FindContours(
InputArray image,
out Point[][] contours,
out HierarchyIndex[] hierarchy,
RetrievalModes mode,
ContourApproximationModes method,
Point? offset = null
)
1、image
-
输入的二值化图像(通常需预处理)。必须为8位单通道图像,非零像素视为前景,0为背景。
-
预处理示例:将图像转为灰度后通过阈值处理或边缘检测二值化。
2、contours(输出参数)
- 检测到的轮廓集合,类型为 Point[][]。每个轮廓由若干个 Point 组成的数组表示。
3、hierarchy(输出参数)
- 轮廓的层次结构,类型为 HierarchyIndex[]。每个元素描述轮廓的父子关系:
- Parent: 父轮廓索引(无父则为-1)
- Next: 同一层级的下一个轮廓索引
- Previous: 同一层级的上一个轮廓索引
- FirstChild: 第一个子轮廓索引
4、mode: 轮廓检索模式
- RetrievalModes.External: 仅检测最外层轮廓。
- RetrievalModes.List: 提取所有轮廓,不建立层次关系。
- RetrievalModes.CComp: 分层检测轮廓,组织为双层结构(外层和孔)。
- RetrievalModes.Tree: 检测所有轮廓并建立完整的层次树。
5、method: 轮廓近似方法
- ContourApproximationModes.ApproxNone: 保存所有轮廓点。
- ContourApproximationModes.ApproxSimple: 压缩冗余点(如矩形保留4个顶点)。
- ContourApproximationModes.ApproxTC89KCOS: 使用Teh-Chin链近似算法优化。
6、offset(可选)
- 轮廓点的偏移量。默认为 null,即无偏移。
二、示例
using OpenCvSharp;
Mat src = Cv2.ImRead("image.jpg", ImreadModes.Color);
Mat gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
Mat binary = new Mat();
Cv2.Threshold(gray, binary, 127, 255, ThresholdTypes.Binary);
Point[][] contours;
HierarchyIndex[] hierarchy;
Cv2.FindContours(
image: binary,
contours: out contours,
hierarchy: out hierarchy,
mode: RetrievalModes.Tree,
method: ContourApproximationModes.ApproxSimple
);
// 绘制所有轮廓
Mat result = src.Clone();
Cv2.DrawContours(
image: result,
contours: contours,
contourIdx: -1, // -1表示绘制所有轮廓
color: new Scalar(0, 255, 0),
thickness: 2
);
Cv2.ImShow("Contours", result);
Cv2.WaitKey(0);
关键注意事项
-
预处理要求
输入图像必须为二值化的单通道图像,否则结果不可靠。未预处理可能导致检测失败。 -
层次结构应用
当处理嵌套轮廓(如孔洞)时,RetrievalModes.Tree 或 CComp 配合 hierarchy 可精确管理轮廓关系。
示例:遍历子轮廓
for (int i = 0; i < contours.Length; i++)
{
if (hierarchy[i].Parent == -1) // 顶级轮廓
{
int childIdx = hierarchy[i].FirstChild;
while (childIdx != -1)
{
// 处理子轮廓
childIdx = hierarchy[childIdx].Next;
}
}
}
- 性能优化
ApproxSimple 可显著减少轮廓点数,提升后续处理速度。
三、 常见问题
-
未检测到轮廓
检查输入图像是否为二值格式,并确认前景像素为非零值。 -
轮廓点过多或过少
调整预处理步骤(如阈值参数、边缘检测算子)。 -
层次结构异常
确保选用合适的mode(如Tree而非List以获取层次信息)。
四、资料
技能拾荒者《93-OpenCVSharp —- Cv2.FindContours()函数功能(轮廓检测,轮廓的层次结构)详解》
https://blog.csdn.net/weixin_45590420/article/details/145905519