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、輪廓填充:

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章