在p5.js中实现视频前120帧序列重复帧移除的方法问询
解决方案
1. 修正前120帧采集逻辑
原有代码存在两处需要调整的逻辑:
- 采集条件里
frameCount <= 100仅采集100帧,需要改成120 image(video.get())是把帧绘制到画布,返回值为空,应直接存储video.get()拿到的p5.Image对象
修正后的基础代码如下:
const videoWidth = 640, videoHeight = 480; const canvasWidth = 640; let video; 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 <= 120) { // 直接存储帧的p5.Image对象 frames.push(video.get()) } else if (!STOP) { STOP = true uniqueFrames = removeDuplicates(frames) // 调试用:输出去重前后的帧数 console.log('原始帧数:', frames.length, '去重后帧数:', uniqueFrames.length) } }
2. 实现连续重复帧移除函数
不需要引入额外的ffmpeg相关JS库,在p5.js环境下直接通过计算相邻帧的像素差异即可实现类似去重效果,可通过调整差异阈值控制去重灵敏度:
function removeDuplicates(frames, threshold = 5) { if (frames.length === 0) return [] // 第一帧直接保留 const unique = [frames[0]] let lastFrame = frames[0] lastFrame.loadPixels() for (let i = 1; i < frames.length; i++) { const currentFrame = frames[i] currentFrame.loadPixels() let diffSum = 0 // 间隔采样计算像素差异,降低性能消耗 for (let j = 0; j < currentFrame.pixels.length; j += 16) { diffSum += Math.abs(currentFrame.pixels[j] - lastFrame.pixels[j]) diffSum += Math.abs(currentFrame.pixels[j+1] - lastFrame.pixels[j+1]) diffSum += Math.abs(currentFrame.pixels[j+2] - lastFrame.pixels[j+2]) } // 计算平均每个采样点的RGB差异值 const avgDiff = diffSum / (currentFrame.pixels.length / 16 * 3) // 差异大于阈值才保留 if (avgDiff > threshold) { unique.push(currentFrame) lastFrame = currentFrame } } return unique }
参数说明:
threshold为差异阈值,数值越小去重越严格,5为常规摄像头场景的推荐值,静态场景可以调至2-3,动态场景可以调至8-10- 代码采用间隔16个像素采样的逻辑,比逐像素计算性能高16倍,对差异计算准确性的影响极小
内容的提问来源于stack exchange,提问作者user2272048
相关产品推荐
相关产品推荐

