使用OpenCV进行视频稳定

时间:2010-08-07 17:51:02

标签: c++ video opencv image-processing

我有一个视频输入,用移动的相机拍摄并包含移动物体。我想稳定视频,以便所有静止物体在视频输入中保持静止。如何使用 OpenCV

执行此操作

即。例如,如果我有两个图像prev_frame和next_frame,如何转换 next_frame 以使摄像机看起来不稳定?

8 个答案:

答案 0 :(得分:39)

我可以建议以下解决方案之一:

  1. 使用本地高级功能:OpenCV包括SURF,因此:对于每个帧,提取SURF功能。然后构建特征Kd-Tree(也在OpenCV中),然后匹配每两个连续帧以找到相应特征对。将这些对输入cvFindHomography以计算这些帧之间的单应性。根据(组合......)单应性变形框架以稳定。据我所知,这是一种非常强大和复杂的方法,但是SURF提取和匹配可能非常慢
  2. 如果您希望两帧之间只有轻微的移动,例如,您可以尝试使用“不太健壮”的功能执行上述操作。使用Harris角点检测并在两个帧中构建彼此最接近的角点,然后如上所述馈送到cvFindHomography。可能更快但不那么健壮。
  3. 如果您限制移动到翻译,您可以将cvFindHomography替换为更简单的内容,以便在功能对之间进行转换(例如平均值)
  4. 如果您希望仅在两个帧之间进行转换,请使用相位相关(参考http://en.wikipedia.org/wiki/Phase_correlation)。 OpenCV包括DFT / FFT和IFFT,请参阅关于公式和解释的链接维基百科文章。
  5. 修改 三个评论我应该明确提一下,以防万一:

    1. 基于单应性的方法可能非常精确,因此静止物体将保持静止。然而,单应性包括透视失真和缩放,因此结果可能看起来有点......不常见(甚至对于某些快速移动而失真)。虽然确切,但这可能在视觉上不那么令人愉悦;所以请使用它进行进一步处理,或者像取证一样。但是你应该尝试一下,对某些场景/动作来说也是非常讨人喜欢的。
    2. 据我所知,至少有几个免费的视频稳定工具使用相位相关。如果你只是想“解除”相机,这可能更合适。
    3. 这个领域正在进行一些研究。在一些论文中你会发现一些更复杂的方法(尽管它们可能需要的不仅仅是OpenCV)。

答案 1 :(得分:15)

OpenCV具有函数estimateRigidTransform()和warpAffine(),可以很好地处理这类问题。

它非常简单:

Mat M = estimateRigidTransform(frame1,frame2,0)
warpAffine(frame2,output,M,Size(640,480),INTER_NEAREST|WARP_INVERSE_MAP) 

现在output包含最适合frame2的{​​{1}}内容。 对于大的移位,M将是一个零矩阵或根本不是一个矩阵,具体取决于OpenCV的版本,因此您必须过滤那些而不应用它们。我不确定那有多大;可能是帧宽的一半,也许更多。

estimateRigidTransform的第三个参数是一个布尔值,告诉它是否也应用任意仿射矩阵或将其限制为平移/旋转/缩放。为了稳定相机中的图像,您可能只需要后者。实际上,对于相机图像稳定,您可能还希望通过将其标准化以仅旋转和平移来从返回的矩阵中删除任何缩放。

此外,对于移动相机,您可能希望通过时间对M进行采样并计算平均值。

以下是指向estimateRigidTransform()warpAffine()

的更多信息的链接

答案 2 :(得分:13)

openCV现在有一个视频稳定类:http://docs.opencv.org/trunk/d5/d50/group__videostab.html

答案 3 :(得分:4)

我从这一个回答了我的答案。 How to stabilize Webcam video?

昨天我刚做了一些关于这个主题的作品(Python),主要步骤是:

  1. 使用cv2.goodFeaturesToTrack找到好角落。
  2. 使用cv2.calcOpticalFlowPyrLK跟踪角落。
  3. 使用cv2.findHomography计算单应矩阵。
  4. 使用cv2.warpPerspective转换视频帧。
  5. 但现在结果并不理想,我应该选择SIFT keypoints以外的goodFeatures

    来源:

    enter image description here

    稳定汽车:

    enter image description here

答案 4 :(得分:3)

这是一个棘手的问题,但我可以提出一个有点简单的情况。

  1. 按任意金额移动/轮换next_frame
  2. 使用背景减法threshold(abs(prev_frame-next_frame_rotated))查找静态元素。您必须使用要使用的阈值。
  3. 查找min(template_match(prev_frame_background, next_frame_rotated_background))
  4. 记录最接近的匹配项的班次/轮换并将其应用于next_frame
  5. 这对于多个帧随着时间的推移效果不佳,因此您需要考虑使用background accumulator,因此算法所寻找的背景会随着时间的推移而变得相似。

答案 5 :(得分:3)

我应该添加以下备注来完成zerm's answer。 如果选择一个静止对象,然后使用zerm的方法(1)与该单个对象一起工作,它将简化您的问题。 如果你找到一个静止物体并对其进行校正,我认为可以安全地假设其他静止物体看起来也很稳定。

虽然它对您的棘手问题肯定有效,但这种方法会遇到以下问题:

  • 检测和单应性估计有时会因各种原因而失败:遮挡,突然移动,运动模糊,严重的光照差异。您将不得不寻找处理它的方法。

  • 您的目标对象可能有遮挡,这意味着它的检测将在该帧上失败,您将不得不处理遮挡,这本身就是一个完整的研究主题。

  • 根据您的硬件和解决方案的复杂程度,您可能会遇到使用SURF实现实时结果的麻烦。您可以尝试使用opencv的gpu实现或其他更快的功能检测器,如ORB,BRIEF或FREAK。

答案 6 :(得分:3)

这里已经有了很好的答案,但它使用了一点点旧算法,我开发了解决类似问题的程序,所以我添加了额外的答案。

  1. 首先,您应该使用SIFT,SURF算法等特征提取器从图像中提取特征。就我而言,FAST + ORB算法是最好的。如果您需要更多信息,请See this paper
  2. 获得图像中的功能后,您应该找到与图像匹配的功能。有几个匹配器但是Bruteforce匹配器也不错。如果您的系统中的Bruteforce速度很慢,则应使用像KD-Tree这样的算法。
  3. 最后,你应该得到几何变换矩阵,它可以最小化变换点的误差。您可以在此过程中使用RANSAC算法。 您可以使用OpenCV开发所有这些过程,我已经在移动设备中开发了它。 See this repository

答案 7 :(得分:0)

背景: 我正在从事这个研究项目,当时我试图计算出排队的人到达柜台要花费多长时间。我需要的第一件事是脚踏车,所以我去了校园,并记录了一些游客在排队等候取票的情况。到现在为止,我还不知道如何计算排队时间以及在录制录像时应采取的预防措施。最终,我发现我录制的所有镜头都是用摇晃的相机录制的。因此,此时我首先需要稳定视频,然后才开发其他解决方案来计算排队时间。

使用模板匹配来稳定视频

  • 找到静态对象,例如民意测验,门或您不应该移动的东西
  • 使用模板匹配来计算每个连续帧中静态对象位置变化(相对于帧边界)的偏移量。
  • 用偏移值(即tx和ty)转换每个帧。

结果镜头:

Gif to show the result of this technique

正如在gif中看到的那样,选定的静态对象在帧边界范围内保持静态,而通过从帧边缘填充黑色可以看到运动。