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 та налаштування ендпоінта для потокової обробки відео. Подробиці уточнюйте при аудиті.