Edge Detect - Sub Pixel 추출
서브픽셀 엣지 검출(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 픽셀 이하 (조건에 따라 달라짐)