Как запустить модель handpose tfjs в web worker

#typescript #tensorflow #web-worker #tensorflow.js

#typescript #тензорный поток #web-worker #tensorflow.js

Вопрос:

Я хочу использовать webcamera для получения фрейма и запуска модели tensorflow «handpose» для оценки видимости рук. Как мы знаем, модель handpose немного медленная, поэтому я пытаюсь перенести оценку на web worker.

проблема HTMLVideoElement object could not be cloned. в том (мне нужно передать видео в метод estimateHand).

Можно ли сделать это по-другому?

web worker:

 import { getModel } from "../utils/tf-model";

let model: any;

const modelLoading = async () => {
    model = await getModel();
}

export const estimate = async (video: HTMLVideoElement) => {
    if (model) {
        const hands = await model.estimateHands(video);
        return hands;
    }
    return null;
}

modelLoading();

export default {} as typeof Worker amp; (new () => Worker);
  

основной поток:

 import MyWorker from 'comlink-loader!./worker';

const worker = new MyWorker();

...

func = async () => {
        const res = await worker.estimate(this.video);
        ...

  

Редактировать
Я нашел решение самостоятельно, его можно получить ImageData из контекста canvas и передать его web worker.

 ...
const canvas = document.createElement('canvas');
// ofc we have to set width and height equal to video sizes ...

const ctx = canvas.getContext('2d')
ctx.drawImage(this.video, 0, 0, this.video.width, this.video.height);
const img = ctx.getImageData(0, 0, this.video.width, this.video.height);
const res = await worker.estimate(img);
  

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

1. Не могли бы вы объяснить свою первую строку import { getModel } from "../utils/tf-model"; ? В настоящее время я использую import * as handPoseDetection from '@tensorflow-models/hand-pose-detection'; который не работает в web worker. Откуда у вас tf-модель?

Ответ №1:

Хорошо, я нашел решение. Это так хорошо, что мы не можем передавать HTML-элементы в качестве параметров web worker, но, конечно, мы можем играть с контекстом canvas, как показано ниже:

 ...
const canvas = document.createElement('canvas');
// ofc we have to set width and height equal to video sizes ...

const ctx = canvas.getContext('2d')
ctx.drawImage(this.video, 0, 0, this.video.width, this.video.height);
const img = ctx.getImageData(0, 0, this.video.width, this.video.height);
const res = await worker.estimate(img);
  

Ответ №2:

Если видео не отображается, ширина и высота могут быть пустыми, поэтому вместо этого используйте videoWidth:

     const canvas = document.createElement('canvas');
    canvas.width = video.videoWidth
    canvas.height = video.videoHeight

    const canvasContext = canvas.getContext('2d')
    canvasContext.drawImage(video, 0, 0, canvas.width, canvas.height)
    const img = canvasContext.getImageData(0, 0, canvas.width, canvas.height)