Как стать автором
Обновить

Комментарии 19

А почему у вас canvas?.getContext('2d'); У канваса не может не быть 2D контекста.
Блюр ооочень ресурсоемок, я бы его заменил на что-то другое, хотя визуально красиво.
Такс… а это блюр на css -ке сделан? хм. интересно, но все равно он тяжеловат.

Работать с канвой можно попробовать через Uint32Array, там пиксель будет представлен как элемент массива в 4 байта, а в канвасовом 1 пиксель один элемент, теоретически облегчается задачка для вычислений.

Но, вообще странно, ведь исходник с лицами не может не быть недоступен для решения этой задачи на канве)

P.S. Если кто подскажет, как при пикселизации смешать цвета соседних пикселей, чтоб было не так «грубо»,

Делать Antialiasing на краях маски самостоятельно. Только это опять доп ресурсы.
Или может это поможет
developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled

Спасибо за комментарий

canvas?.getContext('2d'); сделан так, потому что берется по ref и TS ругается на то, что он может быть null, хотя он в ComponentDidMount. Возможно я не до конца пока разобрался с TS + React.

Блюр ресурсоемок, но для 30FPS он достаточен на современных компах, на маломощных не тестировал, таких не нашлось:) Но на крайний случай, можно использовать Web Worker + OffscreenCanvas и это разгрузит основной поток

getImage возвращает данные в формате Uint8ClampedArray и если я правильно понимаю, это в 4 раза меньше размерности Uint32Array будет, вычисления только усложнятся, да и перегонять из одного формата в другой 30 раз в секунду не лучшая идея

По поводу исходника лиц - да, это больше как редактор предполагается для людей, которые имеют доступ к просмотру лиц, финальное видео генерируется на бэке и отдается с уже размытыми объектами, там не подсмотришь. А со знанием Front End легко можно слои поудалять из DOM и просмотреть)

imageSmoothingEnabled не помог, по крайней мере просто выставление в true.

Про Antialiasing пойду почитаю, спасибо.

Вычисления должны наоборот увеличиться, cудя по этой статье,
hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays
суть в том что доступны побитовые операторы, массив короче в 4 раза, и для редактирования 1 пикселя нужно затратить меньше операций. Ну это только теория :-)
Мне встречались на SO замеры дающие +25% к производительности.

Если я правильно понимаю типизированные массивы, то это просто маска для просмотра области памяти, низкая. Попробуйте сделать console.log() с вызовом buffer вашего канваса, увидите что-то такое:
image

Если сделать общий буфер new ArrayBuffer() для Uint8ClampedArray и Uint32Array то пересчета не происходит, просто возвращается разная структура. Но я не уверен, что переноса чисел из одной области памяти в другую при использовании уже существующего Uint8ClampedArray как Uint32Array не будет происходить, потому что мне как-то все равно приходилось создавать общий буфер как в примере из статьи выше
jsfiddle.net/andrewjbaker/GhwUC
может быть я не понимаю чего и при таких реализациях нет операций копирования, не знаю, а если есть… надо делать замеры.

По поводу исходника лиц — да, это больше как редактор предполагается для людей, которые имеют доступ к просмотру лиц, финальное видео генерируется на бэке и отдается с уже размытыми объектами, там не подсмотришь.

И кстати, вы про SVG не забыли? Можно же там маски накладывать, блюрть, и там будет антиалиазинг.
developer.mozilla.org/en-US/docs/Web/SVG/Element/feGaussianBlur
developer.mozilla.org/en-US/docs/Web/SVG/Element/mask

И ведь можно делать блюр без канвы, создаете div тяните его с border-radius по нужной форме и это
developer.mozilla.org/ru/docs/Web/CSS/backdrop-filter

Но в таком случае как рендерить на сервере? Там стоит дублирующий функционал только для ffmpeg?
Можно попробовать конвертить через wasm-ffmpeg на клиенте.

А можно и на сервере, на ноде, wasm api там завезли.
А вообще, я предлагаю в наглую кропать канвас с фронта и жать на фронте.
Правда я не знаю как обеспечить синхронизацию между фреймом отрисовки и фреймом захвата. Можно ли как стопарить процесс отрисовки браузером?

Впринципе да, если нам нужно по каждому пикселю пройтись, то Uint32Array в теории будет быстрее работать, а т.к тут мы по pixelSize идем, то оно будет одинаковым.

C SVG реализация тоже интересная, можно будет попробовать и сравнить результаты, хорошая тема для след статьи :)

backdrop-filter тоже вариант, но т.к эксперементальная, в продакшене использовать чревато.

На сервере ffmpeg делает такую же логику и генерирует видео результирующее - да.

wasm-ffmpeg - интересно, поизучаю.

Много полезного узнал, спасибо

На сервере ffmpeg делает такую же логику и генерирует видео результирующее — да.

Выходит, что есть дублирующий функционал? На сервер передаются координаты?
вообще можно через tenserflow сделать треки лиц а потом дать возможность подправлять эти треки. он через wasm работает тоже.

Да, можно еще не 2D контекст брать, а 3D, там тоже есть какие то фишки для антиалиазинга.

Входные данные для FE и BE это координаты объектов, да.

вообще можно через tenserflow сделать треки лиц а потом дать возможность подправлять эти треки. он через wasm работает тоже.

Оно так и делает, только на стороне BE, была идея сделать на tensorflow на стороне FE, но у нас есть самописный трекер на питоне. Ну и редактирование потом на FE, да

SVG пробовал - очень медленно получется, фпс упал до 6

вполне возможно, надо спеку смотреть куда там откуда и что гоняется.

Может есть пример кода? хотелось бы тоже попробовать самому сравнить результат

Уже нет, я ноут менял и гит локальный почищен. Но смысл в том, что канвас рисует быстрей, чем работать с svg объектами.

Можно попробовать погонять перфоманс изменения объета на миллион повторений, для интереса.

Возможно пикселизация будет быстрее, если рисовать на маленьком канвасе с маской и растягивать его через трансформ поверх основного канваса.

смешать цвета соседних пикселей

Блюр перед пикселизацией должен как раз смешать цвета

хорошая идея, попробую, спасибо

Снимая видео на своей телефон в общественном месте, не всегда, люди, которые попадают в кадр, будут довольны этим и можно получить "по жопке" за это. Для избежания этого лица рамывают или пикселизируются.

Надо делать не блюр или пикселизацию, надо просто и тупо закрашивать лица одноцветным прямоугольником. Оставлять даже небольшую часть информации о лице -- полумеры.

это выглядит слишком грубо, данная реализация выполняет свою функциональность на юридическом уровне (результирующее видео без слоев на Web. Web app часть как редактор используется).

Это, конечно, правильно (хотя можно для красоты закрашивать изображением размытого абстрактного лица). Но это если закрашивать на сервере.

А если блюр делать в браузере, javascript-ом, то всё равно. Смысл, вешать суперзамок на дверь, если окна нараспашку?

А если блюр делать в браузере, javascript-ом, то всё равно. Смысл, вешать суперзамок на дверь, если окна нараспашку?

Это приватный редактор у кого и так есть доступ к исходникам видео.

Это решение стоит рассматривать как сервис-редактор, который позволяет загрузить видео, заблюрить объекты, просмотреть результат и затем выгрузить готовое видео с заблюренными объектами. Т.е не для общего доступа с просмотром результат

Очень интересно было как такие штуки делаются. Благодаря статье стало понятнее. Автору спасибо! :)

рад был помочь :)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории