AI-замена фона на видео — разработка и интеграция под ключ

Разработка AI для замены фона в видео

Направления AI-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    714
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1006

Разработка AI для замены фона в видео

Замена фона в видео — задача сложнее, чем в статичных изображениях: нужна временная согласованность между кадрами (temporal coherence), иначе фон будет мерцать. Мы реализуем системы для видеоконференций (Zoom, Teams), спортивных трансляций и новостных студий без хромакея. Realtime-требования для конференций — 15–30 FPS при задержке <50 мс на CPU/GPU с низким энергопотреблением.

Почему temporal coherence критична для видео?

Каждый кадр обрабатывается независимо, но без учёта предыдущих кадров маска фона может резко меняться, создавая артефакты. Temporal coherence устраняет мерцание, используя рекуррентные нейронные сети. RVM (Robust Video Matting) — одна из лучших моделей, явно хранящая скрытое состояние между кадрами. Подробнее о RVM можно прочитать в официальной документации.

Как мы добиваемся temporal coherence?

Ключевое решение — RVM с рекуррентным состоянием. Модель хранит скрытые векторы между кадрами, что устраняет мерцание. Наш опыт показывает, что этот подход даёт плавную маску даже на сложных сценах с движением камеры. Например, в одном из проектов для стриминговой платформы мы внедрили RVM MobileNetV3 — замена фона работала на 30 FPS на ноутбуке без GPU.

import torch import torchvision.transforms as T from PIL import Image import numpy as np import cv2 class VideoBackgroundReplacer: def __init__(self, model_path: str, device: str = 'cuda'): self.device = device # RVM с recurrent state — ключ к temporal coherence self.model = torch.jit.load(model_path).to(device) self.model.eval() self.transform = T.ToTensor() # Recurrent state сохраняется между кадрами self.rec = [None] * 4 def reset_state(self): """Сбросить состояние при смене сцены/источника""" self.rec = [None] * 4 @torch.no_grad() def process_frame(self, frame_bgr: np.ndarray, background_bgr: np.ndarray) -> np.ndarray: """ Обработка одного кадра видео. Состояние (rec) сохраняется между вызовами для плавности. """ frame_rgb = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB) bg_rgb = cv2.cvtColor(background_bgr, cv2.COLOR_BGR2RGB) # Изменяем размер до кратного 64 для модели h, w = frame_rgb.shape[:2] src = self.transform(Image.fromarray(frame_rgb)).unsqueeze(0).to(self.device) bgr_tensor = self.transform( Image.fromarray(bg_rgb).resize((w, h)) ).unsqueeze(0).to(self.device) # Основной вывод с передачей recurrent state fgr, pha, *self.rec = self.model(src, *self.rec, downsample_ratio=0.25) # Compositing composite = fgr * pha + bgr_tensor * (1 - pha) result = (composite.squeeze().permute(1, 2, 0).cpu().numpy() * 255).astype(np.uint8) return cv2.cvtColor(result, cv2.COLOR_RGB2BGR) def replace_in_video(self, input_path: str, background_path: str, output_path: str) -> dict: cap = cv2.VideoCapture(input_path) fps = cap.get(cv2.CAP_PROP_FPS) w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # Загружаем фон (может быть изображение или видео) if background_path.endswith(('.jpg', '.png')): bg = cv2.imread(background_path) bg = cv2.resize(bg, (w, h)) bg_is_video = False else: bg_cap = cv2.VideoCapture(background_path) bg_is_video = True out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h)) self.reset_state() frame_count = 0 while cap.isOpened(): ret, frame = cap.read() if not ret: break if bg_is_video: ret_bg, bg = bg_cap.read() if not ret_bg: bg_cap.set(cv2.CAP_PROP_POS_FRAMES, 0) _, bg = bg_cap.read() bg = cv2.resize(bg, (w, h)) result = self.process_frame(frame, bg) out.write(result) frame_count += 1 cap.release() out.release() return {'frames': frame_count, 'fps': fps, 'output': output_path} 

Какие модели обеспечивают realtime на CPU?

Для CPU без GPU мы используем ONNX Runtime с оптимизациями. В проекте для видеоконференций мы добились 30 FPS на ноутбуке Intel i5, применив квантизацию INT8 и уменьшение разрешения до 256x144. ONNX Runtime позволяет запускать модели на различных устройствах с минимальными изменениями.

import onnxruntime as ort class RealtimeBackgroundProcessor: """ ONNX Runtime для CPU-оптимизации на машинах без GPU. Target: 30 FPS на ноутбуке, задержка <33 мс/кадр. """ def __init__(self, onnx_model_path: str): # Настройки для максимальной производительности на CPU opts = ort.SessionOptions() opts.intra_op_num_threads = 4 opts.execution_mode = ort.ExecutionMode.ORT_SEQUENTIAL opts.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL self.session = ort.InferenceSession( onnx_model_path, sess_options=opts, providers=['TensorrtExecutionProvider', 'CUDAExecutionProvider', 'CPUExecutionProvider'] ) # Recurrent state как numpy массивы self.rec_states = [ np.zeros((1, 1, 1, 1), dtype=np.float32) for _ in range(4) ] def process_frame_fast(self, frame_rgb: np.ndarray, target_size: tuple = (256, 144)) -> np.ndarray: """ Уменьшаем до 256x144 для CPU realtime. Upscale маски обратно через билинейную интерполяцию. """ orig_h, orig_w = frame_rgb.shape[:2] small = cv2.resize(frame_rgb, target_size) small_f = small.astype(np.float32) / 255.0 src = small_f.transpose(2, 0, 1)[np.newaxis] # [1, 3, H, W] outputs = self.session.run( None, {'src': src, 'r1i': self.rec_states[0], 'r2i': self.rec_states[1], 'r3i': self.rec_states[2], 'r4i': self.rec_states[3], 'downsample_ratio': np.array([0.25])} ) fgr, pha = outputs[0], outputs[1] self.rec_states = list(outputs[2:6]) # Апскейл маски обратно до исходного размера alpha_small = pha[0, 0] alpha_full = cv2.resize(alpha_small, (orig_w, orig_h), interpolation=cv2.INTER_LINEAR) return alpha_full 

Виртуальный размытый фон (Bokeh effect)

def apply_background_blur(frame: np.ndarray, alpha: np.ndarray, blur_radius: int = 25) -> np.ndarray: """ Альтернатива замене — размытие фона (как в Google Meet/Teams). Не требует загрузки изображения, работает быстрее. """ # Размываем весь кадр blurred = cv2.GaussianBlur(frame, (blur_radius * 2 + 1, blur_radius * 2 + 1), 0) # Compositing с мягкими краями alpha_3ch = np.stack([alpha, alpha, alpha], axis=2) result = (frame * alpha_3ch + blurred * (1 - alpha_3ch)).astype(np.uint8) return result 

Сравнение моделей: какая лучше?

RVM лучше MediaPipe в 2–3 раза по качеству маски, но требует GPU для realtime. Background Matting V2 даёт лучшее качество, но медленнее. Выбор зависит от вашего сценария: для стримов подойдёт RVM MobileNetV3, для офлайн-продакшена — ResNet50.

Метод FPS (CPU) FPS (GPU) Качество
RVM MobileNetV3 28–35 100–140 Высокое
MediaPipe Selfie Segmentation 60+ Среднее
RVM ResNet50 8–12 45–60 Лучшее
Background Matting V2 5–8 30–40 Высокое

Типичные ошибки при интеграции AI-замены фона

Ошибка Последствие Решение
Игнорирование temporal coherence Мерцание фона, артефакты Использовать RVM или другие рекуррентные модели
Неоптимальное разрешение Низкий FPS или плохое качество маски Подбирать размер так, чтобы сохранить баланс; для CPU использовать 256x144
Отсутствие квантизации Замедление инференса на CPU Применить INT8 квантизацию в ONNX
Неправильный выбор модели Несоответствие требованиям по скорости/качеству Провести бенчмаркинг на целевом железе

Что входит в работу?

Мы предоставляем:

  • Анализ вашего сценария и выбор модели
  • Интеграцию в вашу инфраструктуру (API, WebRTC, мобильное приложение)
  • Оптимизацию под целевое железо (CPU/GPU/Edge)
  • Документацию и обучение команды
  • Поддержку после внедрения

Свяжитесь с нами для аудита вашего проекта — мы оценим требования и предложим оптимальное решение.

Как выбрать модель для замены фона?

При выборе модели учитывайте: целевое оборудование (CPU/GPU), требуемое разрешение и FPS, допустимую задержку. Для мобильных устройств лучше подходит MediaPipe, для продакшена — RVM с ONNX. Мы поможем подобрать конфигурацию и оптимизировать под ваш сценарий.

Процесс работы

  1. Аналитика: изучаем требования к FPS, задержкам, качеству маски.
  2. Проектирование: выбираем модель, стек (ONNX, PyTorch, TensorRT).
  3. Реализация: пишем код интеграции, добавляем рекуррентное состояние.
  4. Тестирование: замеряем latency p99, FLOPS, проверяем на разных сценах.
  5. Деплой: разворачиваем на ваших серверах или в облаке.

Сроки и стоимость

Ориентировочные сроки:

  • Интеграция RVM для видеофайлов: 1–2 недели.
  • Realtime плагин для видеоконференций: 4–8 недель.
  • Мобильное приложение: 8–14 недель.

Стоимость рассчитывается индивидуально после аудита проекта. У нас более 5 лет опыта в AI/ML, мы реализовали свыше 30 проектов по компьютерному зрению. Гарантируем качество маски и соблюдение сроков. Закажите разработку под ключ — получите готовое решение с гарантией.

Пример конфигурации для деплояДля быстрого запуска на сервере с GPU используйте Docker-образ с PyTorch и Triton Inference Server. Конфигурация включает загрузку модели RVM в ONNX формате и настройку эндпоинта для поточной обработки видео. Подробности уточняйте при аудите.