C#:轮廓发现与轮廓分析

一、二值图像分析

  • 二值图像分析最常见的一个主要方式就是轮廓发现与轮廓分析
    其中轮廓发现的目的是为轮廓分析做准备,
    经过轮廓分析我们可以得到轮廓各种有用的属性信息。

二、边缘检测和轮廓检测的区别

  • 边缘检测
    主要是通过一些手段检测数字图像中明暗变化剧烈(即梯度变化比较大)像素点,偏向于图像中像素点的变化。如canny边缘检测,结果通常保存在和源图片一样尺寸和类型的边缘图中。
  • 轮廓检测
    指检测图像中的对象边界,更偏向于关注上层语义对象。
    如OpenCV中的findContours()函数, 它会得到每一个轮廓并以点向量方式存储,除此也得到一个图像的拓扑信息,即一个轮廓的后一个轮廓、前一个轮廓、父轮廓和内嵌轮廓的索引编号。

三、轮廓发现与绘制

  • 在OpenCV里面利用findContours()函数和drawContours()函数实现这一功能。
void FindContours(InputOutputArray image, 
  out Point[][] contours, 
  out HierarchyIndex[] hierarchy, 
  RetrievalModes mode, 
  ContourApproximationModes method, 
  Point? offset = null);
  • FindContours
    • 参数一: image,输入图像、八位单通道的,背景为黑色的二值图像。(一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像)

    • 参数二:contours,输出轮廓图像。是一个向量,向量的每个元素都是一个轮廓。因此,这个向量的每个元素仍是一个向量。即:

         vector<vector<Point> > contours;
      
    • 参数三:hierarchy,输出各个轮廓的继承关系。hierarchy也是一个向量,长度和contours相等,每个元素和contours的元素对应。hierarchy的每个元素是一个包含四个整型数的向量。即:

         vector<Vec4i> hierarchy;
      
    • 参数四:mode,检测轮廓的方法。有四种方法:
      RETR_EXTERNAL:只检测外轮廓。忽略轮廓内部的洞。
      RETR_LIST:检测所有轮廓,但不建立继承(包含)关系。
      RETR_TREE:检测所有轮廓,并且建立所有的继承(包含)关系。
      RETR_CCOMP:检测所有轮廓,但是仅仅建立两层包含关系。

    • 参数五:method,每个轮廓的编码信息。也有四种(常用前两种)
      CHAIN_APPROX_NONE:把轮廓上所有的点存储。
      CHAIN_APPROX_SIMPLE:只存储轮廓上的拐点。
      CHAIN_APPROX_TC89_L1,CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法

    • 参数六: Point,偏移量。默认为0
      注意:该函数将白色区域当作前景物体。所以findContours()函数是黑色背景下找白色轮廓。

void DrawContours(InputOutputArray image, 
   IEnumerable<IEnumerable<Point>> contours,
   int contourIdx, Scalar color, 
   int thickness = 1,
   LineTypes lineType = LineTypes.Link8, 
   IEnumerable<HierarchyIndex> hierarchy = null, 
   int maxLevel = int.MaxValue, 
   Point? offset = null);
  • DrawContours()函数
    • contours 全部发现的轮廓对象
    • contourIdx 轮廓索引号,-1表示绘制所有轮廓
    • MaxValue最大层数, 0只绘制当前的,1表示绘制绘制当前及其内嵌的轮廓
    • Point? offset 轮廓位移,可选

四、轮廓分析(二值图像分析)

  • 在得到图像的轮廓以后,我们就可以进行轮廓分析。
    经过轮廓分析我们可以得到轮廓各种有用的属性信息、常见的如下:
    • 1、轮廓的矩
    • 2、轮廓的面积
    • 3、轮廓的长度
    • 4、轮廓的近似多边形
    • 5、轮廓的凸包
    • 6、轮廓的直边界矩形
    • 7、轮廓的旋转矩形
    • 8、轮廓的最小外包圆
    • 9、轮廓的拟合椭圆
    • 10、轮廓的拟合直线
    • 11、轮廓的最小外包三角形

五、程序

        private void uiButton7_Click(object sender, EventArgs e)
        {
            Mat result = src_img.Clone();
            Mat m7 = new Mat();
            double threshold1 = 10;
            double threshold2 = 200;
            int select_i = 0;
            Cv2.Canny(dst, m7, threshold1, threshold2);
            OpenCvSharp.Point[][] contours; //vector<vector<Point>> contours;
            HierarchyIndex[] hierarchyIndexes; //vector<Vec4i> hierarchy;
 
            Cv2.FindContours(m7, out contours, out hierarchyIndexes, RetrievalModes.External, ContourApproximationModes.ApproxSimple);

            for (int i = 0; i < contours.Length; i++)
            {
                double length = Cv2.ArcLength(contours[i], true);
                if (length >= 500)
                {
                    select_i = i;
                    Cv2.DrawContours(result, contours, i, new Scalar(0, 255, 255), 2);

                    Cv2.PutText(result, "i=" + i.ToString(), new OpenCvSharp.Point(20, 120), OpenCvSharp.HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 255));
                    double area = Cv2.ContourArea(contours[i], false);
                    Cv2.PutText(result, "length=" + length.ToString(), new OpenCvSharp.Point(20, 160), OpenCvSharp.HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 255));

                    Cv2.PutText(result, "area=" + area.ToString(), new OpenCvSharp.Point(20, 200), OpenCvSharp.HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 255));
                    RotatedRect rect=Cv2.MinAreaRect(contours[0]);

                    Cv2.Rectangle(result, rect.BoundingRect(), new Scalar(0, 0, 255), 2, LineTypes.Link8,0);
                    Cv2.PutText(result, "width=" + rect.Size.Width.ToString(), new OpenCvSharp.Point(20, 240), OpenCvSharp.HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 255));
                    Cv2.PutText(result, "height=" + rect.Size.Height.ToString(), new OpenCvSharp.Point(20, 280), OpenCvSharp.HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 255));
                }
            }

            pictureBox1.Image = result.ToBitmap();
        }

六、资料

「明月清风_@」的博客:
https://blog.csdn.net/qq_44386034/article/details/125637891
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容