| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- Encapusulation
- Unity
- Pointer
- SERIAL
- atmega328
- c++
- Filtering
- sensor
- digitalRead
- compare
- Gradient
- memory
- UNO
- public
- Read
- Class
- mfc
- parameter
- wpf
- APP
- Binary
- Android
- subpixel
- edge
- Gaussian
- flutter
- file access
- aduino
- stream
- Contour
- Today
- Total
폴크(FOLC)
치수 계산하기 - subpixel - accuracy 본문
CD 측정 같은 선형 구조 분석에는 오히려 1D 프로파일 기반 edge 추출이 정확하고 제어 가능하며, subpixel 정밀도를 높일 수 있다.
1D based edge detection
- 한 줄의 intensity profile에서 경계점을 찾는 방식 (예: 특정 row 또는 column)
- Subpixel 보간, 잡음 억제 용이, 정밀도 향상, 구조 선형성 이용 가능
- Line & Space 구조, mask/wafer CD 측정, 전자현미경 이미지 등
예제
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
// 1D derivative 계산 후 subpixel 보간으로 edge 위치 추정
vector<float> findEdges1DWithSubpixel(const vector<float>& profile) {
vector<float> edges;
for (size_t i = 1; i < profile.size() - 1; ++i) {
float prev = profile[i - 1];
float curr = profile[i];
float next = profile[i + 1];
// 1차 미분 극대점 조건 (edge 후보)
if ((curr > prev && curr > next) || (curr < prev && curr < next)) {
// Subpixel 보간 (parabola fitting)
float denom = prev - 2 * curr + next;
if (fabs(denom) < 1e-5) continue; // flat or noisy
float offset = 0.5f * (prev - next) / denom;
edges.push_back(i + offset);
}
}
return edges;
}
// 이미지에서 특정 row 기반 edge 추출
void detectEdge1D(const Mat& gray, int rowIdx) {
vector<float> profile(gray.cols);
for (int x = 0; x < gray.cols; ++x)
profile[x] = static_cast<float>(gray.at<uchar>(rowIdx, x));
// 1D 미분
vector<float> diff(profile.size(), 0);
for (int i = 1; i < profile.size() - 1; ++i)
diff[i] = 0.5f * (profile[i + 1] - profile[i - 1]);
// Subpixel edge 찾기
vector<float> edgePositions = findEdges1DWithSubpixel(diff);
// 출력
cout << "1D Subpixel Edges at row " << rowIdx << ":\n";
for (auto pos : edgePositions)
cout << " x = " << pos << " px" << endl;
// 시각화
Mat vis;
cvtColor(gray, vis, COLOR_GRAY2BGR);
for (float x : edgePositions)
circle(vis, Point((int)x, rowIdx), 3, Scalar(0, 0, 255), -1);
imshow("1D Edge Detection", vis);
waitKey(0);
}
int main(int argc, char** argv) {
if (argc < 2) {
cout << "Usage: ./Edge1D <image_path>" << endl;
return -1;
}
Mat img = imread(argv[1], IMREAD_GRAYSCALE);
if (img.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
int rowToAnalyze = img.rows / 2; // 중간 라인
detectEdge1D(img, rowToAnalyze);
return 0;
}