상위 목록: 하위 목록: 작성 날짜: 읽는 데 17 분 소요

윤곽선 관련 함수는 검출된 윤곽선의 형상을 분석 및 재가공할 때 사용되는 함수입니다.

윤곽선 검출 정보를 활용하여 파생될 수 있는 정보를 제공합니다.

윤곽선 객체의 중심점, 길이, 넓이, 최소 사각형 등 윤곽선 정보를 통해 계산할 수 있는 정보들을 쉽게 구할 수 있습니다.



메인 코드

using System;
using OpenCvSharp;
using System.Collections.Generic;

namespace Project
{
    class Program
    {
        static void Main(string[] args)
        {
            Mat src = new Mat("hex.jpg");
            Mat yellow = new Mat();
            Mat dst = src.Clone();

            Point[][] contours;
            HierarchyIndex[] hierarchy;

            Cv2.InRange(src, new Scalar(0, 127, 127), new Scalar(100, 255, 255), yellow);
            Cv2.FindContours(yellow, out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxTC89KCOS);
            
            foreach (Point[] p in contours)
            {
                double length = Cv2.ArcLength(p, true);
                double area = Cv2.ContourArea(p, true);

                if (length < 100 && area < 1000 && p.Length < 5) continue;

                Rect boundingRect = Cv2.BoundingRect(p);
                RotatedRect rotatedRect = Cv2.MinAreaRect(p);
                RotatedRect ellipse = Cv2.FitEllipse(p);

                Point2f center;
                float radius;
                Cv2.MinEnclosingCircle(p, out center, out radius);

                Cv2.Rectangle(dst, boundingRect, Scalar.Red, 2);
                Cv2.Ellipse(dst, rotatedRect, Scalar.Blue, 2);
                Cv2.Ellipse(dst, ellipse, Scalar.Green, 2);
                Cv2.Circle(dst, (int)center.X, (int)center.Y, (int)radius, Scalar.Yellow, 2);
            }

            Cv2.ImShow("dst", dst);
            Cv2.WaitKey(0);
        }   
    }
}


세부 코드

Mat src = new Mat("hex.jpg");
Mat yellow = new Mat();
Mat dst = src.Clone();

new Mat을 사용해 이미지를 src에 할당합니다.

전처리 결과를 저장할 yellow를 선언합니다.

연산 결과를 저장할 dst를 선언합니다.


Point[][] contours;
HierarchyIndex[] hierarchy;

Cv2.InRange(src, new Scalar(0, 127, 127), new Scalar(100, 255, 255), yellow);
Cv2.FindContours(yellow, out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxTC89KCOS);

List<Point[]> new_contours = new List<Point[]>();
foreach (Point[] p in contours)
{
    ...
}

윤곽선 관련 함수 알고리즘은 윤곽선 형태의 배열 구조를 사용해 근사합니다.

그러므로, 윤곽선 검출 알고리즘을 진행합니다.

윤곽선 관련 함수 알고리즘은 하나의 윤곽선을 대상으로 진행되므로, 반복문(foreach)를 활용해 개별의 윤곽선에서 정보를 계산합니다.


double length = Cv2.ArcLength(p, true);
double area = Cv2.ContourArea(p, true);

윤곽선 길이 함수(Cv2.ArcLength)는 윤곽선의 전체 길이를 계산합니다.

Cv2.ArcLength(윤곽선 배열, 폐곡선 여부)로 윤곽선 길이를 계산합니다.

윤곽선 넓이 함수(Cv2.ContourArea)는 윤곽선의 면적을 계산합니다.

Cv2.ContourArea(윤곽선 배열, 폐곡선 여부)로 윤곽선 면적을 계산합니다.

폐곡선 여부는 시작점과 끝점의 연결 여부를 의미합니다.

참 값을 사용할 경우, 마지막 점과 시작 점이 연결된 것으로 간주합니다.

폐곡선 여부에 따라 결괏값이 달라집니다.


if (length < 100 && area < 1000 && p.Length < 5) continue;

간단한 조건문(if)을 활용해 유의미한 정보만 계산합니다.

윤곽선의 길이가 100 미만, 면적이 1000 미만, 윤곽점의 개수가 5 미만인 윤곽선은 무시합니다.


Rect boundingRect = Cv2.BoundingRect(p);

경계 사각형 함수(Cv2.BoundingRect)는 윤곽선의 경계면을 둘러싸는 사각형을 계산합니다.

Cv2.BoundingRect(윤곽선 배열)로 최소 크기 사각형을 계산합니다.

경계 사각형 함수는 Rect 구조체를 반환합니다.


RotatedRect rotatedRect = Cv2.MinAreaRect(p);

최소 면적 사각형 함수(Cv2.MinAreaRect)는 윤곽선의 경계면을 둘러싸는 최소 크기의 사각형을 계산합니다.

Cv2.MinAreaRect(윤곽선 배열)로 최소 크기 사각형을 계산합니다.

최소 면적 사각형 함수는 RotatedRect 구조체를 반환합니다.


RotatedRect ellipse = Cv2.FitEllipse(p);

최소 면적 원 함수(Cv2.FitEllipse)는 윤곽선의 경계면을 둘러싸는 최소 크기의 원을 계산합니다.

Cv2.FitEllipse(윤곽선 배열)로 최소 크기 원을 계산합니다.

최소 면적 원 함수는 RotatedRect 구조체를 반환합니다.

최소 면적을 갖는 원은 타원 형태를 가질 수 있으므로, RotatedRect 형태를 갖습니다.


Point2f center;
float radius;
Cv2.MinEnclosingCircle(p, out center, out radius);

타원 피팅 함수(Cv2.MinEnclosingCircle)는 윤곽선에 가장 근사한 원을 계산합니다.

Cv2.MinEnclosingCircle(윤곽선 배열, 중심점, 반지름)로 타원을 계산합니다.

타원 피팅 함수는 out 키워드를 활용해 중심점과 반지름을 반환합니다.


Cv2.Rectangle(dst, boundingRect, Scalar.Red, 2);
Cv2.Ellipse(dst, rotatedRect, Scalar.Blue, 2);
Cv2.Ellipse(dst, ellipse, Scalar.Green, 2);
Cv2.Circle(dst, (int)center.X, (int)center.Y, (int)radius, Scalar.Yellow, 2);

그리기 함수를 활용해 검출된 윤곽선 정보를 이미지 위에 표시합니다.

rotatedRect 구조체는 사각형타원을 그릴 수 있습니다.

해당 구조체는 호 그리기 함수(Cv2.Ellipse)로 그릴 수 있습니다.


출력 결과

댓글 남기기