【问题标题】:Detect differences between two video frames displayed in HTML5 canvas检测 HTML5 画布中显示的两个视频帧之间的差异
【发布时间】:2018-09-08 12:50:49
【问题描述】:

我在 HTML5 画布中显示实时视频流,效果很好。

现在,我需要做的是检查相机中是否有任何"motion" 显示在 HTML5 画布中。

在我的研究中,我发现这可以通过检查前一帧与画布中显示的当前帧来完成。

所以我在setInterval 函数中尝试了这段代码:

  var c = document.querySelector('.mycanv');
  var ctx = c.getContext("2d");

  var imageData = ctx.getImageData(0, 0, 200, 200);
  var data = imageData.data.length;

  console.log(data);

但是,当我查看控制台时,变量data 输出的Number 始终是相同的,即16000!即使相机前面有movemnet也不会改变。

我不完全确定我是否走在正确的轨道上。

有人可以就这个问题提出建议并指出正确的方向吗?

提前致谢。

这是一个缩小的简单示例:

https://jsfiddle.net/2648xwgz/

基本上,代码在画布中绘制视频帧。

现在,我需要做的是检查画布中的前一帧/图像是否与当前帧/图像相同。


第二次编辑:


好的,所以我已经接受了船上 cmets 中的所有建议,并试图提出一些实际上不会检查图像中所有随机像素的方法,因为这很重而且不是一个好的实践。 .

所以,我尝试了这样的事情:

https://jsfiddle.net/qpxjcv3a/6/

上面的代码可以在 Firefox 和本地视频文件中正常运行。但是在 JSFIDDLE 上,你会得到一个跨域错误。

无论如何,上面代码中的关键点是使用ctx.globalCompositeOperation = 'difference'; 我猜。

然后从here 进行“scrore”计算以检测一些变化。

但是,当我运行我的代码时,我总是在控制台中得到:console.log('we have motion');!即使视频暂停并且没有更多新帧。

所以我做了console.log(imageScore);,它总是加起来10000,即使视频暂停或结束!我不确定为什么会这样,以及这个计算是否正确。但这就是我目前所处的位置。

任何指针和帮助表示赞赏。

【问题讨论】:

  • imageData 的length 是相同的,因为它们包含相同数量的像素。您需要比较像素数据本身(可能使用something like this,尽管当前的技术可能比旧问题中显示的技术更多)
  • @DanielBeck,这是有道理的。但是,您发布的链接指的是两张图片。我知道我正在尝试从画布中获取帧,这些画布本质上被归类为不同的图像,但是在添加下一个图像之前删除了图像。所以,老实说,我并不完全确定这对这种情况有什么帮助。
  • 很抱歉,它对您没有多大帮助,但仅检查两帧是否相同不会告诉您是否有任何运动。每一帧都会有噪声,而这种噪声是由随机性构成的,根据定义,每一帧都会有所不同。所以是的,您可以通过遍历两个 ImageData.data 中可用的所有像素数据来检测这种帧变化,但再一次,这不足以检测运动......
  • 您要比较的两个图像将是视频的两个帧——您需要在每次迭代时将像素数组捕获到一个变量中,因此您仍然可以使用它来比较它到下一步的当前视频状态。像this 这样的东西,但没有跨域错误,我对画布方法太生疏了,无法记住如何解决......

标签: javascript jquery html canvas


【解决方案1】:

正如丹尼尔所说,您需要检查像素,所有迭代的长度都是相同的。 您应该研究图像哈希算法。在每个时间间隔,您都可以计算一个哈希值,并将其存储在一个全局变量中,以便在下一个时间间隔进行比较。这还可以让您选择设置阈值,因此微小的更改不会触发运动检测。

此页面更详细地解释了图像哈希:https://jenssegers.com/61/perceptual-image-hashes

您可以从实现平均哈希开始。这很简单。您可以将画布尺寸减小到 8x8 像素。

ctx.drawImage(video, 0, 0, video.width, video.height, 0, 0, 8, 8);
var imageData = ctx.getImageData(0, 0, 8, 8);
var data = imageData.data;

然后你遍历图像数据并计算亮度。

var brightnessdata = []
for(var i = 0; i<data.length; i+=4){
    brightnessdata.push((data[i]+data[i+1]+data[i+2])/3);
}

剩下的就是简单的计算平均亮度,并将每个像素的亮度与平均亮度进行比较来计算哈希。

【讨论】:

  • 你对画布图像进行哈希处理吗?你能解释一下你所说的图像哈希是什么意思吗?
  • 称为感知散列。它的工作原理是使图像中的变化与散列成比例地反映。两个相似的图像会产生相似的哈希值。我分享的链接解释得很好,我不得不复制粘贴整篇文章在这里解释。但是在我分享的代码中,你只需要获取亮度数据数组的平均值。然后将数组中的每个值与平均值进行比较,值越大表示 1,值越小表示 0。
猜你喜欢
  • 2022-01-13
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-11
  • 2011-08-31
相关资源
最近更新 更多