AI-удаление объектов с видео (Video Inpainting)
Удалить объект с одного кадра — задача решённая. Удалить его с видео так, чтобы фон не мигал, не рябил и выглядел натурально — существенно сложнее. Классический подход «inpainting каждого кадра» даёт мерцание на границах патча, потому что каждый кадр обрабатывается независимо. Современные методы используют temporal consistency: берут информацию из соседних кадров.
ProPainter — практический инструмент
ProPainter (2023) — state-of-the-art для video object removal. Использует рекуррентную архитектуру с optical flow для временной согласованности.
import subprocess
from pathlib import Path
def remove_object_from_video(
video_path: str,
mask_dir: str, # директория с бинарными масками (один файл на кадр)
output_path: str,
neighbor_length: int = 10, # кадры-соседи для temporal context
ref_stride: int = 10, # шаг для reference frames
subvideo_length: int = 80 # длина чанка (memory trade-off)
) -> None:
"""
ProPainter принимает видео + маски → видео с удалёнными объектами.
neighbor_length: больше → лучше quality, больше VRAM.
subvideo_length: при OOM уменьшаем до 40-60.
"""
cmd = [
'python', 'ProPainter/inference_propainter.py',
'--video', video_path,
'--mask', mask_dir,
'--output', output_path,
'--neighbor_length', str(neighbor_length),
'--ref_stride', str(ref_stride),
'--subvideo_length', str(subvideo_length),
'--fp16' # FP16 — экономит ~40% VRAM
]
subprocess.run(cmd, check=True)
Получение масок: SAM2 + трекинг
Главная сложность — получить маски для каждого кадра. Рисовать вручную 300 кадров нереально. SAM2 умеет видео-трекинг: разметка на первом кадре → автоматическое отслеживание объекта.
import torch
import numpy as np
from PIL import Image
from sam2.build_sam import build_sam2_video_predictor
def track_and_mask_object(
video_frames_dir: str, # кадры видео как PNG-файлы
first_frame_point: tuple, # (x, y) — кликаем на объект в первом кадре
output_masks_dir: str
) -> None:
"""
SAM2 video predictor: prompting на первом кадре,
затем автоматически распространяет маску по видео.
"""
predictor = build_sam2_video_predictor(
'sam2_hiera_large.yaml',
'weights/sam2_hiera_large.pt',
device='cuda'
)
frame_paths = sorted(Path(video_frames_dir).glob('*.png'))
inference_state = predictor.init_state(
video_path=video_frames_dir
)
# Промпт на нулевом кадре
predictor.add_new_points_or_box(
inference_state=inference_state,
frame_idx=0,
obj_id=1,
points=np.array([first_frame_point], dtype=np.float32),
labels=np.array([1], np.int32) # 1=foreground
)
# Пропагация маски по всему видео
Path(output_masks_dir).mkdir(exist_ok=True)
for frame_idx, obj_ids, masks in predictor.propagate_in_video(
inference_state
):
mask = masks[0].cpu().numpy().squeeze() # (H, W) bool
mask_img = Image.fromarray((mask * 255).astype(np.uint8))
mask_img.save(
Path(output_masks_dir) / f'{frame_idx:05d}.png'
)
Стабилизация результата и postprocessing
ProPainter иногда даёт артефакты на быстро движущихся объектах или при резких сменах фона. Постобработка через temporal smoothing убирает мерцание:
import cv2
import numpy as np
def temporal_smooth_region(
frames: list[np.ndarray], # список кадров (H, W, 3)
masks: list[np.ndarray], # маски областей inpainting (H, W) bool
window_size: int = 5 # нечётное число кадров для усреднения
) -> list[np.ndarray]:
"""
Временное сглаживание в области inpainting.
Применяется поверх ProPainter-результата для убирания мерцания.
"""
n = len(frames)
smoothed = [f.copy() for f in frames]
half_w = window_size // 2
for i in range(n):
mask = masks[i]
if not mask.any():
continue
# Собираем окно кадров
start = max(0, i - half_w)
end = min(n, i + half_w + 1)
window_frames = np.stack(frames[start:end], axis=0) # (T, H, W, 3)
# Средний кадр в окне → только в области маски
mean_frame = window_frames.mean(axis=0).astype(np.uint8)
smoothed[i][mask] = mean_frame[mask]
return smoothed
Типичные проблемы
-
OOM при длинных видео — ProPainter держит neighbour frames в VRAM. При 4K видео +
neighbor_length=10требует 20+ GB. Решение: снижаем доneighbor_length=5,subvideo_length=40 - Текстурированный фон — сложный паттерн (кирпичная стена, трава) восстанавливается хуже однородного. Решение: Content-Aware Fill в дополнение
- Быстрое движение объекта — маски от SAM2 теряют объект на 5–10 кадрах. Решение: ручная правка масок в проблемных кадрах в CVAT
Сроки
| Задача | Срок |
|---|---|
| API-сервис video object removal | 2–4 недели |
| Полный pipeline: маски → inpainting → постобработка | 4–7 недель |
| Кастомная модель под специфический домен | 10–16 недель |







