Во-первых, наглядный пример того, чего я пытаюсь достичь:
(Фото предоставлено: https://unsplash.com/photos/pGcqw1ARGyg)
Короткий (tl; dr) вопрос
Используя HTML5 video & canvas, как я могу выполнить четырехточечное перспективное преобразование, чтобы можно было визуализировать только часть "телевизионного экрана" кадра на холсте? Почемуне моя реализация показывает правильную область?
Справочная информация о том, чего я пытаюсь достичь
Я пытаюсь создать веб-страницу, которая работает следующим образом:
- Пользователь направляет свою веб-камеру на телевизор, чтобы он находился где-то в кадре (но, возможно, под любым углом)
- Используя HTML5-видео и холст, веб-камера захватывается иПредварительный просмотр на веб-странице
- Пользователь может определить (нажав на предварительный просмотр), где расположены 4 угла экрана телевизора (4 пары координат x / y)
- **Видео деформировано (с использованием какого-либо перспективного преобразования), поэтому на холсте только отображаютсячасть изображения для фактического экрана телевизора (не весь вид веб-камеры) **
- Затем выполняется некоторая обработка изображения (например, для определения наиболее заметных цветов).Эта часть выходит за рамки этого вопроса, кроме того, что я хочу иметь возможность получить доступ к содержимому / пикселям холста HTML5 в конце.
Часть, с которой я борюсь, этоШаг 4. Чтобы убедиться, что я обрабатываю только соответствующую часть изображения для каждого кадра видео, важно, чтобы я «деформировал» изображение так, чтобы оно показывало только область «экрана телевизора», а невся картинка с веб-камеры.
После небольшого прочтения, я понимаю, что:
- Это требует некоторого вида преобразования перспективы, поскольку веб-камера может быть под любым углом, и мыне имеют дело с параллельными линиями, требуется 3-мерное преобразование, и 2D не будет достаточно.Это связано с тем, что 2D-преобразование (translate / rotate / scale / skew) не сможет работать со сходящимися сторонами.
- HTML5-холст представляет собой двумерный контекст и поэтому может поддерживать только 2D-преобразования, а не 3Dпреобразования.Поскольку мне нужно решение, которое работает с
canvas
, я не могу просто использовать 3D CSS-преобразование (например, https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d).. Это говорит о том, что, возможно, WebGL - это больше, чем мне нужно для работы с 3D-аспектом.
То, что я пытался сделать до сих пор
Имея это в виду, я попытался использовать следующий подход:
a) Захват веб-камеры с помощью тега video
b) Используя three.js , создайте трехмерную сцену, которая визуализируется в элементе canvas
(чтобы я мог выполнить обработку изображения на полученном содержимом холста)
c) Сцена three.js состоит из: - плоской сетки, в которой показано видео с одной стороны, используя VideoTexture
.- перспективная камера, изначально расположенная так, что она показывает все изображение веб-камеры
d) Разрешить пользователю нажимать на четыре угловые точки, чтобы определить, где находится его телевизор, выяснить, какие координаты х / у и сохранитьих
e) Рассчитайте перспективное преобразование, которое "растянет" изображение так, чтобы правильная область "заполнила кадр".Другими словами, растяните четыре щелкаемых «телевизионных угла» до четырех углов области просмотра.Я использовал эту библиотеку: https://github.com/jlouthan/perspective-transform для вычисления этого.
f) Я думаю, что если соответствующее преобразование применяется к мешу, содержащему видео, и камера остается в фиксированномположение, то выходной холст будет содержать требуемое изображение при просмотре в 2D.
Ссылка на мою текущую (неработающую) реализацию
Вот ссылка на мою текущую попытку выше.Он показывает видео и позволяет щелкнуть четыре угла.Кажется, что это работает, если вы нажимаете точки вокруг источника (в центре), но проблема в том, что он показывает неправильную область, если вы выбираете области в другом месте изображения.
https://bitbucket.org/mattwilson1024/perspective-transform/src/master/
Подводя итог
Я был бы очень признателен за любую помощь, выясняющую, почему это работает не так, как я ожидал, или за любые указания относительно того, есть ли лучший / более легкий подход для достижениячто мне нужно.