frame_align — ASTROSTACK align op

• 데이터 종류: image2d × image2d → matrix

• 호출: import fullseye as fs; fs.ledger.frame_align(reference, frame, model='similarity', threshold_sigma=5.0, max_stars=60, tolerance_px=2.0, max_shift_px=None, ransac_iters=500, seed=0, min_inliers=3)(구현을 직접 호출하려면 import astrostack; astrostack.frame_align(reference, frame, model='similarity', threshold_sigma=5.0, max_stars=60, tolerance_px=2.0, max_shift_px=None, ransac_iters=500, seed=0, min_inliers=3), 원장에서 가져오려면 opsastrostack.get("frame_align"))

• 원장 경유의 반환값: fullseye.ledger.frame_align(...) 는 선언된 out 형 matrix 의 값만 반환합니다(실제 함수는 보조 정보도 반환). 버려진 쪽이 필요하면 fullseye.ledger.frame_align.raw(...) 를 쓰거나 astrostack.frame_align 를 직접 호출하세요.

• 실제 반환: (matrix, info) -> matrix

사용법

별의 대응으로부터 frame → reference 의 2-D 변환을 추정합니다.

공정은 3단계이며, 추정의 본체는 모두 기존 op:

1. star_detect로 양쪽의 별을 얻는다.

2. 대략적인 평행 이동을 오프셋 투표로 낸다(_vote_translation).

여기서 features.match_keypoints를 쓰지 않는 것은 실측에 근거한 판단으로,

별 필드의 9x9 패치는 서로 거의 같은 모양이므로 Lowe의 비 검정

(기본값 ratio=0.8)이 거의 전부를 버린다. 128x128에 40개 별, 참 어긋남이

(+0.590, -0.540) px인 프레임 쌍에서의 실측: match_keypoints가

반환한 대응은 4건, 그중 참값에서 1 px 이내는 0건(= 쓸 수 있는 것이

1개도 없다). 같은 쌍에서 투표법은 26표 → 26 대응 → 26 인라이어, 추정 오차

0.0155 px. 별 필드는 "특징이 없는" 것이 아니라 "특징이 전부 같은" 것이므로,

기술자가 아니라 배치의 기하를 쓰는 것이 옳다.

3. 대략적인 이동으로 최근접 대응을 만들고, mosaic.proj_match_points_ransac로 오대응을 떨어뜨리고, fit_transform.vector_to_similarity(model에 따라 vector_to_rigid / vector_to_hom_mat2d)로 피팅한다. RANSAC 루프도 Umeyama도 여기에는 쓰여 있지 않다.

★반복 구조에는 쓸 수 없다(2026-09-08, poc_print_registration이 발견). inlier_ratio는 "같은 답에 찬성한 대응의 비율"이지 "답이 옳을확률"이 아니다. 망점·직물·격자처럼 같은 모양이 주기적으로 늘어선 이미지에서는격자 벡터만큼 어긋난 대응도 전원이 찬성하므로, 찬성률은 1.00인 채로답만 격자 1개만큼(혹은 몇 개만큼) 어긋난다.

실측: 256x256의 133 lpi 상당·15도 망점을 (0.00, +1.30) px만어긋낸 쌍에서, inlier_ratio 1.00 / rms_px 0.78을 반환하면서추정은 (+54.24, +30.12) px. 별 필드(128x128, 40개 별, 참값(+0.59, -0.54))에서는 inlier_ratio는 똑같이 1.00이고 추정은 옳다. 찬성률로는 2가지를 구별할 수 없다.

구별할 수 있는 것은 vote_margin —— 투표의 2번째 봉우리의 높이를 1번째로나눈 값으로, 0이면 봉우리는 1개, 1에 가까울수록 "똑같이 그럴듯한 답이그 밖에도 있다". 같은 2가지 예에서 망점 0.857 / 별 필드 0.143. 주기 구조를 넘길수도 있는 경로에서는 inlier_ratio가 아니라 이쪽을 볼 것. 평행 이동 자체만 필요하다면 piv_cross_correlate의 상관면을보는 편이 솔직하며, 그쪽은 봉우리가 몇 개 서 있는지를 스스로 셀 수 있다.

*model* "translation"은 대응 차이의 중앙값만 사용한다(별이 1개여도 동작한다). "rigid" = 회전 + 병진, "similarity" = + 등방 스케일, "affine" = 6 자유도. 시야가 넓지 않으면 "similarity"로 충분하다 (적도의의 추적 오차는 회전과 병진, 대기차는 스케일에 1차로 실린다).

Returns (matrix, info):

• matrix —— (3, 3) float64. (row, col, 1)에 왼쪽에서 곱하면 reference의 좌표가 된다(fit_transform과 같은 규약).

• info —— dict. n_stars_ref / n_stars_src / n_pairs / n_inliers / inlier_ratio / shift_row / shift_col / rotation_deg / scale / rms_px(인라이어의 잔차 RMS) / model.

fail-closed: 인라이어가 *min_inliers*에 못 미치면 ValueError를발생시킨다. 항등 변환을 조용히 반환하지 않는다 —— 위치 맞춤에 실패한 프레임을 "어긋남 0"으로 합성에 섞으면 예외도 경고도 없이 이중상이 생긴다.

Raises ValueError: 2-D가 아님 / 형태가 다름 / *model*이 ALIGN_MODELS에 없음 / 어느 한쪽에서 별이 1개도 발견되지 않음 / 대응을 만들 수 없음 / 인라이어가 부족한 경우.

참고(샘플 데이터·문헌)

• 샘플 데이터 카탈로그(DL URL / 라이선스) —— 2-D 는 skimage.data(BSD/public)+ 합성, 3-D 는 실데이터 소스(Stanford/PDS 등)의 DL URL.

• 연산자의 내력·참고문헌 —— 이 연산자 족의 바탕이 된 연구/기법의 출처.

• 알고리즘의 정전(저자·연도)과 용도는 위의 패밀리 사용 가이드에 적혀 있습니다.

실행 가능한 예제(이 연산자를 실제로 호출하는 검증된 샘플)

• astro_stacking — py -3.11 examples/astro_stacking.py

• poc_exoplanet_transit — py -3.11 examples/poc_exoplanet_transit.py

• poc_print_registration — py -3.11 examples/poc_print_registration.py

타입이 이어지는 다음 연산자(matrix 를 입력으로 받는 것)

—

같은 카테고리(align)

align_frames


*Provenance: astrostack.py — ASTROSTACK 연산자 레지스트리. 이 op 노트는 tools/opdocs.py md 가 자동 생성합니다(직접 편집하지 마세요).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.