C#/C# OpenCV/

C# OpenCV 7-7. Contour(7) Convexity defects

2019. 12. 16.

대표함수

Cv2.CvtColor 색공간 변환 [프로그래밍/C# OpenCV] - C# OpenCV 5-1. 색공간 변환

Cv2.Threshold 이미지 이진화 [프로그래밍/C# OpenCV] - C# OpenCV 4-2. Binary

Cv2.FindContour contour 찾기 [프로그래밍/C# OpenCV] - C# OpenCV 7-1. Contour(1) 윤곽선 찾기

Cv2.drawContour contour 그리기 [프로그래밍/C# OpenCV] - C# OpenCV 7-1. Contour(1) 윤곽선 찾기

Cv2.ConvexHull Convex Hull 찾기 [프로그래밍/C# OpenCV] - C# OpenCV 7-6. Contour(6) Convex Hull

Cv2.ConvexHullIndices ConvexHull의 Index정보

Cv2.ConvexityDefects ConvexityDefects 정보

 

Example Code


using System;
using System.Windows.Forms;
using OpenCvSharp;

namespace findContour6
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Mat src = Cv2.ImRead("image.png");
            Mat result = new Mat();
            Mat bin = new Mat();
            src.CopyTo(result);
            Cv2.CvtColor(src, bin, ColorConversionCodes.BGR2GRAY);
            Cv2.Threshold(bin, bin, 0, 255, ThresholdTypes.Otsu);
            Cv2.ImShow("src", src);

            Cv2.FindContours(bin, out Point[][] contour, out HierarchyIndex[] hierarchy, 
                RetrievalModes.Tree, ContourApproximationModes.ApproxSimple);
            Cv2.DrawContours(result, contour, 0, Scalar.Yellow, 2, LineTypes.AntiAlias, hierarchy);

            Point[][] hull = new Point[contour.Length][];
            hull[0] = Cv2.ConvexHull(contour[0]);
            Cv2.DrawContours(result, hull, 0, Scalar.Red, 2, LineTypes.AntiAlias);

            int[] convexHullIdx = Cv2.ConvexHullIndices(contour[0]);
            Vec4i[] defects = Cv2.ConvexityDefects(contour[0], convexHullIdx);
            for (int i = 0; i &lt defects.Length; i++)
            {
                Point start = contour[0][defects[i].Item0];
                Point end = contour[0][defects[i].Item1];
                Point far = contour[0][defects[i].Item2];
                int d = defects[i].Item3;

                if (d > 5000)
                {
                    Scalar scalar = Scalar.RandomColor();
                    Cv2.Line(result, start, far, scalar, 2, LineTypes.AntiAlias);
                    Cv2.Line(result, end, far, scalar, 2, LineTypes.AntiAlias);
                    Cv2.Circle(result, far, 5, scalar, -1, LineTypes.AntiAlias);
                }
            }
            Cv2.ImShow("result", result);

            Cv2.WaitKey(0);
            Cv2.DestroyAllWindows();
        }
    }
}

 

Explain Code


	    Mat src = Cv2.ImRead("image.png");
            Mat result = new Mat();
            Mat bin = new Mat();
            src.CopyTo(result);
            Cv2.CvtColor(src, bin, ColorConversionCodes.BGR2GRAY);
            Cv2.Threshold(bin, bin, 0, 255, ThresholdTypes.Otsu);
            Cv2.ImShow("src", src);
            

필요한 요소 선언, 초기화

이미지 이진화

 


	    Cv2.FindContours(bin, out Point[][] contour, out HierarchyIndex[] hierarchy, 
                RetrievalModes.Tree, ContourApproximationModes.ApproxSimple);
            Cv2.DrawContours(result, contour, 0, Scalar.Yellow, 2, LineTypes.AntiAlias, hierarchy);
            

contour 찾기

contour 그리기 - 노랑

 


	    Point[][] hull = new Point[contour.Length][];
            hull[0] = Cv2.ConvexHull(contour[0]);
            Cv2.DrawContours(result, hull, 0, Scalar.Red, 2, LineTypes.AntiAlias);
            

ConvexHull 찾기

ConvexHull 그리기 - 빨강

 

	    int[] convexHullIdx = Cv2.ConvexHullIndices(contour[0]);
        

contour의 ConvexHull Index 정보 획득

Cv2.ConvexHullIndicse(IEnumerable<Point> points)

      points ConvexHull Index정보를 가져올 point 배열

 


	    Vec4i[] defects = Cv2.ConvexityDefects(contour[0], convexHullIdx);
        

획득한 ConvexHull Index 정보를 이용 Defects정보 획득

Cv2.ConvexityDefects(IEnumerable<Point> points, IEnumerable<int> convexhull)

      points contour 혹은 point배열

      convexHull 매개변수 points의 ConvexHull Index 배열

 

※ Cv2.ConvexityDefects의 반환값음 Vec4i의 형식이다, 즉 {int, int, int, int} 형식으로 반환됨

  item0 : Start Index, defects 값의 시작점

  item1 : End Index, defects 값의 끝점

  item2 : Farthest Point Index, 가장먼점

  item3 : Fixpt Depth, Hull 과 item2 사이의 거리를 근사한 점, 거리값

 


	    for (int i = 0; i &lt defects.Length; i++)
            {
                Point start = contour[0][defects[i].Item0];
                Point end = contour[0][defects[i].Item1];
                Point far = contour[0][defects[i].Item2];
                int d = defects[i].Item3;

                if (d > 5000)
                {
                    Scalar scalar = Scalar.RandomColor();
                    Cv2.Line(result, start, far, scalar, 2, LineTypes.AntiAlias);
                    Cv2.Line(result, end, far, scalar, 2, LineTypes.AntiAlias);
                    Cv2.Circle(result, far, 5, scalar, -1, LineTypes.AntiAlias);
                }
            }
            

for문을 이용 필요로 하는 정보들 그리기 - 랜덤컬러

 

결과