视频 blob 上的 javascript 边缘检测

问题描述 投票:0回答:0

我正在尝试从网络摄像头录制视频,然后使用 openCV.js(正确包含在我的 html 文件中)对该视频应用边缘检测过滤器。录音有效,我正在使用 WebRTC 进行录音。它给了我一个 blob 中的视频,我可以毫无问题地显示它。

这里是边缘检测函数的代码:

async function detectContours(inputBlob) {
    console.trace("a");

    const response = await fetch(URL.createObjectURL(inputBlob));
    const blob = await response.blob();

    const inputVideo = document.createElement("video");
    inputVideo.src = URL.createObjectURL(blob);

    await new Promise((resolve) => {
    inputVideo.addEventListener("loadedmetadata", () => {
        resolve();
    });
    inputVideo.load();
    });

    console.log("type de inputVideo : %o", typeof inputVideo);
    console.log("vidéo d'entrée : %o * %o", inputVideo.height, inputVideo.width);

    console.trace("b");
    await new Promise((resolve) => {
    inputVideo.addEventListener("canplaythrough", () => {
        resolve();
    });
    inputVideo.load();
    });
    await inputVideo.play();

    console.trace("c");
    const outputCanvas = document.createElement("canvas");
    outputCanvas.width = inputVideo.videoWidth;
    outputCanvas.height = inputVideo.videoHeight;
    const outputCtx = outputCanvas.getContext("2d");

    console.trace("d");
    outputCtx.drawImage(
        inputVideo,
        0,
        0,
        outputCanvas.width,
        outputCanvas.height
    );

    console.trace("e");
    const cvInput = cv.imread(outputCanvas);
    const cvOutput = new cv.Mat();

    console.trace("f");
    cv.Canny(cvInput, cvOutput, 100, 200);

    console.trace("g");
    console.log(
      "vidéo d'entrée : %o * %o",
        inputVideo.videoHeight,
        inputVideo.videoWidth
    );
    console.log("canvas de sortie : %o * %o", cvOutput.rows, cvOutput.cols);
    console.log("%o bytes", cvOutput.data.length);
    const outputImageData = new ImageData(
        new Uint8ClampedArray(cvOutput.data),
        cvOutput.cols,
        cvOutput.rows / 4
    );

    console.trace("h");
    const outputCanvas2 = document.createElement("canvas");
    outputCanvas2.width = outputImageData.width;
    outputCanvas2.height = outputImageData.height;
    const outputCtx2 = outputCanvas2.getContext("2d");
    outputCtx2.putImageData(outputImageData, 0, 0);

    console.trace("i");
    const outputBlob = await new Promise((resolve) =>
        outputCanvas2.toBlob(resolve, "image/png")
    );

    console.trace("j");
    URLvideoEdge = URL.createObjectURL(outputBlob);
    blobVideoEdge = outputBlob;

    console.trace("k");
}

这是我点击“停止录制”按钮时调用的函数代码:

async function stopRecording() {
    console.trace("1");
    //Recording the video
    for (let track of stream.getTracks()) {
        track.stop(); //when this event is triggered, function called display the video without any issue 
    }
    console.trace("2");

    // verifying blobVideoCouleur actually is an object
    while (typeof blobVideoCouleur !== "object") {
      await new Promise(resolve => setTimeout(resolve, 100)); // Pause 100ms
    }

    console.trace("3");


    //Applying edge detection filter
    await detectContours(blobVideoCouleur);

    console.trace("4");


    //Displaying filtered video 
    playBack.src = URLvideoEdge;
    playBack.autoplay = true;

    console.trace("5");

}

playBack
是一个全局变量,定义为播放录制视频的 html 视频元素

以防万一,这是执行此操作的函数,在我停止录制时调用:

    recorder.onstop = () => { // Event triggered when I stop the recorder 
        const blob = new Blob(chunks, { //
        type: 'video/webm' // Et il le fait en webm
        })
        chunks = [];
        URLvideoCouleur = URL.createObjectURL(blob);
        playBack = document.getElementById("playBack");
        playBack.src = URLvideoCouleur;
        playBack.controls = true;
        blobVideoCouleur = blob;
    }

好吧,我在使用 openCV.js 时遇到了很多问题,因为我以前从未使用过它,所以这就是为什么我的代码中有那么多

console.trace
,因为我可以看到代码哪里有错误。我在这段代码中找到的最后一个“解决方案”是在这里除以 4:

    const outputImageData = new ImageData(
        new Uint8ClampedArray(cvOutput.data),
        cvOutput.cols,
        cvOutput.rows / 4
    );

Cause ImageData 正在寻找等于 in_video_height*in_video_width*4 尺寸乘以 4“颜色”(RGBA)的数据长度,但实际上我只是在应用边缘检测过滤器后有一层,黑色或白色。

所以从现在开始,代码在控制台中没有中断或错误地运行,但最终的行为并不像预期的那样。我的视频播放器不显示过滤视频而不是“正常”视频,它甚至不是视频而是黑色块,带有控件,但无用,因为视频的持续时间为 0。 (见画面) what's shown instead of my filtered video

好吧...因为我没有控制台反馈,我只是被困住了,我不再知道我能做些什么来获得这个过滤后的视频。你有什么建议吗? 此外,我不禁认为这个功能

detectContours
是一个巨大的gasworks,没有更简单的方法可以在js中对我的视频应用边缘检测滤镜?

提前致谢

javascript opencv video blob edge-detection
© www.soinside.com 2019 - 2024. All rights reserved.