deskew — 2D geometry op

• 데이터 종류: image → image

• 호출: fullseye.apply(img, "deskew", a=0.5, b=0.5)(2-D 는 이미지 1 장 + 스칼라 노브 2 개 a,b∈[0,1] 모델)

deskew: input → output

*그림은 128×128 합성 입력에서 실제로 실행한 출력. 왼쪽이 입력, 오른쪽이 출력. 점군은 위에서 본 산점도(밝기 = z), 1-D 열은 꺾은선, 볼륨은 z 방향 최대값 투영, 동영상은 가운데 프레임, 복소 영상은 진폭이며, 그림이 되지 않는 반환값은 값 자체를 표시한다.*

노브 a 를 훑기(0.1 / 0.5 / 0.9, 다른 노브는 기본값):

▸ deskew: 노브 a 스윕 (문서 사이트)

노브 b 를 훑기(0.1 / 0.5 / 0.9, 다른 노브는 기본값):

▸ deskew: 노브 b 스윕 (문서 사이트)

단계(앞에 오는 op → 이 op, 왼쪽에서 오른쪽으로):

▸ deskew: 단계 (문서 사이트)

다른 영상에서도(합성 장면 / 사진 / 동전. 윗줄이 입력, 아랫줄이 그 출력. 노브는 기본값):

▸ deskew: 다른 입력 이미지 (문서 사이트)

*컬러 (H,W,3) 입력은 싣지 않았다: 이 op는 색 채널을 세 번째 공간축으로 다룬다(채널을 넘나듦). 채널별로 나눠 호출할 것.*

사용법

기울기를 측정해 바로 세운다(deskew). 각도는 노브로 주는 것이 아니라 영상에서 추정한다.

a가 탐색 범위 ±(2 + 43a)°를 바꾼다(a=0에서 ±2°, a=1에서 ±45°). b가정밀화의 스텝 1/(1 + round(9b))°를 바꾼다(b=0에서 1° 스텝, b=1에서 0.1° 스텝. 촘촘할수록 느리다 ―― 여기가 거래가 되어 있다).

판정량은 가로 방향 사영 프로파일의 차분 제곱합. 어떤 각도로 돌렸을 때 행이가지런해지면, 행 방향으로 눌러 찌그러뜨린 농도의 꺾은선이 가장 격렬하게 오르내린다. 1° 스텝으로 거칠게 찾고, 최선의 ±1°를 b의 스텝으로 좁힌다. 동점이면 각도가 작은 쪽을 택하므로, 구조가 없는 영상·빈 프레임에서는 0°(= 입력을 그대로 반환)로 떨어진다.

• 탐색은 긴 변 256 화소로 솎아낸 사본에서 한다(각도는 솎아내기로 바뀌지 않는다). 원래 크기로 돌리는 것은 마지막 1회뿐. 512x512에서 가장 넓은 탐색이라도 실측 121 ms.

• 점수는 회전 후의 중앙 정사각형(한 변 = min(H,W)/sqrt(2))에서만 취한다 ―― 어느 각도에서도 틀 안에 들어가는 범위이므로, 모서리를 채우는 방식이 점수에 섞이지 않는다.

• 틀 밖은 가장자리의 중앙값으로 채운다(mode="constant"). 기존의 rotate_image는거울 반사로 채우기 때문에 장표를 세우면 네 모서리에 거울 문자가 비쳐 들어간다(그쪽 docstring이스스로 "틀 밖을 배경색으로 채우고 싶은 용도에는 맞지 않는다"고 인정하고 있다). 세운 것을그대로 OCR·잘라내기로 넘길 수 있다는 것이 이 op가 더하는 점이다.

실측 정밀도와 한계(행간 14 화소·폭 384 화소의 합성 페이지): b=1(0.1° 스텝)에서 1 / 2 / 3.7 / 5 / 12 / 20° 모두 오차 0.00°. 다만 0.6° 미만의 기울기는 0을 반환한다 ―― 페이지 폭 가득해도 행의 어긋남이 1 화소에 미치지 못해, 사영의 날카로움이 보간의뭉개짐에 묻히기 때문. 세밀하게 측정하고 싶다면 입력을 크게 한다(판정량은 폭에 비례한다).

선행 연구: 사영 프로파일로 기울기를 재는 것은 고전이며, Postl (1986)이 분산을, Baird (1987)가 제곱합 + 성김·촘촘함의 각도 탐색을 판정량으로 했다. 이 op는 Baird의 계보이며, 새로운 것은 기법이 아니라 가장자리의 처리다(아래).

★이전에는 차분 기준이 +3.0 도 어긋나 있었다. 그 원인이 확정되었다. 2026-09-17의 사전 측정에서, 참값 −7/−3/+3/+7 도 에 대해 분산 기준은 오차 0.0 도, 차분 기준은 4개 모두 +3.0 도 어긋났고, 원인은 ndimage.rotate가 만드는 가장자리의 인공물이겠지만 "mode="constant"로 사라지는지는 미검증"이라고기록해 두었다. 칠하는 방식이 아니라 보는 범위가 원인이었다 —— 회전 후의 내접 정사각형에서만 점수를취하면, 차분 기준으로도 1/2/3.7/5/12/20 도 모두에서 오차 0.00 도 가 된다(실측).

값 범위는 입력 그대로(선형 보간과 가장자리의 중앙값은 둘 다 값 범위를 넓히지 않는다). ★빈 프레임(값 범위 1e-9 미만)과 8 화소 미만의 입력은 그대로 반환한다. ★타일 분할해서는 안 된다 ―― 각도는 영상 전체에서 1개로 정해지는 것이며, 타일마다 측정하면 각 타일이 서로 다른 각도로돌아간다(scale.py에 이유와 함께 등록되어 있음).

자세한 사용 가이드

• gallery2d_geometry 패밀리 가이드

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

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

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

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

Studio에서 시도하기

아래 프로그램은 실제로 실행됨을 확인했습니다(그림과 같은 입력). Studio 도움말에서는 이 블록이 버튼이 되어 즉시 불러와 실행할 수 있습니다.

rotate_img 0.58 0.50
deskew 0.50 0.50

▸ 이 파이프라인 불러오기  ·  불러와서 실행

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

• gallery2d_geometry — py -3.11 examples/gallery2d_geometry.py

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

identity · gaussian · mean_box · bilateral · unsharp · median · min_filter · max_filter

같은 카테고리(geometry)

rotate_img · rescale_img · affine_warp · sk_swirl · mirror_image · transpose_region · rotate_image · zoom_image_factor


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

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