일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- SERIAL
- parameter
- atmega328
- Read
- wpf
- flutter
- digitalRead
- Unity
- stream
- subpixel
- Pointer
- memory
- Gradient
- aduino
- edge
- public
- Encapusulation
- Binary
- Class
- compare
- mfc
- c++
- Gaussian
- UNO
- APP
- Android
- file access
- Filtering
- sensor
- Contour
- Today
- Total
폴크(FOLC)
치수 계산하기 - robust edge detection 5 본문
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을 계산