Gyroflow로 이해하는 EIS 파이프라인

오픈소스로 들여다보는 손떨림 보정의 내부 구조

by Bluefree

들어가며

이전 글에서 OIS, EIS, HIS의 차이를 다뤘다. 그중 EIS에 대해 "자이로 데이터를 기반으로 프레임을 보정한다"는 정도로 설명했는데, 실제로 그 안에서 일어나는 일은 생각보다 복잡하다.

EIS는 단순히 "흔들린 영상을 크롭해서 안정화하는 것"이 아니다. 자이로 센서에서 데이터를 읽고, 카메라의 움직임을 추정하고, 어떤 움직임을 남기고 어떤 움직임을 제거할지 판단하고, 최종적으로 프레임을 변환하는 일련의 파이프라인이다.

이 글에서는 Gyroflow라는 오픈소스 프로젝트를 참조하면서, EIS 파이프라인의 각 단계가 실제로 무엇을 하는지 들여다본다. 상용 제품의 EIS 구현은 공개되어 있지 않지만, Gyroflow는 동일한 원리를 오픈소스로 구현하고 있어서 학습 소재로 매우 적합하다.


Gyroflow란

Gyroflow는 자이로스코프 데이터를 이용한 영상 안정화 오픈소스 소프트웨어다. 원래 액션캠이나 드론 촬영 영상의 후처리 안정화를 목적으로 만들어졌다.

주요 특징을 정리하면 이렇다:

자이로 데이터 기반: 영상의 모션 벡터를 영상 분석(optical flow)이 아닌 자이로 센서 데이터로 추정한다

다양한 카메라 지원: GoPro, DJI, Sony, Insta360 등 주요 액션캠의 자이로 데이터를 직접 읽을 수 있다

렌즈 프로파일: 어안 렌즈를 포함한 다양한 렌즈의 왜곡 모델을 내장하고 있다

GPU 가속: OpenCL/wgpu 기반으로 실시간에 가까운 처리 속도를 지원한다

Rust 기반: 코어 로직이 Rust로 작성되어 있어 코드가 비교적 읽기 쉽다

GitHub에서 소스코드를 볼 수 있고, 커뮤니티도 활발하다. 실사용 목적뿐 아니라, EIS가 내부적으로 어떻게 동작하는지를 이해하기 위한 참고 자료로도 가치가 높다.


EIS 파이프라인 전체 흐름

EIS 파이프라인은 크게 다섯 단계로 나눌 수 있다. 아래 다이어그램이 전체 흐름이다.

eis_pipeline_kr.png

각 단계를 하나씩 살펴보자.


1단계: 자이로 데이터 수집

자이로스코프 센서는 카메라의 각속도(angular velocity)를 측정한다. 쉽게 말하면, 카메라가 어느 방향으로, 얼마나 빠르게 회전하고 있는지를 3축(pitch, yaw, roll)으로 기록하는 것이다.

이 데이터는 보통 카메라 펌웨어 단에서 영상 프레임과 함께 기록된다. GoPro 같은 액션캠은 이 자이로 데이터를 영상 파일의 메타데이터에 포함시킨다. Gyroflow는 이 메타데이터를 파싱해서 자이로 데이터를 추출한다.

여기서 중요한 점이 있다:


타임스탬프 동기화

자이로 데이터와 영상 프레임의 타임스탬프가 정확히 일치해야 한다. 자이로 센서의 샘플링 레이트(보통 200Hz~8kHz)와 영상 프레임 레이트(30fps, 60fps 등)는 다르기 때문에, 특정 프레임에 해당하는 자이로 데이터를 정확히 매칭하려면 시간 동기화가 필수다.

이 동기화가 얼마나 민감한지 구체적으로 말하면, 오프셋이 10ms만 어긋나도 보정 방향이 실제 흔들림과 반대가 되어 흔들림이 오히려 2배로 증폭될 수 있다. 30fps 영상 기준으로 1프레임이 약 33ms이니, 10ms는 프레임 1/3에 불과하지만 결과물에는 치명적이다. Gyroflow에서는 이 오프셋을 자동 또는 수동으로 조정할 수 있는데, 상용 제품에서는 하드웨어 레벨에서 동기화를 맞추는 것이 일반적이다.


자이로 데이터의 노이즈

자이로 센서 데이터에는 항상 노이즈가 포함되어 있다. 드리프트(drift)라고 불리는 느린 오차 누적도 있고, 고주파 노이즈도 있다. 이 노이즈를 그대로 사용하면 보정 결과가 떨리거나 불안정해진다. 따라서 자이로 데이터 자체에 대한 전처리(로우패스 필터 등)가 필요하다.


2단계: 모션 추정 — 카메라 자세 계산

자이로 데이터(각속도)를 시간에 대해 적분하면 카메라의 자세(orientation)를 얻을 수 있다. 각 프레임 시점에서 카메라가 어떤 방향을 향하고 있었는지를 쿼터니언(quaternion)이나 회전 행렬로 표현한다.


각속도 데이터 → 시간 적분 → 프레임별 카메라 자세 (쿼터니언)


이 과정에서 몇 가지 실무적인 문제가 생긴다:


적분 드리프트

각속도를 적분하면 오차가 누적된다. 이것이 자이로 드리프트다. 짧은 구간에서는 문제가 없지만, 수십 초~수 분 길이의 영상에서는 무시할 수 없는 수준으로 쌓인다. Gyroflow에서는 이 드리프트를 보정하기 위해 optical flow 기반 보조 추정을 함께 사용하는 옵션이 있다.


좌표계 변환

자이로 센서의 좌표계와 카메라(이미지) 좌표계가 항상 일치하지는 않는다. 센서가 기판 위에 어떤 방향으로 실장되어 있느냐에 따라 축 매핑이 달라진다. Gyroflow에서 IMU orientation 설정이 있는 이유가 이것이다. 상용 제품에서는 이 매핑이 펌웨어에 고정되어 있다.


3단계: 스무딩 — 어떤 움직임을 남기고, 어떤 움직임을 제거할 것인가

이 단계가 EIS의 핵심이자, 결과물의 품질을 가장 크게 좌우하는 부분이다.

카메라의 움직임에는 두 종류가 있다:

의도된 움직임: 패닝, 틸팅 등 촬영자가 의도한 부드러운 카메라 이동

의도되지 않은 움직임: 손떨림, 걷기 진동 등 원치 않는 흔들림

EIS의 목표는 후자만 제거하고 전자는 살리는 것이다. 문제는 이 둘을 자동으로 완벽하게 구분하는 것이 불가능하다는 점이다.


단순 로우패스 필터의 한계

가장 직관적인 접근은 카메라 자세 데이터에 **로우패스 필터(LPF)**를 적용하는 것이다. 고주파 흔들림은 제거하고 저주파 움직임은 통과시킨다는 발상이다.

그러나 이 방법에는 근본적인 문제가 있다:

컷오프 주파수를 낮게 설정하면 → 손떨림은 잘 잡히지만, 빠른 패닝에 지연이 생긴다 (영상이 뒤따라오는 느낌)

컷오프 주파수를 높게 설정하면 → 패닝 반응은 좋지만, 손떨림이 남는다


결국 고정된 LPF로는 "안정적이면서도 반응이 빠른" 결과를 동시에 얻기 어렵다.


Gyroflow의 스무딩 알고리즘

Gyroflow는 여러 스무딩 알고리즘을 제공하며, 대표적으로:

Plain 3D: 쿼터니언 공간에서의 가우시안 스무딩. 단순하지만 기본적인 결과를 낸다.

Horizon lock: 수평선을 고정하는 특수 모드. 드론 영상에 자주 사용된다.

Fixed camera: 카메라가 고정된 것처럼 모든 움직임을 제거. 삼각대 효과.

Velocity dampened: 카메라 이동 속도에 따라 스무딩 강도를 동적으로 조절한다. 정지 시에는 강하게, 패닝 시에는 약하게.


이 중 velocity dampened 방식이 가장 실용적이다. 단순 LPF의 한계를 극복하기 위해 "카메라가 빠르게 움직이면 스무딩을 줄이고, 정지 상태이면 스무딩을 강하게"라는 적응적 접근을 취하기 때문이다.

상용 제품의 EIS도 원리적으로는 비슷한 적응적 스무딩을 사용하지만, 구체적인 구현은 제조사마다 다르고 공개되지 않는다.


4단계: 프레임 워핑

스무딩을 통해 "보정된 카메라 자세"를 얻었으면, 이제 실제 영상 프레임을 변환해야 한다.

원래 프레임의 카메라 자세와 보정된 카메라 자세의 차이만큼 프레임을 회전/변환하는 것이다. 이 과정을 프레임 워핑(frame warping)이라고 한다.


워핑의 원리

단순화하면 이런 흐름이다:

원래 프레임의 카메라 자세: Q_original

스무딩된 목표 자세: Q_smoothed

보정 회전: Q_correction = Q_smoothed × Q_original⁻¹

이 보정 회전을 이미지에 적용


여기서 Q_original⁻¹(쿼터니언의 역수)을 곱하는 것은 "원래 프레임의 회전을 반대로 되돌린다"는 의미다. 원래의 흔들린 자세를 상쇄하고, 목표하는 부드러운 자세로 프레임을 옮겨놓는 연산이다.

실제로는 단순 회전만이 아니라, 렌즈 왜곡 보정도 함께 이루어진다. 광각 렌즈의 어안 왜곡이 남아 있는 상태에서 이미지를 회전시키면 가장자리가 울렁거리는 현상이 발생하기 때문이다. Gyroflow에서 렌즈 프로파일을 설정하는 이유가 여기에 있다 — 왜곡 모델을 알아야 정확한 워핑이 가능하다.


FOV 손실

프레임을 회전/변환하면 가장자리에 빈 영역이 생긴다. 이 빈 영역을 숨기기 위해 영상을 크롭해야 하고, 결과적으로 화각(FOV)이 줄어든다.

이것이 EIS의 가장 근본적인 트레이드오프다:

보정을 강하게 할수록 → 더 많은 크롭 → FOV 손실 증가

FOV를 보존하려면 → 보정 강도를 줄여야 → 흔들림이 남음


Gyroflow에서는 이 크롭 비율을 사용자가 직접 조절할 수 있고, Dynamic Zoom 기능으로 프레임마다 최적의 크롭을 자동 계산하는 옵션도 제공한다. 상용 제품에서는 보통 고정 크롭(10~15% 정도)을 사용하거나, 해상도 오버샘플링(4K 촬영 → 1080p 안정화 출력)으로 FOV 손실을 체감하지 못하게 처리한다.


5단계: 출력

워핑된 프레임을 인코딩하면 최종 안정화 영상이 완성된다. Gyroflow는 후처리 도구이므로 이 과정이 별도의 렌더링 단계로 이루어지지만, 상용 제품의 실시간 EIS에서는 이 전체 파이프라인이 매 프레임 촬영과 동시에 실행된다.

실시간 처리에서는 추가적인 제약이 생긴다:

look-ahead 제한: 스무딩에 사용할 수 있는 미래 프레임이 제한적

연산 자원: GPU/DSP 자원 내에서 처리를 완료해야 함

발열/전력: 모바일 기기의 열 및 전력 예산 내에서 동작해야 함


이 때문에 같은 원리를 사용하더라도 후처리(Gyroflow) 대비 실시간(상용 EIS) 결과물의 품질 차이가 발생한다.


Gyroflow와 상용 EIS의 차이

Gyroflow를 통해 EIS의 원리를 이해할 수 있지만, 상용 제품의 EIS와는 몇 가지 중요한 차이가 있다.


항목 Gyroflow (후처리) 상용 EIS (실시간)


처리 시점 촬영 후 촬영과 동시에

스무딩 look-ahead 전체 영상 사용 가능 수 프레임~수십 프레임

렌즈 왜곡 보정 별도 렌즈 프로파일 ISP에 내장

자이로 동기화 수동/자동 추정 하드웨어 동기화

연산 자원 PC GPU (제한 없음) 모바일 DSP (제한적)

FOV 처리 동적 크롭 가능 보통 고정 크롭


상용 제품에서는 이 파이프라인 전체가 ISP(Image Signal Processor) 안에서 하드웨어 가속으로 돌아가며, OIS와 연동되어 하이브리드로 동작하는 경우가 많다.


정리

EIS는 겉으로는 "크롭해서 흔들림을 잡는다"로 요약되지만, 내부적으로는:

자이로 센서 데이터 수집과 시간 동기화

각속도 적분을 통한 카메라 자세 추정

의도된 움직임과 흔들림을 분리하는 스무딩

렌즈 왜곡까지 고려한 프레임 워핑

FOV 손실과 보정 강도의 트레이드오프 관리

라는 복잡한 파이프라인이 존재한다.

Gyroflow는 이 파이프라인을 오픈소스로 투명하게 구현하고 있어서, EIS의 동작 원리를 이해하는 데 좋은 참고 자료가 된다. 실제 코드를 읽어보고 싶은 분은 GitHub 저장소를 확인해보길 추천한다.

다음 글에서는 Rolling Shutter와 EIS의 관계 — 롤링 셔터 보정이 왜 EIS에서 추가적으로 필요한지를 다룰 예정이다.


이 글은 카메라 모듈 개발 실무 경험을 바탕으로 작성되었습니다. Gyroflow에 대한 설명은 공개된 소스코드와 문서를 참고한 것이며, 특정 제품의 내부 구현을 서술한 것이 아닙니다. 오류나 의견이 있으시면 댓글로 알려주세요.

작가의 이전글OIS vs EIS vs HIS