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

다각형 근사(Approx Poly)

다각형 근사는 검출된 윤곽선의 형상을 분석할 때 정점(Vertex)의 수가 적은 다각형으로 표현할 수 있게 다각형 곡선을 근사하는 방법입니다.

다각형 근사는 더글라스-패커(Douglas-Peucker) 알고리즘을 사용합니다.

반복끝점을 이용해 선분으로 구성된 윤곽선들을 더 적은 수의 윤곽점으로 동일하거나 비슷한 윤곽선으로 데시메이트(Decimate)합니다.

더글라스-패커 알고리즘은 근사치 정확도(Epsilon)의 값으로 기존의 다각형윤곽점이 압축된 다각형최대 편차를 고려해 다각형을 근사하게 됩니다.

  • Tip : 데시메이트(Decimate)일정 간격으로 샘플링된 데이터를 기존 간격보다 더 큰 샘플링 간격으로 다시 샘플링하는 것을 의미합니다.



메인 코드

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);

            List<Point[]> new_contours = new List<Point[]>();
            foreach (Point[] p in contours)
            {
                double length = Cv2.ArcLength(p, true);
                if (length < 100) continue;

                new_contours.Add(Cv2.ApproxPolyDP(p, length * 0.02, true));
            }

            Cv2.DrawContours(dst, new_contours, -1, new Scalar(255, 0, 0), 2, LineTypes.AntiAlias, null, 1);
            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);
if (length < 100) continue;

new_contours.Add(Cv2.ApproxPolyDP(p, length * 0.02, true));

윤곽선 길이 함수(Cv2.ArcLength)를 활용해 length가 100 이상의 값만 new_contours의 값으로 사용합니다.

다각형 근사 함수(Cv2.ApproxPolyDP)를 통해 근사치 정확도(Epsilon)의 값으로 근사합니다.

Cv2.ApproxPolyDP(원본 배열, 근사치 정확도, 폐곡선 여부)로 다각형 근사를 적용합니다.

원본 배열에서 근사치 정확도값으로 다각형 근사를 진행합니다.

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

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

다각형 근사 함수에서 가장 중요한 매개변수는 근사치 정확도입니다.

일반적으로 전체 윤곽선 길이의 1% ~ 5%의 값을 사용합니다.

다각형 근사 함수(Cv2.ApproxPolyDP)는 새로운 윤곽 배열을 반환하며, 이 값을 바로 new_contours에 추가합니다.



출력 결과

댓글 남기기