TT Lab
요금제

한국어

시작하기
블로그

블로그

매 프레임 다 돌리지 않기: 검출+추적, 키프레임, 해상도, ROI — 그리고 공 찾기의 512×288

상태: 초안 (2026-10-16), 일부 실측. 공 모델(BlurBall)의 입력 크기별 지연은 집 랩의 8GB급 노트북용 GPU 한 장에서 1회용 파드로 쟀습니다(예열 20회 뒤 50회 × 5묶음의 중앙값). 건너뛰기·ROI 는 노트북 CPU 의 합성 궤적 흉내입니다(code/05_skip_frames.py, 1초 안팎). 실제 탁구 영상에서 건너뛰기를 한 정확도는 미실측입니다. 시리즈 「비전 모델 읽기 3」 5편. 광류의 원리는 비전 모델 읽기 2 의 5편, 공 추적 모델의 학습은 같은 시리즈 9편에 있습니다.

목차

1. 직관: 이웃 프레임은 거의 같다

30fps 영상에서 이웃한 두 프레임은 33ms 차이입니다. 그사이 배경은 그대로이고, 사람은 몇 화소 움직입니다. 그런데 매 프레임 무거운 모델을 처음부터 돌리면 거의 같은 계산을 30번 되풀이합니다. 이 글의 방법들은 모두 이 중복을 덜어 냅니다.

매 프레임 다 돌리지 않기 ① 3프레임마다 검출, 사이는 등속 예측 탁구대 검출 실제 위치 예측 — 바운드 뒤에 크게 빗나감 ② 입력을 줄이면 화소는 제곱으로, 공은 그대로 작아진다 1280×720 공 13px 512×288 공 5px 256×144 공 2.6px ③ ROI: 예측한 자리 둘레만 본다 512×288 중 96×96 창 = 화소 6% 빗나가면 전체 화면으로 돌아간다
그림: 3프레임마다 검출하고 사이를 등속 예측으로 메우면 바운드 뒤에 예측이 크게 빗나가는 그림, 입력 크기에 따른 공 크기, 예측한 자리 둘레만 보는 ROI
무엇을 덜어 내나 방법 대표
시간(프레임 수) 검출은 가끔, 사이는 추적 SORT, MediaPipe, BlazePose
시간(특징) 키프레임에서만 특징을 뽑고 옮겨 쓰기 Deep Feature Flow
공간(해상도) 장면마다 입력 크기 고르기 AdaScale
공간(영역) 예측한 자리 둘레만 보기 ROI 자르기

2. 검출은 가끔, 사이는 추적

Bewley 외의 SORT(2016)는 매 프레임 검출 결과를 받아, 물체마다 등속 칼만 필터로 다음 위치를 예측하고, 예측 상자와 새 검출 상자를 IoU 로 짝짓습니다(헝가리안 알고리즘). 추적 부분은 2016년 무렵 CPU 코어 하나에서 260Hz 로 돌았습니다(4.3절, 검출 시간은 빠진 것으로 읽힙니다). 같은 추적기에 검출기만 바꿔도 MOT 정확도(MOTA)가 15.1 에서 34.0 으로 올랐습니다(표 1). 추적의 질은 결국 검출이 정하고, 추적기 자체는 거의 공짜라는 뜻입니다.

이 「거의 공짜」 를 이용하면 검출을 가끔만 할 수 있습니다. MediaPipe 의 자세 추적은 검출기를 첫 프레임과 추적이 사람을 놓쳤을 때만 돌리고, 나머지 프레임은 이전 프레임의 관절 위치로 사람 둘레를 잘라 관절 모델만 돌립니다(공식 문서). BlazePose(2020)는 이렇게 해서 2017년 휴대폰의 CPU 코어 하나에서 Lite 모델로 약 30 FPS 를 냈습니다(표 1).

칼만 필터의 예측 단계는 한 줄입니다.

상태 x = [위치, 속도],   다음 예측 x' = F·x,   F = [[1, Δt], [0, 1]]   (등속 가정)
검출이 오면 예측과 검출을 불확실성 비율로 섞어 고친다(갱신 단계)

직접 해 보기: 탁구공에서 건너뛰면

등속 가정은 공이 방향을 바꾸는 순간 깨집니다. 탁구공은 0.5초에 한 번꼴로 탁구대에 튀거나 라켓에 맞습니다. 512×288 화면에 중력·바운드·타구가 있는 합성 랠리(60fps, 1,161프레임, 바운드 29·타구 40)를 만들고, 검출기를 k 프레임마다 한 번 돌리고(위치 잡음 σ=1px) 사이를 마지막 두 검출의 등속 예측으로 메웠습니다.

k(검출 간격) 검출 비용 위치 오차 중앙 · p95 바운드·타구 앞뒤 3프레임의 중앙 · p95 10px 넘게 빗나간 프레임
1 100% 1.2 · 2.5px 1.1 · 2.3px 0.0%
2 50% 1.5 · 5.4px 1.7 · 20.1px 3.8%
3 33% 1.9 · 29.3px 2.2 · 46.8px 9.6%
4 25% 2.4 · 48.7px 3.3 · 75.7px 15.7%
6 17% 5.8 · 92.5px 7.2 · 83.6px 34.0%

중앙값만 보면 3프레임마다 검출해도 2px 남짓으로 괜찮아 보입니다. 하지만 꼬리(p95)는 바운드·타구 앞뒤에서 46.8px 로, 공 지름(512 폭에서 약 5px)의 아홉 배가 넘습니다. 오차가 하필 우리가 알고 싶은 사건(바운드) 둘레에 몰립니다. 사람 자세처럼 부드럽게 움직이는 대상에서 잘 통하는 「검출은 가끔」 을, 점수 판정이 바운드에 달린 탁구공에 그대로 쓰기 어려운 까닭입니다.

3. 키프레임: 특징을 옮겨 쓰기

Zhu 외의 Deep Feature Flow(2017)는 건너뛸 단위를 「검출 결과」 가 아니라 「깊은 특징」 으로 잡습니다. 무거운 특징 망(ResNet-101)은 키프레임에서만 돌리고, 사이 프레임은 가벼운 광류 망이 구한 흐름을 따라 키프레임의 특징을 옮긴(warp) 뒤 가벼운 머리만 돌립니다. 끝까지 함께 학습합니다.

과제(논문 표 4) 키프레임 간격 매 프레임 Deep Feature Flow
ImageNet VID 영상 검출 10 mAP 73.9, 4.05 fps mAP 73.1, 20.25 fps(5.0배)
Cityscapes 분할 5 mIoU 71.1, 1.52 fps mIoU 69.2, 5.60 fps(3.7배)

(2013년 데이터센터 GPU 한 장.) 정확도를 1–2점 내주고 3.7–5배 빨라졌습니다. 더 가벼운 광류 망을 쓰면 약 10배(41.26 fps)까지 갔지만 mAP 가 69.5 로 떨어졌습니다(5.2절). 광류는 「한 프레임 동안 조금씩 움직인다」 를 가정하므로, 한 프레임에 지름의 몇 배를 날아가는 공에는 맞지 않습니다(아래 4절의 표).

4. 해상도: 입력을 줄이면

계산은 화소 수, 곧 가로×세로에 비례합니다. 폭을 절반으로 줄이면 계산은 4분의 1 입니다. 대신 작은 물체가 더 작아집니다. 탁구대 길이 2.74m 가 화면 폭의 70% 를 차지한다고 두고 공(40mm)의 크기와 한 프레임 동안의 이동을 계산했습니다(공 속도 10m/s).

화면 폭 공 지름 한 프레임 이동(60fps / 30fps) 화소 수(512×288 대비)
1920 19.6px 81.8 / 163.5px 14.1배
1280 13.1px 54.5 / 109.0px 6.3배
768 7.8px 32.7 / 65.4px 2.3배
512 5.2px 21.8 / 43.6px 1
256 2.6px 10.9 / 21.8px 0.25배

어느 해상도에서든 공은 한 프레임에 자기 지름의 4.2배(60fps)–8.3배(30fps) 를 움직입니다. 그래서 공 모델은 프레임 하나가 아니라 여러 장을 함께 보고, 번진 자국까지 단서로 씁니다(같은 시리즈 2의 9편).

우리 실측: 공 모델을 입력 크기 넷으로

TT Score 의 공 모델(BlurBall, 3프레임 창, 파라미터 149만 개)을 실험용 GPU 에서 입력 크기만 바꿔 쟀습니다. 모델은 완전 합성곱이라 가중치를 그대로 두고 입력 크기만 바꿀 수 있습니다(학습은 512×288 에서 했으므로 다른 크기의 정확도는 미실측입니다).

입력 FP32 FP16 512×288 대비 화소 512×288 대비 시간(FP32)
256×144 4.07ms 4.69ms 0.25배 0.27배
512×288 15.09ms 9.77ms 1 1
768×432 41.90ms 24.10ms 2.25배 2.78배
1024×576 82.24ms 49.30ms 4배 5.45배

(배치 1, 창 하나, FP16 은 autocast. 예열 20회 뒤 250회의 중앙값이고 다섯 묶음의 중앙값끼리 0.1ms 안에서 같았습니다.)

두 가지가 보입니다.

30fps 예산(33ms)에 추론만 넣는다면 768×432 의 FP16(24ms)까지 들어갑니다. 하지만 1편에서 본 것처럼 예산에는 전처리·전송·후처리·다른 세션 몫이 함께 들어가야 하므로, 512×288(FP16 9.8ms)이 여유를 남기는 크기입니다. 이 값은 공 모델이 학습된 크기이기도 합니다.

장면마다 크기를 고르기: AdaScale

Chin 외의 AdaScale(2019)은 검출기 특징 위에 작은 회귀기를 달아, 다음 프레임에 쓸 입력 크기(짧은 변 600·480·360·240)를 예측합니다. 큰 물체만 있는 장면은 작게 넣어도 되고, 오히려 오검출이 줄어 정확도가 오르기도 합니다. ImageNet VID 에서 1.6배 빨라지면서 mAP 가 74.2 → 75.5 로 올랐습니다(R-FCN, 2017년 소비자용 상위 GPU, 75 → 47ms). 회귀기 자체는 약 2ms 입니다. 탁구에서는 공이 늘 작으므로 이 생각을 그대로 쓰기는 어렵지만, 「이번 장면은 공이 안 보이는 쉬는 시간이니 작게·드물게」 같은 형태로는 쓸 수 있습니다(미실측).

5. ROI: 예측한 자리 둘레만

추적이 다음 위치를 예측해 주면 그 둘레의 작은 창만 모델에 넣을 수 있습니다. 화면 전체 대신 96×96 창이면 화소는 6% 입니다. 대신 예측이 빗나가 공이 창 밖에 있으면 놓치고, 그때는 전체 화면을 다시 봐야 합니다. 2절의 합성 랠리에서 매 프레임 검출(σ=1px)하며 직전 두 추정으로 창 위치를 예측했습니다.

창 화소 몫 공이 창 밖(검출 실패 0%) 공이 창 밖(검출 실패 10%) 그중 바운드·타구 앞뒤(실패 10%)
32×32 0.7% 3.71% 4.66% 11.95%
64×64 2.8% 2.50% 2.85% 7.36%
96×96 6.2% 0.35% 0.78% 1.84%
128×128 11.1% 0.35% 0.60% 1.61%

창 밖으로 나가는 순간은 역시 방향이 바뀌는 순간에 몰립니다. 이 흉내에는 가림·서브 시작(공이 손에서 갑자기 나타남)·카메라 흔들림이 없으므로 실제로는 더 자주 빗나갈 것입니다(미실측). 또 BlurBall 처럼 여러 프레임을 함께 보는 모델은 창을 자르면 앞뒤 프레임의 같은 자리도 잘라야 하므로, 창이 공을 따라 움직이면 「같은 자리의 변화」 라는 단서가 흐려집니다.

6. 한계

7. 우리 프로젝트와의 연결

다음 글은 여러 사람이 한 GPU 를 함께 쓸 때, 묶어 돌리기가 지연과 처리량을 어떻게 바꾸는지입니다.

티티 한마디. 공은 한 프레임에 제 몸의 네 배를 날아가고, 꼭 튀는 순간에 방향을 바꿔요. 그래서 저는 눈을 한 번도 감지 않아요 — 대신 탁구대는 가끔만 봐요!

참고 문헌

로그인하면 좋아요를 누를 수 있습니다

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다