21-22轮廓绘制(EmguCV学习)

文章目录

注意

1、CvInvoke.FindContours()函数输入图像应该为二值图像,检测的轮廓针对的是白色物体(高亮部分);FindContours()函数会修改原图像;
在这里插入图片描述2、hierarchy(层次结构) : 每个轮廓都有一个自己的层次结构;对每一个轮廓,hierarchy包含四个元素,表示同等级的后一个轮廓、前一个轮廓、子轮廓序号、父轮廓序号;在drawContours()函数中用的上,用来控制绘制的轮廓数;(参考:https://blog.csdn.net/qq_33810188/article/details/81285867?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task)
在这里插入图片描述
在这里插入图片描述
3、RetrType : 设置轮廓的检索模式(只检测最外层轮廓,检测全部轮廓,轮廓是否建立层级结构,轮廓建立2层层次结构) ; ChainApproxMethod : 轮廓近似方法(不近似保存所有点,近似只保存端点)

在这里插入图片描述
轮廓近似方法:
在这里插入图片描述
在这里插入图片描述

3、CvInvoke.DrawContours()函数:
contourIdx : 控制绘制当前轮廓i,如果为负值,则绘制所有轮廓;
thickness : 绘制线宽,如果为负,则填充轮廓;
hierarchy : 轮廓的层次结构信息;
maxLevel : 控制是否绘制当前轮廓之外的轮廓(需要有hierarchy信息做为参考):取0:只绘制当前轮廓,取1:绘制轮廓同一层次之后的所有轮廓;取2: 绘制轮廓之后所有轮廓,及轮廓之下所有子轮廓…

在这里插入图片描述

在这里插入图片描述

Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;
using System.Drawing;

namespace lesson21
{
    class Program
    {
        static void Main(string[] args)
        {
            //Mat src = CvInvoke.Imread("01.png");
            //Mat dst = src.Clone();
            //Mat gray_src = new Mat();
            //CvInvoke.Imshow("input", src);
            //CvInvoke.CvtColor(src, gray_src, ColorConversion.Bgr2Gray);
            //CvInvoke.Threshold(gray_src, gray_src, 100, 255, ThresholdType.Binary);
            //VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            //VectorOfRect hierarchy = new VectorOfRect();  //等价vector<Vec4i>
            //CvInvoke.FindContours(gray_src, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple);

            //Console.WriteLine("contours_size = {0}", contours.Size);
            //CvInvoke.DrawContours(dst, contours, -1, new MCvScalar(0, 255, 0), 2,
            //    LineType.EightConnected,hierarchy);  //maxLevel控制绘制轮廓数

            //CvInvoke.Imshow("result", dst);
            //CvInvoke.WaitKey(0);

            //Mat src = CvInvoke.Imread("01.png");
            //Mat dst = src.Clone();
            //Mat gray_src = new Mat();
            //CvInvoke.Imshow("input", src);
            //CvInvoke.CvtColor(src, gray_src, ColorConversion.Bgr2Gray);
            //CvInvoke.Threshold(gray_src, gray_src, 100, 255, ThresholdType.Binary);
            //VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            //VectorOfRect hierarchy = new VectorOfRect();  //等价vector<Vec4i>
            //CvInvoke.FindContours(gray_src, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple);

            //Console.WriteLine("contours_size = {0}", contours.Size);

            //Random random = new Random();
            ////遍历每一个轮廓
            //for(int i = 0; i < contours.Size;i++)
            //{
            //    CvInvoke.DrawContours(src, contours, i, new MCvScalar(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255))
            //                            , 2, LineType.EightConnected, hierarchy,0 );
            //    CvInvoke.Imshow("result1", src);
            //    CvInvoke.WaitKey(0);
            //}

            //遍历每个轮廓上的点
            //for(int i = 0; i < contours.Size;i++)
            //{
            //    for(int j = 0; j < contours[i].Size;j++)
            //    {
            //        CvInvoke.Circle(src, new Point(contours[i][j].X, contours[i][j].Y), 
            //            3, new MCvScalar(255, 0, 0), 2);   //依次绘制所有轮廓点
            //        CvInvoke.Imshow("result", src);        //每绘制一次显示显示一次
            //        CvInvoke.WaitKey(0);
            //    }
            //}
            //CvInvoke.WaitKey(0);

            Mat src = CvInvoke.Imread("05.png");
            Mat dst = src.Clone();
            Mat gray_src = new Mat();
            CvInvoke.Imshow("input", src);
            CvInvoke.CvtColor(src, gray_src, ColorConversion.Bgr2Gray);
            CvInvoke.Threshold(gray_src, gray_src, 100, 255, ThresholdType.BinaryInv);
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            VectorOfRect hierarchy = new VectorOfRect();  //等价vector<Vec4i>
            CvInvoke.FindContours(gray_src, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple);

            Console.WriteLine("contours_size = {0}", contours.Size);
            for(int i = 0; i< contours.Size;i++)
            {
                CvInvoke.DrawContours(src, contours, i, new MCvScalar(255, 0, 0), -1);
                CvInvoke.Imshow("contours", src);
                CvInvoke.WaitKey(0);
            }

        }
    }
}

效果

1、绘制所有轮廓:
在这里插入图片描述2、只保存轮廓端点:
在这里插入图片描述
3、每次只绘制一个轮廓(maxLevel = 0),遍历绘制所有轮廓:

在这里插入图片描述
4、轮廓填充:

在这里插入图片描述

发布了61 篇原创文章 · 获赞 5 · 访问量 4466

猜你喜欢

转载自blog.csdn.net/hellohake/article/details/105005058