ai technology
비디오 인페인팅은 레퍼런스 프레임에서 시작한다: 방송 제작에서 Object Removal 모델을 고른 과정
Junyoung Park · 2026-08-30 · 11 min
비디오에서 사람이나 장비를 지우는 일을 처음 검토할 때는 temporal consistency가 가장 큰 문제라고 생각했다. Optical flow를 얼마나 안정적으로 구할지, 어느 프레임의 정보를 전달할지, 생성된 texture가 시간축에서 흔들리지 않게 할지가 먼저 떠올랐다.
실제로 파이프라인을 만들면서 가장 먼저 막힌 곳은 그보다 앞단이었다. 기준으로 삼을 이미지 한 장을 제대로 만들기가 어려웠다.
Video Inpainting에서 다른 프레임에 한 번이라도 드러난 배경은 known pixel로 전달할 수 있다. 영상 전체에서 한 번도 보이지 않은 영역은 결국 모델의 generative prior로 만들어야 한다. 이때 레퍼런스 프레임의 복원이 틀리면 뒤 단계가 그 오류를 꽤 성실하게 전파한다. 벽의 무늬가 잘못 만들어져도 모든 프레임에서 같은 모양으로 유지되면 temporal consistency는 좋아 보일 수 있다. 하지만 영상은 여전히 틀렸다.
그래서 이번 검토에서 이미지 인페인팅은 독립적인 미화 기능이 아니었다. 비디오 파이프라인에 넣을 background hypothesis를 만드는 첫 단계였다. 자연스러움만큼 중요한 것은 지우지 않은 픽셀의 보존이었다.
마스크가 있다고 해서 픽셀 경계가 보장되지는 않는다
처음에는 Nano Banana와 GPT Image 같은 범용 이미지 편집 모델을 사용했다. 이미지와 대략적인 마스크를 주고 대상을 지워 달라고 하면 첫인상은 꽤 좋다. 큰 물체도 알아보고, 비어 있는 자리에 그럴듯한 배경을 만든다. 한 장만 화면에 띄워 놓고 보면 전용 Inpainting 모델보다 나아 보이는 경우도 있었다.
문제는 그 결과를 원본 위에 합성하려고 할 때 드러났다. 마스크 바깥의 벽 색이 조금 달라지고, 물체의 위치가 몇 픽셀 움직이거나, 직선의 길이와 원근이 미세하게 바뀌었다. 사람 눈에는 비슷한 이미지지만 파이프라인 입장에서는 정렬되지 않은 새 이미지였다.
여기서 먼저 확인하고 싶었던 것은 단순했다. gpt-image-2가 mask edit를 지원한다면, 마스크 바깥 픽셀은 정말 전혀 건드리지 않는가.
내부 네트워크가 어떻게 구현됐는지는 공개되어 있지 않다. 운영에서 의지할 수 있는 것은 API가 보장하는 계약이다. OpenAI 공식 문서는 GPT Image의 masking을 prompt-based라고 설명하며, mask를 정확한 합성 경계가 아니라 편집을 유도하는 guidance로 사용한다고 적고 있다. 마스크 모양을 완전히 정밀하게 따르지 않을 수 있다는 주의도 붙어 있다.
이 문서만 놓고 보면 운영에서 내릴 수 있는 답은 ‘아니다’에 가깝다. gpt-image-2에는 mask 입력이 있지만, 그것이 곧 마스크 바깥의 bit-identical preservation을 뜻하지는 않는다. 결과가 우연히 같을 수는 있어도, 같아야 한다고 API가 보장하지는 않는다.
Nano Banana 계열의 설명은 더 semantic하다. Gemini API 문서는 해당 기능을 아예 Inpainting (semantic masking)이라고 부르고, 대화로 이미지의 특정 부분을 정의해 수정하는 예를 든다. 문장에는 나머지를 그대로 둔다고 적혀 있지만, 이것 역시 binary mask 밖의 픽셀을 서버가 원본에서 그대로 복사한다는 계약은 아니다.
mask라는 같은 단어를 써도 두 종류의 의미가 섞여 있었다.
- 모델에게 어디를 바꿀지 알려주는 semantic guidance
- 최종 합성에서 이 경계 밖은 원본 픽셀이어야 한다는 spatial contract
범용 편집 API가 제공하는 것은 대체로 앞쪽에 가깝다. 우리가 비디오 합성에서 필요로 한 것은 뒤쪽이었다.
눈으로는 비슷해도 합성에는 쓸 수 없는 결과
이 문제는 문서의 작은 주의 문구로만 존재하지 않았다. OpenAI Developer Community의 한 gpt-image-2 mask edit 테스트는 마스크 밖 영역과 요청하지 않은 물체가 바뀌고, 선택 영역이 필요 이상으로 다시 생성되는 사례를 보고했다. 벽, 바닥, 조명, 원근과 그림자를 바꾸지 말라고 프롬프트에 명시한 뒤에도 같은 증상을 봤다고 한다.
같은 글에 올라온 첨부본에는 입력 mask가 1920×1306, 결과가 1521×1034로 표시되어 있다. 이 숫자만으로 API가 항상 해상도를 바꾼다고 일반화할 수는 없다. 업로드 과정의 변환 가능성도 있기 때문이다. 다만 응답의 크기와 좌표계를 원본과 같다고 가정해서는 안 된다는 점은 충분히 보여준다. 출력 크기를 명시하고 다시 확인하는 단계가 필요하며, 크기가 같더라도 건물 모서리나 가구 위치가 같은 좌표에 있다는 보장은 별개다.
같은 사용자 보고의 mask 첨부본(위)과 result 첨부본(아래). 라이트박스의 해상도 표기가 보이도록 해당 부분만 남겼다.
같은 글의 mask-api.png와 composition-image-2.png 원본 첨부도 직접 받아 비교했다. 검정색으로 표시한 선택 영역이 양쪽에 모두 포함된 pair다. 결과 이미지(1521×1034)를 masked input(1920×1306)과 같은 크기로 Lanczos resize한 뒤, 별도의 registration 없이 RGB absolute difference를 계산했다. 작은 차이까지 보이도록 delta만 4배 증폭했다.
왼쪽부터 검정색으로 표시한 masked input, 1920×1306으로 resize한 결과, 정렬 보정 없이 계산한 |before − after| × 4다. JPEG 재인코딩과 resize에서 생긴 오차도 포함되므로 모델만의 pixel error를 재는 benchmark로 해석하면 안 된다. 원문
이 조건을 감안해도 차분이 선택 영역에만 모이지 않고 벽돌, 계단, 조명과 가구의 윤곽 전반에 나타나는 것은 확인할 수 있다. 적어도 이 응답을 원본 좌표계에 그대로 붙일 수 있는 국소 patch로 보기는 어렵다. 다만 이 그림은 관찰된 결과를 시각화한 것이지, 비공개된 API 내부 동작 방식을 증명하는 자료는 아니다.
Nano Banana에서도 비슷한 정렬 문제가 보고된다. Adobe Community의 한 사용자는 Photoshop Generative Fill에서 Gemini 2.5를 사용할 때 생성 layer가 다른 scale로 나오거나 몇 픽셀 이동해 정밀 작업에 쓸 수 없었다고 적었다.
Photoshop 통합 환경에서의 사용자 보고이므로 원인이 모델, API, 플러그인 중 어디에 있는지는 이 글만으로 구분할 수 없다. 여기서는 현업에서 관찰되는 실패 형태로만 인용했다. 원문
몇 픽셀은 생성 이미지 한 장에서는 사소하다. 같은 결과를 영상의 여러 프레임과 합성하면 이야기가 달라진다. 경계가 떨리고, 원본과 생성 영역 사이에 이중선이 생기며, propagation이 잘못된 구조를 다음 프레임으로 넘긴다. “그럴듯한 새 이미지”와 “원본에 바로 붙일 수 있는 patch”는 다른 결과물이다.
원본을 다시 덮으면 끝날까
가장 간단한 방어는 생성 결과의 마스크 바깥을 원본으로 다시 덮는 것이다.
이렇게 합성하면 영역의 픽셀은 수학적으로 원본과 같다. API가 외부 영역을 다시 그려도 최종 결과에서는 버릴 수 있다. 실제 파이프라인에서도 기본 안전장치로 둘 만하다.
하지만 Object Removal에서는 마스크가 곧 실제 수정 범위가 아니다. 사람의 silhouette만 가리면 바깥에 그림자가 남고, 유리나 금속에는 반사가 남는다. 반대로 shadow까지 넓게 잡으면 그 앞을 지나가는 테이블, 자막, 다른 사람처럼 유지해야 할 foreground가 마스크 안에 들어올 수 있다. 생성 결과가 몇 픽셀 밀려 있다면 hard composite 경계에는 seam도 생긴다.
외부 픽셀을 지키는 일과 지워야 할 effect를 찾는 일은 같은 mask에서 충돌한다.
결국 필요한 것은 단순한 hole filling보다 복잡했다. 모델은 어떤 물체를 지우는지 알아야 하고, 그 물체가 만든 shadow와 reflection을 찾아야 하며, 앞뒤 관계가 겹친 부분에서는 남겨야 할 물체를 보존해야 한다. 입력은 2D 이미지와 mask지만 판단에는 depth-awareness가 들어간다.
속도가 느린 것보다 더 곤란한 것은 완료 시간을 예측할 수 없는 것
범용 생성 API를 대량 파이프라인에 붙일 때는 latency도 무시하기 어렵다. OpenAI 공식 문서는 복잡한 prompt가 처리되는 데 최대 2분이 걸릴 수 있다고 적고 있다. 같은 항목에서 layout-sensitive composition의 정밀한 배치가 어려울 수 있다는 제한도 함께 안내한다.
Gemini 쪽에서는 서비스 상태에 따른 편차를 호소하는 보고도 있었다. 한 Google AI Developers Forum 글은 이미지 생성 시간이 30초에서 3분으로 늘고 429 실패가 반복됐던 시기의 운영 경험을 적었다. 이것은 특정 시점의 사용자 보고이지 정상 latency를 뜻하지 않는다. 오히려 production에서는 평균값만으로 capacity를 잡기 어렵다는 사례에 가깝다.
특정 기간의 capacity 이슈에 대한 사용자 보고다. 수치를 보편적인 성능으로 인용하지 않고 운영 변동성의 사례로만 사용했다.
응답이 느리더라도 결과가 정확히 정렬되어 있으면 batch로 기다릴 수 있다. 문제는 1분 넘게 기다린 결과를 pixel diff로 검사하고, 정렬 실패 때문에 다시 요청해야 할 때다. 이 경우 API 호출 시간보다 실패를 판별하고 재시도하는 시간이 더 커진다.
Photoshop을 내부 API처럼 쓰는 방법도 생각했다
전용 모델이 전혀 없었던 것은 아니다. 당시 방송사에서 사용하던 Adobe enterprise 계정으로 Photoshop의 Firefly 기반 Generative Fill을 쓸 수 있었고, 물체 제거 품질도 실무에 가까웠다. 다만 그 계약 안에서 desktop 기능을 쓰는 것과 별도 API를 개발 환경에 연결하는 것은 다른 문제였다. API 사용에는 추가 enterprise 협의가 필요했다.
그래서 한동안 특정 workstation에서 Photoshop을 띄워 두고, 내부망의 다른 PC가 작업을 요청하는 구조를 검토했다. 프로그램이 이미지를 열고 선택 영역에 Generative Fill을 실행한 뒤 결과를 저장하면, 바깥에서는 일반 API처럼 보이게 만들 수 있다.
가능은 했지만 service로 만들기에는 불안한 지점이 많았다. Photoshop의 UI와 상태에 종속된 automation을 완전히 headless하게 유지하기 어렵고, dialog나 update 하나가 worker를 멈출 수 있다. 동일한 worker를 여러 대 복제해도 application state와 license, 파일 입출력을 포함한 load balancing을 별도로 풀어야 한다. 무엇보다 그 workstation이 Single Point of Failure가 된다. 좋은 모델을 쓸 수 있다는 것과 운영 가능한 backend를 가졌다는 것은 역시 다른 문제였다.
코드와 weight가 있는 제거 전용 모델만 다시 골랐다
이후에는 당시 코드와 weight를 실제로 받을 수 있는 모델만 후보에 넣었다.
| 모델 | 공개 시점 | 접근 방식 | 내부 테스트에서 본 특성 |
|---|---|---|---|
| SmartEraser | CVPR 2025 | Masked-Region Guidance | mask 안의 대상을 참고하지만 일부 복잡한 장면에서 제거가 불완전했다 |
| OmniPaint | ICCV 2025 | FLUX 기반 insertion-removal 학습 | 생성력은 좋지만 sampling 비용과 간헐적인 재생성이 부담이었다 |
| ObjectClear | CVPR 2026 | object-effect attention과 fusion | effect-aware 설계는 분명했지만 테스트한 장면 모두에서 안정적이지는 않았다 |
| OSOR | ECCV 2026 | one-step restoration과 alpha head | 가장 빨랐고 shadow 같은 부수 effect까지 비교적 잘 지웠다 |
이 표는 논문 benchmark 순위가 아니다. 같은 방송 제작 샘플에 여러 모델을 걸어 보고 어느 결과를 다음 video 단계에 넘길 수 있는지 판단한 내부 사용 기록이다. 모델마다 권장 해상도와 backbone, sampling step이 다르므로 정량 비교라고 부르기도 어렵다.
그 조건에서는 OSOR이 가장 나았다. SDXL Inpainting과 FLUX Fill 기반 weight를 모두 제공했고, one-step이라 응답도 빨랐다. 논문과 repository는 1024×1024 입력을 A100 한 장에서 1초 이내에 처리한다고 보고한다. 내게 더 중요했던 것은 숫자보다 mask 밖의 영역을 비교적 안정적으로 유지하면서, mask에 정확히 포함하지 않은 shadow까지 지우는 경우가 많았다는 점이다.
다른 후보는 어떤 장면에서 대상을 덜 지우거나, 비워진 자리에 비슷한 물체를 다시 만드는 경우가 있었다. OSOR도 늘 맞지는 않았지만 실패를 검수하고 다시 돌릴 수 있을 정도로 빨랐고, 방송 장면에서 반복적으로 등장하는 사람과 장비 제거에는 가장 현실적인 기본값이었다.
OSOR이 잘 못 지운 장면에 공통점이 있었다
OSOR을 기본 모델로 정하고 나니 실패 장면이 조금 더 구체적으로 보였다.
첫째는 아웃포커싱된 배경이었다. 초점 밖의 스태프나 카메라는 이미 경계와 texture가 무너져 있다. 사람이 보기에는 “뒤에 있는 카메라”지만 픽셀 수준에서는 색이 번진 덩어리에 가깝다. 모델이 blur를 배경의 특성으로 받아들이면 물체를 다 지우지 못하거나, 그 자리에 정체를 알 수 없는 blur를 다시 만들었다.
둘째는 세트에 걸린 복잡한 그림과 장식이었다. 반복되는 벽지나 바닥은 주변 patch에서 규칙을 찾을 수 있다. 아방가르드한 그림 한가운데를 가린 물체 뒤에는 복사할 규칙도, 하나의 정답도 없다. 생성 능력이 좋은 모델도 작품의 “없었던 부분”을 복원하는 데에는 근거가 없다. 자연스러운 다른 그림을 만드는 것과 원래 액자를 복원하는 것은 다른 일이다.
셋째는 mask가 대상을 말해주지 못하는 경우였다. 뒤쪽 사람을 지우려고 넓게 칠하면 앞쪽 소품과 자막도 mask 안에 들어간다. 전통적인 Inpainting 입력은 어떤 픽셀을 다시 그릴지는 알려주지만, 그 안에서 무엇을 제거하고 무엇을 유지할지까지 명시하지는 않는다. 이 문제는 이미지에서 벌어지지만 사실상 depth와 object identity를 요구한다.
학습 데이터의 한계도 같은 곳에 닿아 있다. 물체를 background 위에 합성하면 정렬된 before/after pair를 대량으로 만들 수 있다. 대신 실제 촬영에서 생기는 defocus, contact shadow, reflection, partial occlusion과 foreground overlap을 충분히 재현하기 어렵다. 실제 물체를 놓기 전과 치운 뒤를 촬영하면 물리 효과는 살아 있지만 규모를 만들기 어렵고, 조명이나 움직이는 배경을 완전히 고정하기도 어렵다.
OSOR의 실패를 몇 장의 정성 비교로 모델 탓이라고 결론 내리기는 어렵다. 학습 data prior, 입력 mask, scene의 depth ambiguity가 겹친 결과일 수 있다. 더구나 이 이미지가 video propagation에 들어갔을 때 어떤 실패가 커지고 어떤 오차가 주변 프레임의 관측값으로 보정되는지도 봐야 한다. 최종 평가는 이미지 한 장이 아니라 E2E Video Inpainting 결과에서 해야 한다.
1편에서 내린 선택
현재 파이프라인에서는 범용 image editing API를 합성 가능한 Inpainting API처럼 간주하지 않는다. gpt-image-2와 Nano Banana가 좋지 않은 모델이라는 뜻은 아니다. 원하는 변화를 자연어로 지정하고 장면 전체의 의미를 다시 구성하는 데에는 오히려 강하다. 다만 mask 바깥의 pixel identity와 원본 좌표계 보존이 필요한 작업에는 별도의 검증과 후처리가 필요하다.
기본 Object Removal 경로는 OSOR로 두었다. 속도, 외부 영역 보존과 effect 제거의 균형이 테스트한 모델 중 가장 좋았다. 결과는 원본과 동일한 크기로 맞추고, unmasked region의 pixel difference와 edge alignment를 검사한 뒤 video 단계로 넘긴다. hard composite는 안전장치로 쓰되 object mask를 그대로 믿지는 않는다.
그래도 복잡한 그림, defocus와 겹침이 있는 장면에서는 mask-only Inpainting의 ceiling이 보였다. 그 다음에 검토한 것이 Qwen Image Edit를 기반으로 한 MaskFlow였다. 전용 Inpainting 모델이 못 풀던 몇몇 장면에서 오히려 편집 모델이 더 좋은 배경을 만들었다.
그러면 질문이 바뀐다.
지우는 영역을 엄격히 제한하는 Inpainting과, 지울 대상을 언어로 명확히 지정하는 Editing 중 어느 쪽을 믿어야 할까.
다음 글에서는 MaskFlow를 사용하면서 확인한 차이와, pixel locality와 semantic control이 왜 서로 쉽게 바뀌지 않는지 다뤄보려고 한다.