OpenCVSharp入门教程 特征提取②——FindContours寻找轮廓,轮廓提取

2,672 阅读2分钟

一、前文

基于边缘检测算法的轮廊寻找和提取

二、算法流程

  1. 高斯模糊
  2. Canny边缘检测
  3. FindContours寻找轮廓,轮廊提取

三、界面布局

  • 一个Label
  • N个Button
  • 三个Picture

在这里插入图片描述

四、功能实现

4.1 打开图片

 private void openFileBtn_Click(object sender, EventArgs e)
 {
     OpenFileDialog openfiledialog = new OpenFileDialog();
     openfiledialog.Filter = "PNG Files (*.png)|*.png|JPG Files (*.jpg)|*.jpg|GIF Files (*.gif)|*.gif";
     openfiledialog.RestoreDirectory = true;
     if (openfiledialog.ShowDialog() == DialogResult.OK)
     {
         Console.WriteLine(openfiledialog.FileName);
         fileName = openfiledialog.FileName;

         //Mat src = new Mat("foo.png", LoadMode.Color);
         Mat src = new Mat(fileName);
         //Mat src = new Mat(fileName, ImreadModes.Color);
         var frameBitmap = BitmapConverter.ToBitmap(src);

         pictureBox1.Image?.Dispose();
         pictureBox1.Image = frameBitmap;
     }
 }

4.2 FindContours轮廓提取—源码

private void contoursBtn_Click(object sender, EventArgs e)
{
    cannyBtn_Click(sender, e);
    mOutput = new Mat(mInput.Rows, mInput.Cols, MatType.CV_8UC4);
    mInput.CopyTo(mOutput);

    RetrievalModes mode = RetrievalModes.External;
    ContourApproximationModes method = ContourApproximationModes.ApproxNone;
    Point offset = new OpenCvSharp.Point(0, 0);

    Cv2.FindContours(
        image: edges,
        contours: out OpenCvSharp.Point[][] contours,
        hierarchy: out HierarchyIndex[] outputArray,
        mode: mode,
        method: method,
        offset: offset);

    for (int i = 0; i < contours.Length; i++)
    {
        Scalar color = Scalar.RandomColor();
        if (contours[i].Length > 100)
        {
            Cv2.DrawContours(
                mOutput,
                contours,
                contourIdx: i,
                color: color,
                thickness: 2,
                lineType: LineTypes.Link8,
                hierarchy: outputArray,
                maxLevel: 0);
        }
    }

    srcPictureBox.Image = BitmapConverter.ToBitmap(mInput);
    grayPictureBox.Image = BitmapConverter.ToBitmap(edges);
    dstPictureBox.Image = BitmapConverter.ToBitmap(mOutput);
}

4.3 FindContours轮廓提取—参数讲解

//
// 摘要:
//   Finds contours in a binary image.
//
// 参数:
//   image:
//     Source, an 8-bit single-channel image. Non-zero pixels are treated as 1’s. Zero
//     pixels remain 0’s, so the image is treated as binary. The function modifies the
//     image while extracting the contours.
//
//   contours:
//     Detected contours. Each contour is stored as a vector of points.
//
//   hierarchy:
//     Optional output vector, containing information about the image topology. It has
//     as many elements as the number of contours. For each i-th contour contours[i],
//     the members of the elements hierarchy[i] are set to 0-based indices in contours
//     of the next and previous contours at the same hierarchical level, the first child
//     contour and the parent contour, respectively. If for the contour i there are
//     no next, previous, parent, or nested contours, the corresponding elements of
//     hierarchy[i] will be negative.
//
//   mode:
//     Contour retrieval mode
//
//   method:
//     Contour approximation method
//
//   offset:
//     Optional offset by which every contour point is shifted. This is useful if the
//     contours are extracted from the image ROI and then they should be analyzed in
//     the whole image context.
public static void FindContours(InputArray image, out Point[][] contours, out HierarchyIndex[] hierarchy, RetrievalModes mode, ContourApproximationModes method, Point? offset = null);
  • image,灰度图片输入
  • contours,轮廓结果输出
  • mode,轮廓检索模式
    • External,只检测外层轮廓
    • List,提取所有轮廓,并放置在list中,检测的轮廓不建立等级关系
    • CComp,提取所有轮廓,并将轮廓组织成双层结构(two-level hierarchy),顶层为连通域的外围边界,次层位内层边界
    • Tree,提取所有轮廓并重新建立网状轮廓结构
    • FloodFill,官网没有介绍,应该是洪水填充法
  • method,轮廓近似方法
    • ApproxNone,获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1
    • ApproxSimple,压缩水平方向,垂直方向,对角线方向的元素,值保留该方向的重点坐标,如果一个矩形轮廓只需4个点来保存轮廓信息
    • ApproxTC89L1,使用Teh-Chinl链逼近算法中的一种
    • ApproxTC89KCOS,使用Teh-Chinl链逼近算法中的一种

五、运行效果图

从左到右

  • 第一张是原图
  • 第二张是高斯模糊的结果图
  • 第三张是FindContours轮廊提取的结果图

在这里插入图片描述 在这里插入图片描述

在这里插入图片描述

六、参考

OpenCV---轮廓发现

觉得好,就一键三连呗(点赞+收藏+关注)