카테고리 없음

Edge Detect - Sub Pixel 추출

folcjin 2025. 5. 3. 10:01
728x90
반응형

서브픽셀 엣지 검출(Subpixel Edge Detection) 알고리즘은 머신 비전 분야에서 매우 정교하게 설계된 고정밀 위치 추정 기법입니다. 이 방식은 일반적인 픽셀 해상도를 넘어 0.1 픽셀 이하의 위치 정밀도를 달성할 수 있습니다.

엣지 검출의 기본 흐름
다음과 같은 순서로 작동합니다:

ROI(Region of Interest) 설정
-> 측정 위치에 ROI 위치시키기

 

픽셀 프로파일 생성 (Intensity Profile)
-> I(x)=grayscale intensity

 

Gradient 계산 (1차 미분 또는 필터 기반)
-> G(x)=I(x+1)−I(x)
또는 Gaussian Derivative 필터도 사용 가능:
-> G(x) = I(x) ∗ d / dx * Gaussian(x)

 

Peak 위치 탐색
-> 엣지는 Gradient의 극값(maximum, minimum)으로 정의됨.
찾은 극값은 정수 픽셀 좌표(ex: x = 25 픽셀)로 제공됨.

 

서브픽셀 보간 (Subpixel Interpolation or Curve Fitting)
-> 엣지를 정수 좌표가 아닌 소수점 수준의 정밀도로 구하려면 보간 또는 곡선 피팅을 수행해야 합니다. 

✔ 방법 A: 3-point Quadratic Fitting (2차 보간)
정수 좌표 근방의 3개 포인트를 이용해 2차 곡선을 피팅:
y = ax2  + bx + c
피크 위치는 다음과 같이 계산:
𝑥 peak = −𝑏 / 2𝑎
이로써 서브픽셀 정밀도의 엣지 위치가 추출됨.

✔ 방법 B: Gaussian 또는 Sinc 보간
엣지가 Gaussian 형태일 경우, 로그 변환하여 Gaussian fit을 수행.
더 높은 정밀도가 필요할 경우, 전체 profile을 곡선 피팅하여 위치를 추정함.

 

참고 구현 예 (유사 코드)

#include <iostream>
#include <vector>
#include <cmath>

// 서브픽셀 위치를 추정하는 함수
double estimateSubpixelPeak(const std::vector<double>& gradient, int peakIndex) 
{
    if (peakIndex <= 0 || peakIndex >= gradient.size() - 1) 
    {
        std::cerr << "Peak index out of bounds for interpolation.\n";
        return static_cast<double>(peakIndex); // fallback to integer position
    }

    double y0 = gradient[peakIndex - 1];
    double y1 = gradient[peakIndex];
    double y2 = gradient[peakIndex + 1];

    // 2차 보간 공식에 따른 서브픽셀 위치 보정값 계산
    double denominator = (y0 - 2 * y1 + y2);
    if (std::abs(denominator) < 1e-6) 
    {
        return static_cast<double>(peakIndex); // Flat region: no meaningful peak
    }

    double offset = 0.5 * (y0 - y2) / denominator;

    return static_cast<double>(peakIndex) + offset;
}

int main() 
{
    // 예시 gradient 값 (1차 미분 결과), 엣지가 중심에 존재한다고 가정
    std::vector<double> gradient = {0.1, 0.6, 1.2, 2.5, 3.8, 4.1, 3.9, 2.2, 0.9, 0.3};

    // 가장 강한 gradient 위치 찾기 (엣지 후보)
    int maxIndex = 0;
    for (int i = 1; i < gradient.size() - 1; ++i) 
    {
        if (gradient[i] > gradient[maxIndex]) 
        {
            maxIndex = i;
        }
    }

    double subpixelEdge = estimateSubpixelPeak(gradient, maxIndex);

    std::cout << "Integer edge position: " << maxIndex << "\n";
    std::cout << "Subpixel edge position: " << subpixelEdge << "\n";

    return 0;
}

 

✅ 정리
엣지 검출 방식 Gradient 기반, 프로파일 분석
서브픽셀 추정 3-point quadratic fitting, Gaussian fitting
정확도 ±0.05 픽셀 이하 (조건에 따라 달라짐)

728x90
반응형
사업자 정보 표시펼치기/접기
사업자 등록번호 : -- | TEL : --