【问题标题】:Motion detection on screenshots屏幕截图上的运动检测
【发布时间】:2023-03-11 22:31:01
【问题描述】:

我想知道是否有一种快速算法可以检测在两个连续屏幕截图之间移动的部分。该算法应该获取两张图像,并在一张图像中输出一组(矩形)区域,以及一个描述匹配区域在另一张图像中的位置的向量。

我想将其用于为屏幕捕获而优化的无损视频压缩算法。我认为这使得用例与运动检测的通常应用有点不同:

  • 图像是屏幕截图。不太可能存在任何伪影或图像噪点
  • 如果图像的一部分移动,它会按像素移动。移动部分的像素差异通常不到 2%
  • 移动的区域通常很大并且呈矩形

由于视频压缩管道还有其他步骤并且应该实时发生,因此运动检测应该很快。

有什么有用的吗?

【问题讨论】:

    标签: screenshot video-processing motion-detection video-codecs


    【解决方案1】:

    Opencv 深入介绍了图像处理,并提供了大量关于该主题的教程。

    http://docs.opencv.org/doc/tutorials/tutorials.html

    PDF 比网站有更多的 tuts。 Google for... opencv 教程 pdf ...顶部链接。

    主要网站。 http://opencv.willowgarage.com/wiki/

    基本上,您可以在图像上运行一些数学函数来为您解决这个问题。卷积之类的。

    【讨论】:

    • 哦,请注意,有 opencv 1 和 2,并不是所有的教程都已转换为 2.0 语法。本质上,如果您看到 iplimage() 而不是 Mat() 那么您使用的是 1.0,您应该寻找一个使用 Mat() 的(opencv 2.0)
    • 这对于一台普通机器上 25 fps 的帧速率是可能的吗?
    【解决方案2】:

    跨帧跟踪运动的常用方法是: 1. 确定要在图像 1 中跟踪的点 2. 将输入图像中的点与输出图像中的点相关联 3. 确定让他们到达那里的变换

    对于第 1 步,有很多“跟踪器”,您可以在 OpenCV 中找到一些相当标准的用于寻找“有趣”点(边缘的交叉点、局部最大值等)。 Kanade-Tomasi 图像跟踪器就是其中之一。但是,为了您的使用,您可能更喜欢创建一个规则的点网格。

    对于第 2 步,一种常用技术是使用降低分辨率的四叉树...我的意思是拍摄您的图像,创建一个宽度和高度为 1/2 的新图像,一次又一次。现在您在顶部有一个非常低分辨率的图像,您可以更快地搜索数量级,并且会给您一个边界框来查看下一个更高的 rez 图像。在您的情况下,优化可能是首先查看输出以查看它是否发生了变化,当您找到点 x、y 的匹配项时,还要在其旁边查找点 x+1 或 y+1 等。

    对于第 3 步,这取决于您...如果您说的是在屏幕上滑动的窗口,则会有大块一起移动,但边缘内外是相同的。但是,如果有任何动画,那可能会把事情搞砸。并且鼠标光标本身是一个小东西,会四处移动并降低算法的有效性。

    【讨论】:

    • 那东西看起来很有趣!这是我想得到的答案。谢谢。
    【解决方案3】:

    我做了什么

    我实现了一种简单的技术,可以补偿大多数运动并且易于实现。

    每一帧都被分成固定大小的图块,例如 8×8 像素。编解码器管理可自定义数量的磁贴的环形缓冲区,例如 220。现在,对于编解码器在输入流中遇到的每个图块,它检查是否已经在环形缓冲区中找到它。如果是,它只是保存图块索引,如果不是,它将图块存储在环形缓冲区中。

    每当图像的一部分从过去的任何图像中移动块大小的倍数时,很可能会在缓存中找到切片。这样,可以补偿大多数运动。由于在 ringbuffer 中找到一个 tile 非常快,这足以实时运行。

    【讨论】:

    • 我正在尝试解决同样的问题。这是您最终实施的解决方案还是您进一步改进了它?理想情况下,我希望得到一个移动的矩形区域。你找到办法了吗?
    • @tunafish24 这是我们最终实施的解决方案,虽然它的效果相当平庸。有更好的运动检测方法;查看 H.264 等现代视频编解码器的功能。
    • 会的。你们在使用 Aero 的 Windows 7 上使用什么技术进行屏幕截图?我已经尝试过这里描述的流行的,即 GDI(鼠标闪烁 + 最大 30 fps)、DirectX(比 GDI 慢)。有一些闭源软件能够达到 60fps 且 CPU 使用量较小且无需安装驱动程序。很想知道他们是如何做到的。
    • 我们为 UNIX 开发了这个软件,并通过适当的 X11 接口捕获屏幕。我不在乎 Windows。
    【解决方案4】:

    我有一些想法,以及一个您可以考虑的可能可行的解决方案。

    首先,考虑跟踪单个像素增量并仅传输/存储这些增量。一个典型的交互会话通常只涉及很小部分的 UI 更改;对于长时间使用计算机的会话,移动或调整窗口大小往往不太常见(有趣的是)。这可以有效地捕获简单的内容,例如输入的文本、光标移动和小的 UI 更新,而无需大量额外工作。

    您还可以考虑尝试在较低级别挂钩操作系统,例如像素的显示列表,甚至(最好)“损坏”矩形列表。例如,Mac OS X 的 Quartz 合成器可以为您提供这些信息。这可以帮助您快速缩小要更新的范围,并且在理想情况下,可以为您提供屏幕本身的有效表示。

    如果您可以查询有关窗口的操作系统(窗口管理器)信息,则可以为每个可见窗口存储单独的数据流(像素增量),然后在播放期间应用简单的显示列表方法来“渲染”它们。然后,识别移动窗口就很简单了,因为您可以简单地区分显示列表。

    如果您可以查询操作系统关于光标位置的信息,您可以使用光标移动来快速估计移动增量,因为光标移动通常与屏幕上的对象移动密切相关(例如移动窗口、图标、拖动对象等)。 )。这使您可以避免处理图像以确定移动增量。

    关于一个可能的解决方案(或者如果您仍然无法通过上述方法识别移动增量的最后手段):我们实际上可以相当容易地处理(非常常见的)单个移动矩形的情况。制作帧中所有变化的像素的蒙版。识别掩码中最大的连通分量。如果它近似于一个矩形,那么您可以假设它代表一个移动的区域。窗口移动完全正交(例如完全在 x 或 y 方向),在这种情况下,总增量看起来像一个稍大的矩形,或者窗口沿对角线移动,在这种情况下,总增量将有一个 8 边形状。无论哪种方式,您都可以估计运动矢量,并通过区分区域来验证这一点。请注意,这种处理故意忽略了您必须考虑的细节,例如像素在窗口附近独立移动,或者看起来没有变化的区域(例如窗口中的大块纯色)。实际的实现必须处理上述所有问题。

    最后,我将研究有关实时运动估计的现有文献。在优化运动估计和补偿方面已经做了很多工作,例如视频编码,所以如果您发现上述方法不合适,您也可以使用该工作。

    【讨论】:

    • 使用鼠标光标估计运动是一个好主意,但在大多数情况下它会失败:考虑滚动 - 运动是反向的,不等同于鼠标光标(也可能上下移动)。还要考虑不使用鼠标滚动的 UI,例如 2D 游戏。此外,很难以便携的方式完成所有这些工作。无论如何感谢您的反馈!
    猜你喜欢
    • 2012-11-09
    • 2015-06-14
    • 2021-08-18
    • 1970-01-01
    • 2014-08-21
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多