我正在创建一个稳定视频流的程序。目前,我的程序基于相位相关算法工作。我计算两个图像之间的偏移 - 基础和当前。接下来,我根据新坐标校正当前图像。这个程序有效,但效果不理想。相关链接您可能会发现处理后的视频显得不受欢迎,并且震动整个视频的情况变得更糟
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和基于角点检测的算法似乎很有吸引力,但我并不完全清楚它是如何工作的。
所以我的问题是如何有效地解决这个问题。
其中一个条件 - 程序将在较慢的计算机上运行,因此繁重的算法可能不合适
谢谢!
附:
我为文中的任何错误道歉 - 这是一种自动翻译。
答案 0 :(得分:2)
您可以在每个帧中使用SIFT等图像描述符,并在帧之间计算robust matches。然后,您可以计算帧之间的homography并使用它来对齐它们。与使用密集关联相比,使用稀疏特征可以实现更快的实现。
或者,如果您知道camera parameters可以calculate 3D positions点和相机,并将图像重新投影到稳定的投影平面上。在结果中,您还获得了场景的sparse 3D reconstruction(有些不精确,通常需要optimized才能使用)。这就是例如Autostitch会这样做,但实施起来却相当困难。
请注意,相机参数也可以是calculated,但这更加困难。
答案 1 :(得分: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等平滑变换参数集。