5

我正在创建一个程序来稳定视频流。目前,我的程序基于相位相关算法工作。我正在计算两个图像之间的偏移量 - 基本图像和当前图像。接下来我根据新坐标校正当前图像。该程序有效,但结果并不令人满意。相关链接您可能会发现处理后的视频看起来不受欢迎,并且整个视频的抖动变得更糟。
Orininal video
Unshaked video
有我目前的实现:
计算图像之间的偏移量:

Point2d calculate_offset_phase_optimized(Mat one, Mat& two) {

  if(two.type() != CV_64F) {
    cvtColor(two, two, CV_BGR2GRAY);
    two.convertTo(two, CV_64F);
  }

  cvtColor(one, one, CV_BGR2GRAY);
  one.convertTo(one, CV_64F);

  return phaseCorrelate(one, two);

}

根据此坐标移动图像:

void move_image_roi_alt(Mat& img, Mat& trans, const Point2d& offset) {

  trans = Mat::zeros(img.size(), img.type());
  img(
    Rect(
        _0(static_cast<int>(offset.x)),
        _0(static_cast<int>(offset.y)),
        img.cols-abs(static_cast<int>(offset.x)),
        img.rows-abs(static_cast<int>(offset.y))
    )
  ).copyTo(trans(
    Rect(
        _0ia(static_cast<int>(offset.x)),
        _0ia(static_cast<int>(offset.y)),
        img.cols-abs(static_cast<int>(offset.x)), 
        img.rows-abs(static_cast<int>(offset.y))
    )   
  )); 
}

int _0(const int x) {
  return x < 0 ? 0 : x;
}

int _0ia(const int x) {
  return x < 0 ? abs(x) : 0;
}

我正在查看文档作者稳定器 YouTube 和基于角点检测的算法似乎很有吸引力,但我并不完全清楚它是如何工作的。所以我的问题是如何有效地解决这个问题。条件之一 - 程序将在较慢的计算机上运行,​​因此可能不适合繁重的算法。
谢谢!
PS 对于文本中的任何错误,我深表歉意 - 这是自动翻译。

4

2 回答 2

3

您可以在每一帧中使用图像描述符(例如SIFT )并计算帧之间的稳健 匹配。然后您可以计算帧之间的单应性并使用它来对齐它们。使用稀疏特征可以比使用密集相关更快地实现。

或者,如果您知道相机参数,您可以计算点和相机的 3D 位置,并将图像重新投影到稳定的投影平面上。结果,您还获得了场景的稀疏 3D 重建(有些不精确,通常需要对其进行优化才能使用)。这就是例如Autostitch会做的事情,但是很难实现。

请注意,相机参数也可以计算,但这更加困难。

于 2014-05-21T07:58:33.750 回答
2

OpenCV 可以用 3 行代码为您完成(绝对是最短的方法,甚至可能是最好的方法):

t = estimateRigidTransform(newFrame, referenceFrame, 0); // 0 means not all transformations (5 of 6)
if(!t.empty()){    
    warpAffine(newFrame, stableFrame, t, Size(newFrame.cols, newFrame.rows)); // stableFrame should be stable now
}

您可以通过修改矩阵 t 来关闭某种变换,这样可以得到更稳定的结果。这只是核心思想,然后您可以按照您想要的方式对其进行修改:更改 referenceFrame、平滑矩阵 t 的转换参数集等。

于 2014-11-02T09:07:31.087 回答