본문 바로가기
카테고리 없음

C# OpenCvSharp을 이용한 RANSAC 알고리즘 설명 및 구현

by tasiklee 2025. 2. 18.

1. RANSAC 알고리즘이란?

RANSAC(Random Sample Consensus)은 데이터에서 이상치(Outlier)를 제거하고 최적의 모델을 찾는 반복적인 알고리즘입니다. 일반적으로 이미지 처리와 컴퓨터 비전에서 직선 또는 곡선을 피팅할 때 사용됩니다.

이 알고리즘은 랜덤 샘플을 선택하여 모델을 추정하고, 최대한 많은 인라이어(Inlier)를 포함하는 최적 모델을 찾는 방식으로 동작합니다.


2. RANSAC 알고리즘 동작 순서

  1. 데이터에서 임의의 샘플을 선택하여 초기 모델을 생성합니다.
  2. 모델과 가장 잘 맞는 인라이어(일치하는 데이터)를 찾습니다.
  3. 인라이어를 기반으로 새로운 모델을 재추정합니다.
  4. 위 과정을 여러 번 반복하며 최적의 모델을 찾습니다.

이 과정을 거치면서 이상치(Outlier)를 효과적으로 제거하고, 신뢰할 수 있는 모델을 도출할 수 있습니다.

📌 RANSAC의 수학적 개념

주어진 데이터 집합 에서 모델 을 찾는 과정은 다음과 같습니다:

  1. 두 개의 샘플 을 선택하여 직선 모델을 정의합니다.
  2. 해당 모델이 다음 직선 방정식을 만족한다고 가정합니다.
  3. 여기서 기울기 와 절편 는 다음과 같이 계산됩니다:
  4. 모든 데이터 포인트에 대해 오차 를 계산합니다.
  5. 오차가 임계값 보다 작은 점들을 인라이어로 간주합니다.
  6. 최대 인라이어를 포함하는 모델을 최종적으로 선택합니다.

3. C# OpenCvSharp을 이용한 RANSAC 구현

📌 코드 구현

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

class Ransac
{
    public static (double a, double b) ComputeRansac(List<Point2d> points, int iterations, double threshold)
    {
        Random rand = new Random();
        int bestInlierCount = 0;
        double bestA = 0, bestB = 0;

        for (int i = 0; i < iterations; i++)
        {
            // 무작위 두 개의 점 선택
            int index1 = rand.Next(points.Count);
            int index2 = rand.Next(points.Count);
            while (index1 == index2)
                index2 = rand.Next(points.Count);

            Point2d p1 = points[index1];
            Point2d p2 = points[index2];

            // 직선의 기울기와 절편 계산
            double a = (p2.Y - p1.Y) / (p2.X - p1.X);
            double b = p1.Y - a * p1.X;

            // 인라이어 개수 측정
            int inlierCount = 0;
            foreach (var p in points)
            {
                double yEstimate = a * p.X + b;
                if (Math.Abs(p.Y - yEstimate) < threshold)
                    inlierCount++;
            }

            // 최적의 모델 갱신
            if (inlierCount > bestInlierCount)
            {
                bestInlierCount = inlierCount;
                bestA = a;
                bestB = b;
            }
        }
        return (bestA, bestB);
    }

    static void Main()
    {
        List<Point2d> points = new List<Point2d>
        {
            new Point2d(1, 2), new Point2d(2, 2.8),
            new Point2d(3, 3.6), new Point2d(4, 4.5),
            new Point2d(5, 5.1), new Point2d(10, 20) // Outlier
        };

        var (a, b) = ComputeRansac(points, 100, 1.0);
        Console.WriteLine($"RANSAC 회귀선: y = {a:F2}x + {b:F2}");
    }
}

🔍 코드 설명

  • ComputeRansac() 메서드는 임의의 두 점을 선택하여 직선을 만들고, 인라이어를 평가하여 최적의 모델을 찾습니다.
  • Main()에서 샘플 데이터를 사용하여 RANSAC을 적용합니다.
  • 일부 이상치(Outlier)를 포함하여도 강건한 모델을 찾아낼 수 있습니다.
  •  


4. RANSAC의 활용 분야

📌 주요 응용 분야

  • 컴퓨터 비전: 이미지 상에서 직선 및 원 검출
  • 로보틱스: 센서 데이터 노이즈 제거 및 위치 추정
  • 3D 재구성: 여러 이미지에서 일치하는 점을 찾는 데 사용
  • 의료 영상 처리: MRI 및 X-ray에서 이상치 필터링

📌 OpenCvSharp에서 활용 가능성

  • Cv2.FindHomography(): RANSAC을 이용한 특징점 매칭을 수행할 수 있음
  • Cv2.FitLine(): 직선 검출 시 RANSAC을 적용하여 이상치를 제거

5. 결론

이번 포스트에서는 C#과 OpenCvSharp을 이용하여 RANSAC 알고리즘을 구현하는 방법을 설명했습니다. RANSAC은 이상치를 효과적으로 제거하고 신뢰할 수 있는 모델을 찾는 강력한 방법입니다.

추후 포스트에서는 OpenCvSharp을 활용한 이미지 기반 특징점 추출 및 객체 검출을 다룰 예정이니, 많은 관심 부탁드립니다! 🚀