javascript - 删除 p5.js 中连续重复的帧

标签 javascript image-processing ffmpeg video-processing p5.js

  1. 在下面的代码中,我想要获取前 120 帧。
  2. 然后我想删除连续重复的

ffmpeg 有一个 mpdecimate过滤器应该丢弃彼此差异不大的帧。

但我不知道是否有 ffmpeg Js 库(或等效库)可以在 p5.js 上下文中执行类似的操作。

function setup() {
  frameRate(24)
  video = createCapture(VIDEO)
  video.size(videoWidth, videoHeight)
  video.hide()

  createCanvas(canvasWidth, canvasWidth)
}

let frames       = []
let uniqueFrames = []
let STOP         = false

function draw() {

  if (video && video.loadedmetadata && frameCount <= 100) {
    frames.push(image(video.get()))
  } else if (!STOP) {
    STOP = true
    uniqueFrames = removeDuplicates(frames)
  }
}

最佳答案

您可以做的一件事是获取两帧之间的绝对差异。

当您这样做时,如果所有像素都匹配,则结果将是全黑的图像,否则您将在帧不同的地方获得更亮的像素。这是一项对于一系列传统计算机视觉任务非常有用的基本技术。

您可以做的是编写一个函数,该函数接受两个帧,计算绝对差,计算非零像素并返回该值。该值在针对阈值的 if 条件中非常有用:也许这些帧不需要 100% 相同,但如果它们比方说 85% 相同,那么您可以将其标记为重复项。

Kyle McDonald's Frame Difference p5.js example太棒了!

作为引用,我在这里简单列出凯尔的示例:

// https://kylemcdonald.github.io/cv-examples/

var capture;
var previousPixels;
var w = 640;
var h = 480;

function setup() {
    capture = createCapture({
        audio: false,
        video: {
            width: w,
            height: h
        }
    }, function() {
        console.log('capture ready.')
    });
    capture.elt.setAttribute('playsinline', '');
    capture.size(w, h);
    createCanvas(w, h);
    capture.hide();
}

function copyImage(src, dst) {
    var n = src.length;
    if (!dst || dst.length != n) dst = new src.constructor(n);
    while (n--) dst[n] = src[n];
    return dst;
}

function draw() {
    capture.loadPixels();
    var total = 0;
    if (capture.pixels.length > 0) { // don't forget this!
        if (!previousPixels) {
            previousPixels = copyImage(capture.pixels, previousPixels);
        } else {
            var w = capture.width,
                h = capture.height;
            var i = 0;
            var pixels = capture.pixels;
            var thresholdAmount = select('#thresholdAmount').value() * 255. / 100.;
            thresholdAmount *= 3; // 3 for r, g, b
            for (var y = 0; y < h; y++) {
                for (var x = 0; x < w; x++) {
                    // calculate the differences
                    var rdiff = Math.abs(pixels[i + 0] - previousPixels[i + 0]);
                    var gdiff = Math.abs(pixels[i + 1] - previousPixels[i + 1]);
                    var bdiff = Math.abs(pixels[i + 2] - previousPixels[i + 2]);
                    // copy the current pixels to previousPixels
                    previousPixels[i + 0] = pixels[i + 0];
                    previousPixels[i + 1] = pixels[i + 1];
                    previousPixels[i + 2] = pixels[i + 2];
                    var diffs = rdiff + gdiff + bdiff;
                    var output = 0;
                    if (diffs > thresholdAmount) {
                        output = 255;
                        total += diffs;
                    }
                    pixels[i++] = output;
                    pixels[i++] = output;
                    pixels[i++] = output;
                    // also try this:
                    // pixels[i++] = rdiff;
                    // pixels[i++] = gdiff;
                    // pixels[i++] = bdiff;
                    i++; // skip alpha
                }
            }
        }
    }
    // need this because sometimes the frames are repeated
    if (total > 0) {
        select('#motion').elt.innerText = total;
        capture.updatePixels();
        image(capture, 0, 0, 640, 480);
    }
}
<html>

<head>
    <meta charset="UTF-8">
    <title>DifferenceImage</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
    <p>
        Threshold: <input type="range" id="thresholdAmount" value="25">
    </p>
    <p>
        Motion: <span id="motion">0</span>
    </p>
    <script src="sketch.js"></script>
</body>

</html>

查看实际效果 here .

祝您好运,将帧差异代码封装到可重用函数中,您可以在 removeDiplicates() 中调用该函数。

关于javascript - 删除 p5.js 中连续重复的帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69829962/

相关文章:

javascript - html 中具有相同属性的两个 <div> 层

php - 在从数据库中获取图像时,使用带有 php 的图像 magick 来调整图像大小

c# - GPU 上的 OpenCV MatchTemplate

java - 使用 opencv 进行人脸检测时出现异常

linux - 将 movflags 添加到 mp4 文件的顶部,而不使用 ffmpeg 进行实时 RTSP 流

bash - 将以数字开头的文件重命名为两位数

ffmpeg - 如何修复输出流中的非单调 DTS 0 :1; when using ffmpeg

javascript - AngularJS中3维数组的ngModel?

javascript isNaN() 函数不起作用?

javascript - 检查 'this' 在 JavaScript 中引用了什么