반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

폴크(FOLC)

치수 계산하기 - robust edge detection 5 본문

카테고리 없음

치수 계산하기 - robust edge detection 5

folcjin 2025. 6. 21. 20:00
728x90
반응형

Knife-edge Method (Gaussian Profile Estimation) 은 광학 시스템의 Point Spread Function(PSF)을 정량적으로 평가하는 데 사용되는 대표적인 간접 측정 방법 중 하나입니다. 여기서 PSF는 시스템이 한 점 광원을 어떻게 퍼뜨리는지를 나타내는 함수이며, 이는 시스템의 해상도와 직결됩니다.

기본 원리
- Knife-edge method는 광원이 일정한 에너지를 가진 빔(보통 Gaussian 분포를 가짐)을 생성할 때, 그 빔의 일부를 knife(날카로운 가장자리, 예: 블레이드)로 차단하고, detector(카메라, 포토다이오드 등)로 전달되는 빛의 세기를 측정하는 방식입니다.
- 측정된 신호는 광원의 **적분된 intensity profile (Edge Spread Function; ESF)**이 되며, 이를 미분하면 **Line Spread Function (LSF)**을 얻습니다.
- 이 LSF가 Gaussian 형태라고 가정하면, 이를 이용하여 Gaussian의 σ (표준편차)와 FWHM(Full Width at Half Maximum)을 추정할 수 있습니다.

 

알고리즘 순서

Edge profile 측정 (ESF)
– 빔이 knife-edge를 따라 이동하며 검출된 광세기(I(x))를 수집.

미분 (LSF)
– 측정된 ESF를 수치 미분하여 LSF를 얻음.

Gaussian curve fitting
– LSF를 Gaussian 모델에 맞춰 적합하여 sigma(σ) 추정.

FWHM 계산
– FWHM = 2.3548 * σ 를 이용하여 시스템 해상도 계산.

 

예제

#include <iostream>
#include <vector>
#include <cmath>
#include <numeric>
#include <algorithm>

// Gaussian fitting을 위한 간단한 모델
double gaussian(double x, double A, double mu, double sigma) {
    return A * std::exp(-0.5 * std::pow((x - mu) / sigma, 2));
}

// 간단한 수치 미분
std::vector<double> numerical_derivative(const std::vector<double>& y, double dx) {
    std::vector<double> dy(y.size() - 1);
    for (size_t i = 0; i < dy.size(); ++i)
        dy[i] = (y[i + 1] - y[i]) / dx;
    return dy;
}

// 가우시안 피팅 (초간단 비선형 최적화 - 실제 적용에는 Levenberg-Marquardt 권장)
void fit_gaussian(const std::vector<double>& x, const std::vector<double>& y, double& A, double& mu, double& sigma) {
    // 초기값 추정
    auto max_it = std::max_element(y.begin(), y.end());
    A = *max_it;
    size_t idx = std::distance(y.begin(), max_it);
    mu = x[idx];

    // 분산 추정
    double sum = 0.0, weight_sum = 0.0;
    for (size_t i = 0; i < x.size(); ++i) {
        double w = y[i];
        sum += w * std::pow(x[i] - mu, 2);
        weight_sum += w;
    }
    sigma = std::sqrt(sum / weight_sum);
}

int main() {
    // 예시: ESF (Edge Spread Function) 측정 데이터
    const int N = 100;
    double dx = 0.1;
    std::vector<double> x(N), esf(N);

    // 가우시안 적분 형태로 에지 스프레드 시뮬레이션
    double true_sigma = 1.5;
    for (int i = 0; i < N; ++i) {
        x[i] = (i - N / 2) * dx;
        esf[i] = 0.5 * (1.0 + std::erf(x[i] / (std::sqrt(2.0) * true_sigma))); // 적분된 Gaussian
    }

    // LSF 구하기
    std::vector<double> lsf = numerical_derivative(esf, dx);
    std::vector<double> x_lsf(x.begin(), x.end() - 1);

    // Gaussian fitting
    double A, mu, sigma;
    fit_gaussian(x_lsf, lsf, A, mu, sigma);

    // 결과 출력
    std::cout << "Estimated Sigma: " << sigma << std::endl;
    std::cout << "Estimated FWHM: " << 2.3548 * sigma << std::endl;

    return 0;
}
측정된 ESF 데이터를 기반으로 LSF를 얻고 Gaussian curve를 피팅하여 sigma와 FWHM을 계산

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