2010-08-07 156 views
32

我有一个使用移动摄像头拍摄并包含移动对象的视频输入。我想稳定视频,以便所有静止物体在视频输入中保持静止。我怎么能这样做OpenCV使用OpenCV进行视频稳定

即例如,如果我有两个图像prev_frame和next_frame,我该如何转换next_frame因此摄像机显示为静止?

回答

32

我可以建议如下解决方案中的一种:

  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,请参阅关于公式和解释的链接维基百科文章。

编辑 三的言论,我应该更好地明确提及,以防万一:

  1. 单应为基础的方法可能是非常精确的,所以静止的物体将保持静止。然而,单应包括透视失真和变焦,所以结果可能看起来有点不平常(甚至在某些快速移动时会失真)。虽然确切,但这可能不太视觉愉悦;所以把它用于进一步处理或者像取证。但是你应该尝试一下,对于一些场景/动作也可以是超级喜欢的。
  2. 据我所知,至少有几个免费的视频稳定工具使用相位相关。如果你只是想“摇动”相机,这可能是更好的选择。
  3. 在这个领域有相当多的研究正在进行。在一些论文中你会发现一些更复杂的方法(尽管它们可能需要的不仅仅是OpenCV)。
+0

伟大的答案!一个不错的清单。我不知道相位相关。谢谢 ! – 2012-06-01 12:00:49

3

这是一个棘手的问题,但我可以建议一个有点简单的情况我的头顶。任意量

  • 使用背景减除threshold(abs(prev_frame-next_frame_rotated))

    1. 移动/旋转next_frame找到静态元素。你必须玩弄使用什么样的阈值。
    2. 查找min(template_match(prev_frame_background, next_frame_rotated_background))
    3. 记录位移/最接近的匹配的旋转,并把它应用到next_frame

    这将不能很好的为多帧随着时间的工作,所以你要考虑使用background accumulator所以算法查找的背景是相似的。

  • 2

    我要添加下面的注释来完成zerm's answer。 如果选择了一个静止物体,然后用zerm的方法(1)处理该单个物体,它将简化您的问题。 如果您发现一个静止的物体并对其进行修正,我认为假设其他静止的物体也会保持稳定是安全的。

    虽然它肯定是有效的为您的难题,你将有以下的问题这种方法:

    • 检测和单应估计有时会失败的各种原因:闭塞,突然的动作,运动模糊,严重的照明差异。你将不得不寻找方法来处理它。

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

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

    14

    OpenCV的功能estimateRigidTransform()和warpAffine(),它处理这样的问题非常好。

    它非常简单,如下:

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

    现在output包含frame2是最好的排列以适应frame1内容。 对于大型移位,M将是一个零矩阵,或者根本不是矩阵,这取决于OpenCV的版本,因此您必须对其进行过滤,而不应用它们。我不确定这有多大;可能是框架宽度的一半,也许更多。

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

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

    这里是链接到estimateRigidTransform()更多信息,与warpAffine()

    +0

    什么库是'Size'方法中的? – user3731622 2018-01-05 20:03:55

    2

    这已经是很好的答案,但它有点用旧的算法和我公司开发的程序来解决类似的问题,所以我添加额外的答案。

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

    我过去了我的回答。 How to stabilize Webcam video?


    昨天我只是做了一些工作(在Python)关于这个问题,主要步骤是:

    1. 使用cv2.goodFeaturesToTrack找到好的角落。使用cv2.calcOpticalFlowPyrLK来追踪角落。
    2. 使用cv2.findHomography来计算单应性矩阵。
    3. 使用cv2.warpPerspective来转换视频帧。

    但现在结果不是那么理想,可能是我应该选择而不是goodFeatures


    来源:

    enter image description here

    稳定汽车:

    enter image description here