Содержание статьи +
Кратко
Виртуальный фон и размытый фон начинаются с одного и того же шага: маленькая нейросеть смотрит на каждый кадр видео и решает попиксельно, какие пиксели – это вы, а какие – комната. Разница в том, что происходит дальше: размытие смягчает ту комнату, что у вас уже есть, а виртуальный фон выбрасывает её и рисует на её месте новую картинку. Эта вторая работа, называемая композитингом (наложением), – простая арифметика, которая смешивает ваши пиксели с пикселями нового фона вдоль края трафарета; трудность в том, что человек, освещённый лампой в спальне, на фоне солнечного пляжа выглядит фальшиво, пока вы не спрячете шов. Эта статья объясняет математику композита простыми словами, почему замена выглядит менее естественно, чем размытие, какие приёмы прячут шов, и как встроить функцию в свой видеопродукт.
Почему это важно
Если вы когда-нибудь включали пляж или книжную полку за спиной в Zoom и замечали мерцание уха или ореол вокруг волос – эта статья объясняет, что именно идёт не так и почему. Если вы делаете софт – продакт-менеджер, основатель или инженер, добавляющий видео в продукт, – виртуальные фоны входят в число самых запрашиваемых функций камеры, и их обманчиво легко сделать на 80% и неожиданно трудно довести последние 20%. Тот же шаг сегментации лежит в основе размытия, виртуальных фонов, beauty-фильтров и живых AR-эффектов, так что инженерия, которую вы здесь освоите, переносится на целое семейство функций. Правильный композит – это разница между функцией, которая выглядит профессионально, и вырезкой, наклеенной на плакат.
Тот же трафарет, другая краска
В нашем уроке про то, как размыть фон, мы подробно разобрали первый шаг, поэтому здесь – кратко. Программа прогоняет каждый кадр через модель сегментации – маленькую нейросеть, обученную узнавать форму человека, – и получает обратно маску: чёрно-белое изображение того же размера, что и видео, где каждый пиксель, принадлежащий вам, белый, а каждый пиксель комнаты – чёрный. Думайте о маске как о трафарете, вырезанном точно по форме вашего тела и волос.
Размытие и виртуальные фоны используют этот трафарет одинаково. Модель не знает и не интересуется, что вы собираетесь делать с результатом. Меняется только краска. Размытие оставляет ваши резкие пиксели там, где трафарет белый, и рисует смягчённую копию той же комнаты там, где он чёрный. Виртуальный фон оставляет ваши резкие пиксели там, где трафарет белый, и рисует совсем другое изображение – пляж, офис, логотип компании – там, где он чёрный.
Именно общий первый шаг объясняет, почему эти две функции всегда выходят вместе. Google добавил размытие и замену в Google Meet одним релизом в 2020 году, обе на одной модели сегментации MediaPipe, работающей в браузере. Если у вас есть одна, добавить вторую почти ничего не стоит. Детали модели – как её обучают, насколько она мала, как быстро работает – лежат в нашем уроке про MediaPipe Selfie Segmentation; эта статья – про краску.
Шаг композита: смешать две картинки вдоль края
Композитинг – это соединение переднего плана (вас) с фоном (новым изображением) в один кадр. Маска говорит, откуда брать каждый пиксель. Там, где маска полностью белая, выходной пиксель на 100% – это вы. Там, где маска полностью чёрная, выходной пиксель на 100% – новый фон. Самое интересное – край, где маска не чисто белая и не чисто чёрная, а где-то посередине.
Это промежуточное значение называется альфа – число от 0 до 1, которое говорит, сколько переднего плана сохранить. Альфа 1 значит «весь человек», альфа 0 – «весь фон», а альфа 0,6 – «60% человека, 40% фона». Формула смешивания – одна из самых старых и надёжных в компьютерной графике, оператор over, опубликованный Томасом Портером и Томом Даффом в 1984 году:
output = foreground × alpha + background × (1 − alpha)Покажем математику вслух один раз – и она перестанет быть абстрактной. Представьте один пиксель прямо на краю вашего плеча, где трафарет наполовину включён. Модель даёт ему альфа 0,6. Красный канал вашего плеча там равен 200; красный канал нового пляжного фона в той же точке – 50. Композитор вычисляет:
output red = 200 × 0,6 + 50 × (1 − 0,6)
= 120 + 20
= 140Выходной пиксель – это смесь: в основном ваше плечо, с небольшой примесью пляжа, – и именно эта смесь делает край гладким, а не зубчатым. Выполните этот расчёт для каждого пикселя и каждого цветового канала тридцать раз в секунду – и у вас виртуальный фон. Вся функция – это одна нейросеть плюс одна строка арифметики.
Есть практическая тонкость, которую стоит знать, потому что она вызывает очень частую ошибку. Многие графические системы хранят цвета уже умноженными на альфу – формат, называемый premultiplied alpha (предумноженная альфа), – потому что это ускоряет оператор over и убирает тёмную кайму при масштабировании. Если ваш передний план предумножен, а фон – нет, или наоборот, вы получите характерный тёмный или светлый ореол вокруг человека. Согласовать их – правка в одну строку, как только знаешь, куда смотреть, и загадочный визуальный дефект, пока не знаешь.
Почему виртуальный фон выглядит фальшивее размытия
Вот мысль, которая объясняет любой неуклюжий виртуальный фон, что вы видели. При размытии передний план и фон пришли с одной камеры в один момент, поэтому у них одно освещение, одна цветовая температура, одно зерно и одна дистанция фокуса. Ваша размытая комната по-настоящему находится за вами, потому что она и есть за вами. Мозг принимает это мгновенно.
При замене вы склеиваете две картинки, у которых нет ничего общего. Вас освещала тёплая лампа спальни; пляж снят на холодном полуденном солнце. Ваша веб-камера добавляет цифровой шум; стоковое фото чистое. Получается человек, который не вписывается в сцену, и мозг замечает это в трёх конкретных местах.
Первая улика – край. Бинарная маска – чисто белая или чисто чёрная без промежутка – даёт жёсткий контур как у формочки для печенья. На фоне размытой копии вашей же комнаты жёсткий край незаметен, потому что обе стороны похожи. На фоне резкого контрастного пляжа тот же жёсткий край читается как наклейка. Решение – растушевать край: пусть альфа плавно спадает от 1 к 0 на нескольких пикселях, ровно как на Рисунке 2, – и, что ещё лучше, использовать alpha matting (альфа-матирование) вместо обычной сегментации. Маска сегментации помечает каждый пиксель «человек или нет»; альфа-матте оценивает дробную прозрачность для каждого пикселя, и именно это позволяет сохранить отдельные пряди волос, которые жёсткая маска срезает. Телефоны Google Pixel перешли в портретных селфи от сегментации к альфа-матированию именно по этой причине.
Вторая улика – несовпадение цвета и освещения. Ничто в простом композите не заставляет ваше тёпло освещённое лицо согласоваться с холодно освещённым фоном. Продвинутые конвейеры измеряют общий цвет фона и подтягивают к нему передний план или добавляют слабую кайму цвета фона вокруг человека.
Эта кайма – третье решение, и у неё есть имя: light wrapping (обтекание светом). Google Meet применяет его именно для замены фона. Light wrapping позволяет части света фона «перелиться» на край переднего плана – так свет реально огибает человека, стоящего в сцене. Это смягчает край сегментации и, когда передний план и новый фон резко различаются по яркости, минимизирует ореол, который иначе появился бы. Это самый эффективный приём, чтобы вклеенный человек выглядел снятым на месте.
Третья улика – spill (засветка цветом) – зеркальное отражение light wrapping и важнее всего, когда задействован зелёный экран. Это подводит нас к чит-коду.
Чит-код «зелёный экран»
Всё выше – это трудный путь: просить нейросеть угадать ваш контур на обычной, захламлённой сцене. Есть лёгкий путь, которым киноиндустрия пользуется десятилетиями. Встаньте перед однотонным, равномерно освещённым цветом – классически зелёным – и вопрос «какие пиксели фон» перестаёт быть угадыванием. Любой зелёный пиксель – фон; всё остальное – вы. Это chroma key (цветовая рирпроекция), и она настолько надёжна, что не требует нейросети вовсе – лишь сравнение цвета.
Поэтому Zoom предлагает режим виртуального фона «с зелёным экраном». Когда вы говорите Zoom, что у вас есть зелёный экран, он переключается с ML-сегментации на chroma key – чище, резче по краям и настолько дёшево, что работает на железе, слишком слабом для ML-пути. Собственные рекомендации Zoom это отражают: без зелёного экрана функция требует достаточно мощного процессора, а с ним работает на куда более скромных машинах. Для постоянной студии – ведущего регулярного вебинара, телемед-врача, отдела продаж, который записывает демо, – зелёная ткань за сорок долларов часто бьёт любую программную хитрость.
Цена зелёного экрана – единственный дефект, которого нет у ML-сегментации: spill. Зелёный свет отражается от ткани и подкрашивает края ваших волос и плеч зелёным, поэтому композиту нужен шаг spill suppression (подавление засветки), который находит и нейтрализует это загрязнение. Это решённая задача, но думать о ней приходится только с физическим экраном.
| Размытие | Виртуальный фон (ML) | Виртуальный фон (зелёный экран) | |
|---|---|---|---|
| Что показано | Ваша комната, смягчённая | Выбранное фото или видео | Выбранное фото или видео |
| Как находит вас | Сегментация человека | Сегментация человека | Chroma key (по цвету) |
| Доп. железо | Нет | Нет | Однотонная освещённая ткань |
| Качество края | Спрятано размытием | Нужны растушёвка + light wrap | Самое чистое, но нужен spill suppression |
| Главная слабость | Косметика, не приватность | Несовпадение света/цвета | Зелёная засветка; фикс. сетап |
| Работает на слабых | Иногда | Самый трудный путь | Да – chroma key дёшев |
Таблица 1. Три способа изменить то, что за вами. Колонки «размытие» и «ML-замена» используют общий движок сегментации; «зелёный экран» меняет его на сравнение цвета – дешевле и резче, но нужен физический экран.
Встроить в свой продукт
Если вы добавляете виртуальные фоны в веб-видеопродукт, у вас уже есть почти весь конвейер при условии, что вы сделали размытие, потому что архитектура идентична вплоть до финального шейдера. Вы подключаетесь к потоку камеры в точке сырых кадров – где каждый кадр ещё несжатые пиксели – через браузерный MediaStreamTrackProcessor, чтобы читать кадры, и MediaStreamTrackGenerator, чтобы возвращать изменённые кадры в звонок. Между ними – ваш transform: сегментировать кадр, чтобы получить маску, затем наложить ваше изображение фона под человека по этой маске.
// Берём кадр камеры, сегментируем, накладываем выбранный фон, возвращаем обратно.
const processor = new MediaStreamTrackProcessor({ track: cameraTrack });
const generator = new MediaStreamTrackGenerator({ kind: "video" });
const transformer = new TransformStream({
async transform(frame, controller) {
const mask = await segmenter.segment(frame); // человек или фон
const output = composite(frame, bgImage, mask); // вы поверх нового изображения
controller.enqueue(output);
frame.close(); // освобождаем память каждый кадр
},
});
processor.readable.pipeThrough(transformer).pipeTo(generator.writable);
const virtualBgStream = new MediaStream([generator]); // это и шлём в звонокДелайте шаг composite на GPU – графическом чипе, созданном ровно для такого попиксельного смешивания. Композит там дёшев: для каждого выходного пикселя шейдер читает один пиксель переднего плана, один пиксель фона и одно значение alpha, затем применяет формулу over. Это часто меньше работы, чем качественное размытие, которому надо усреднять много соседних пикселей, так что виртуальный фон может быть чуть быстрее размытия на том же устройстве. Оба всё равно должны уложиться в бюджет 33 миллисекунды, который даёт один кадр при 30 кадрах в секунду; наш урок про бюджет задержки разбирает эти часы, а ваш video SDK решает, доберётесь ли вы до точки сырых кадров вообще.
Несколько деталей отделяют чистый результат от грубого. Загрузите изображение фона на GPU один раз, а не каждый кадр – оно не меняется, и повторная отправка съедает весь бюджет. Решите, как изображение впишется в кадр: фото 16:9 на камере 4:3 надо обрезать «по покрытию», иначе ваш пляж растянется в кашу, поэтому большинство приложений масштабируют по покрытию и центрируют. Помните про зеркало: ваш self-view обычно отражён, поэтому любой текст на фоне будет читаться задом наперёд, если это не обработать. А если вы предлагаете видео-фон – зацикленный океан – держите его маленьким и заранее декодированным, потому что декодирование второго видеопотока съедает те же 33 мс.
Три ошибки из размытия возвращаются здесь, плюс одна новая. Растушуйте край маски, чтобы контур не был жёсткой линией от формочки. Смешивайте каждую маску с предыдущим кадром, чтобы край не мерцал от кадра к кадру. Закрывайте каждый VideoFrame, иначе вкладка течёт по памяти и падает за минуты. Новая – несовпадение premultiplied alpha с Рисунка 2: держите передний план и фон в одной альфа-конвенции, иначе будете гоняться за ореолом полдня.
О доверии и раскрытии
Виртуальный фон – косметика, но это и первый шаг к тому, чтобы видеопоток показывал то, чего на самом деле не было. Заменить комнату безобидно; тот же конвейер, продвинутый дальше, переходит в область изменённого или синтетического видео. Если ваш продукт выходит за рамки статичной замены – к чему-то, что может исказить человека или место, – начинают иметь значение правила раскрытия, которые мы разбираем в уроке про C2PA и Статью 50 EU AI Act. А поскольку функция опирается на обнаружение человека, граница, где обнаружение становится распознаванием – определением того, кто именно человек, – регулируется правилами из урока про обнаружение лиц и EU AI Act. Сама замена фона держится далеко от обеих границ, но это въезд на эту дорогу.
Есть и пункт про приватность, зеркальный размытию. Виртуальный фон скрывает вашу реальную комнату от других участников звонка, что по-настоящему полезно для телемедицины и удалённой работы. Но замена происходит после того, как камера уже захватила реальную комнату, так что незаменённый кадр всё ещё существует в памяти устройства мгновение. Для приватность-критичных продуктов придерживайте первые кадры, пока маска не готова, а не доверяйте тому, что замена мгновенна.
Где здесь Фора Софт
Мы делаем real-time видеопродукты с 2005 года – видеоконференции, WebRTC-приложения, e-learning, телемедицину и прямые трансляции, – и виртуальные фоны входят в число функций камеры, которые клиенты просят чаще всего. Работа редко в самом композите; она в том, чтобы шов держался на тысяче камер, схем освещения и причёсок, не сажая батарею и не мерцая на пятилетнем ноутбуке. В телемедицине, где виртуальный фон защищает дом пациента, и в брендированных вебинарах, где фон несёт логотип, который не должен искажаться, разница между убедительным композитом и картонной вырезкой – это набор инженерных решений, принятых рано: качество матте, light wrap, логика вписывания и стоит ли рекомендовать зелёный экран. Мы помогаем командам выбрать модель, чип и конвейер, чтобы функция, лёгкая в демо, работала и в поле.
Ключевые выводы
- Виртуальный фон использует ту же маску сегментации, что и размытие; различается только финальная краска.
- Композит – это одна формула: output = foreground × alpha + background × (1 − alpha).
- Замена выглядит фальшивее размытия, потому что человек и новая сцена не делят освещение.
- Растушёвка, alpha matting, light wrapping и подгонка цвета прячут шов.
- Зелёный экран меняет ML на дешёвый, резкий chroma key – ценой зелёной засветки.
- Стройте на GPU в точке сырых кадров; загружайте фон один раз и закрывайте каждый кадр.