prepare op• 데이터 종류: depth → depth
• 호출: import fullseye as fs; fs.ledger.surface_form_remove(z, dx, order=1, method='ls', thresh=None, dy=None, iters=200, seed=0)(구현을 직접 호출하려면 import roughness; roughness.surface_form_remove(z, dx, order=1, method='ls', thresh=None, dy=None, iters=200, seed=0), 원장에서 가져오려면 opsroughness.get("surface_form_remove"))
• 원장 경유의 반환값: fullseye.ledger.surface_form_remove(...) 는 선언된 out 형 depth 의 값만 반환합니다(실제 함수는 보조 정보도 반환). 버려진 쪽이 필요하면 fullseye.ledger.surface_form_remove.raw(...) 를 쓰거나 roughness.surface_form_remove 를 직접 호출하세요.
• 실제 반환: (residual, coeffs)
격자 그대로 평면 / 2차 곡면을 제거한다. (residual, coeffs)를 반환한다.
인수
z 높이장.
dx, dy 샘플 간격. dy=None 은 정사각 화소.
order 1 = 평면, 2 = 이차 곡면.
method "ls"(최소제곱) 또는 "ransac"(로버스트).
thresh RANSAC 의 인라이어 임계값(높이 단위). None 이면 최소제곱 잔차의
로버스트한 산포 2.5 x 1.4826 x MAD 를 사용한다.
iters RANSAC 의 시행 횟수. seed 로 결정적.
coeffs 는 장의 중심을 원점으로 하는 물리 좌표의 단항식 계수. order=1 이면 [c0, gx, gy] 이고 gx/gy 가 그대로 기울기, order=2 이면 [c0, gx, gy, cxx, cxy, cyy](x^2, xy, y^2 순서).
★ 왜 격자 그대로 받는가
기존 fit_plane / fit_plane_ransac 는 (N,3) 점군밖에 받지 않는다.
512² 높이장을 넘기려면 매번 column_stack 으로 262144x3 = 6.3 MB 로
전개해야 한다(실측). 여기서는 격자를 격자 그대로 받고, 기저도
1 차원 벡터의 외적으로 만들기 때문에 전개가 필요 없다.
★ 비용(실측, 1024x1024, iters=200)
method="ls" 47 ms 에 비해 method="ransac" 는 1.8 초(38 배).
RANSAC 은 매번 1024² 점의 잔차를 다시 세므로 iters 에 선형으로 영향을 받는다.
거칠기만 본다면 "LS + λc 하이패스"로 같은 답이 1/40 비용으로 나온다
(아래 실측 참조) —— RANSAC 을 기본값으로 하지 않는 이유가 이것.
★ 함정 —— 로버스트가 필요한 것은 "깊은 흠집"이 아니라 "넓은 이상치".
단 이상치가 다수파가 되면 RANSAC 도 동시에 망가진다.
깊이 3 µm 흠집 4 개를 한쪽에 몰아 둔 512x512 면에서 흠집의 폭만을
바꾼 실측(기울기 0.050/-0.025 를 넣고 제거한다. 참값은 흠집을 포함한 면 그 자체):
흠집 반치반폭 면적비 LS 의 Sq 오차 RANSAC 의 Sq 오차 개선
4 µm 5.6 % -1.94 % -0.39 % 5.0 배
12 µm 16.3 % -6.47 % -3.03 % 2.1 배
24 µm 31.0 % -13.79 % -11.53 % 1.2 배
40 µm 46.0 % -23.80 % -23.56 % 1.0 배
3 가지를 읽을 수 있다:
• 효과를 내는 것은 깊이가 아니라 면적비. "깊은 흠집 = 로버스트 필수"는 성급한 결론이고, 올바르게는 "넓은 이상치 = 로버스트 필수".
• 오차는 반드시 과소 쪽으로 나온다 —— 최소제곱이 "흠집이 한쪽에 몰려 있는데서 오는 진짜 비대칭"까지 평면으로 흡수해 버리기 때문. 합부 판정에서는 위험한 방향으로 망가진다.
• 면적비 46 % 에서는 RANSAC 도 도움이 되지 않는다(개선 1.0 배). 이상치가 절반 가까이를 차지하면 RANSAC 의 다수결 자체가 흠집을 고른다. 로버스트 피팅은 "이상치가 소수파이다"라는 전제의 도구이며, 그 전제가 끊기는 곳은 표로 보여 줄 수밖에 없다.
★ 함정 —— λc 를 후단에 두면 LS 와 RANSAC 의 차이는 사라진다
같은 면(반치반폭 4 µm)에 λc=80 µm 하이패스를 나중에 걸면,
Sq 오차는 LS +0.00 % / RANSAC -0.00 %(위 표에서는 5.0 배 차이).
여분으로 제거한 평면은 순수한 장파장이므로, 하이패스가 같은 것을 한 번 더
버릴 뿐이다. 피팅의 로버스트성이 효과를 내는 것은 λc 를 걸지 않는 운용(평면도·형상 편차)일 때. 거칠기만 본다면 순서로 구할 수 있다.
또한 평면 자체의 복원은 LS 로도 좋아서, 위 면에 넣은 기울기
0.050 / -0.025 에 대해 0.050006 / -0.025127 이 반환된다(실측).
fail-closed(실패 시 거부)
• order 가 1 또는 2 이외 / method 가 "ls"·"ransac" 이외.
• thresh 가 양수가 아니거나 유한하지 않음.
• RANSAC 이 인라이어를 규정 수만큼 모으지 못한다(퇴화한 면).
• 샘플 데이터 카탈로그(DL URL / 라이선스) —— 2-D 는 skimage.data(BSD/public)+ 합성, 3-D 는 실데이터 소스(Stanford/PDS 등)의 DL URL.
• 연산자의 내력·참고문헌 —— 이 연산자 족의 바탕이 된 연구/기법의 출처.
• 알고리즘의 정전(저자·연도)과 용도는 위의 패밀리 사용 가이드에 적혀 있습니다.
• poc_polish_wipe_measure — py -3.11 examples/poc_polish_wipe_measure.py
• poc_pv_thermal_survey — py -3.11 examples/poc_pv_thermal_survey.py
• poc_surface_roughness — py -3.11 examples/poc_surface_roughness.py
depth 를 입력으로 받는 것)surface_filter · surface_params · surface_psd
prepare)*Provenance: roughness.py — ROUGHNESS 연산자 레지스트리. 이 op 노트는 tools/opdocs.py md 가 자동 생성합니다(직접 편집하지 마세요).*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.