移除 p5.js 中的连续重复帧
Remove sequentially duplicate frames in p5.js
- 在下面的代码中,我想获取前 120 帧。
- 然后我想删除顺序重复的
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)
}
}
你可以做的一件事是在两帧之间取绝对差值。
当您这样做时,如果所有像素都匹配,则结果将是一张全黑的图像,否则您将在帧不同的地方有更亮的像素。对于一系列传统的计算机视觉任务来说,这是一项非常有用的基本技术。
你可以做的是编写一个接受两帧的函数,计算绝对差,计算非零像素,然后 returns。该值在针对阈值的 if 条件中很有用:也许帧不需要 100% 相同,但如果它们有 85% 相同,那么您可以将其标记为重复。
Kyle McDonald's Frame Difference p5.js example太棒了!
作为参考,我只是在此处列出 Kyle 的示例:
// 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()
.
中调用它
- 在下面的代码中,我想获取前 120 帧。
- 然后我想删除顺序重复的
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)
}
}
你可以做的一件事是在两帧之间取绝对差值。
当您这样做时,如果所有像素都匹配,则结果将是一张全黑的图像,否则您将在帧不同的地方有更亮的像素。对于一系列传统的计算机视觉任务来说,这是一项非常有用的基本技术。
你可以做的是编写一个接受两帧的函数,计算绝对差,计算非零像素,然后 returns。该值在针对阈值的 if 条件中很有用:也许帧不需要 100% 相同,但如果它们有 85% 相同,那么您可以将其标记为重复。
Kyle McDonald's Frame Difference p5.js example太棒了!
作为参考,我只是在此处列出 Kyle 的示例:
// 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()
.