Opencv - 如何区分抖动和平移?
Posted
技术标签:
【中文标题】Opencv - 如何区分抖动和平移?【英文标题】:Opencv - How to differentiate jitter from panning? 【发布时间】:2013-06-13 14:01:53 【问题描述】:我正在使用 C++ 中的 Opencv 开发视频稳定器。
在项目的这个时候,我能够正确地找到两个连续帧之间的转换,使用 3 种不同的技术(光流、相位相关、兴趣点上的 BFMatcher)。
为了获得稳定的图像,我将所有平移向量(从连续帧)加到一个,用于warpAffine
函数以校正输出图像。
我在固定摄像头上的效果很好,但在平移摄像头上的效果非常糟糕:图像从屏幕上消失了。
我认为我必须将我想要移除的抖动运动与我想要保留的平移运动区分开来。但我对其他解决方案持开放态度。
【问题讨论】:
【参考方案1】:实际上,整个问题比您一开始所想的要复杂一些。让我们这样看:当您在世界中移动相机时,靠近相机的物体移动得比背景中的物体移动得更快 - 因此不同深度的物体会改变它们的相对距离(移动头部时查看取景器看看它如何指向不同的东西)。这意味着图像实际上会发生变换,而不仅仅是平移(在 x 或 y 中移动)——那么你想如何补偿呢?您需要做的是推断相机移动了多少(沿 x、y 和 z 平移)和旋转了多少(偏航、平移和倾斜角度)。这不是一个非常简单的任务,但是 openCV 附带了一个非常好的包:http://opencv.willowgarage.com/documentation/camera_calibration_and_3d_reconstruction.html
所以我建议你尽可能多地阅读 Homography(http://en.wikipedia.org/wiki/Homography)、相机模型和校准,然后想想你真正想要稳定什么,如果它只是旋转角度,任务就简单多了如果您还想稳定平移抖动。
如果您不想花哨而忽略三维,我建议您平均光流,对其进行高通滤波,并通过将图像平移到相反方向来补偿这种运动。这将使您的图像或多或少保持在帧的中间,并且只会抵消小而快的变化。
【讨论】:
【参考方案2】:我会建议您可能的方法(按复杂性顺序):
在应用稳定之前,在平移向量上应用一些易于实现的 IIR 低通滤波器。这会将高频(抖动)与低频(平移)分开 同样的想法,稍微复杂一点,使用卡尔曼滤波来跟踪具有恒定速度或加速度的运动。为此,您可以使用 OpenCV 的卡尔曼滤波器。 有点棘手,在运动幅度上设置一个阈值以决定两种状态(移动与静态相机)之间并过滤平移与否。 最后,您可以使用机器学习中的一些精细技术来尝试识别用户所需的运动(静态、平移等)并过滤或不过滤用于稳定的运动矢量。只是一个阈值不是低通滤波器。 可能的低通滤波器(易于实现):
有众所周知的平均,它已经是一个低通滤波器,其截止频率取决于进入平均方程的样本数量(样本越多,截止频率越低)。 一种常用的过滤器是指数过滤器(因为它会以指数速率衰减忘记过去)。它被简单地计算为x_filt(k) = a*x_nofilt(k) + (1-a)x_filt(k-1)
和0 <= a <= 1
。
另一个流行的过滤器(可以超过 1 阶计算)是 Butterworth filter。
等Low pass filters on Wikipedia、IIR filters...
【讨论】:
感谢您的快速答复。你能告诉我更多关于第一种方法的信息吗?一个简单的ìf
足以制作一个低通滤波器吗?这就是我尝试过的。以上是关于Opencv - 如何区分抖动和平移?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 中将 OpenCV 旋转和平移矢量与 OpenGL ES 一起使用?