使用opencv稳定视频
Posted
技术标签:
【中文标题】使用opencv稳定视频【英文标题】:video stabilization using opencv 【发布时间】:2014-02-07 08:19:20 【问题描述】:我正在尝试使用 opencv 进行视频稳定(没有 opencv 视频稳定类)。
我的算法步骤如下->
冲浪点提取,
匹配,
单应矩阵,
warpPerspective
并且输出视频根本不稳定:(。它看起来就像原始视频。我找不到视频稳定的参考代码。我按照here 描述的程序进行操作。有人可以告诉我吗?我哪里出错了,或者提供一些源代码链接来改进我的算法。
请帮忙。谢谢
【问题讨论】:
这个问题很模糊,也很宽泛。如果我们能够为您提供帮助,您需要重新措辞并向我们提供更多信息。 【参考方案1】:您可以使用我的代码 sn-p 作为起点(不是很稳定,但似乎可行):
#include "opencv2/opencv.hpp"
#include <iostream>
#include <vector>
#include <stdio.h>
using namespace cv;
using namespace std;
int main(int ac, char** av)
VideoCapture capture(0);
namedWindow("Cam");
namedWindow("Camw");
Mat frame;
Mat frame_edg;
Mat prev_frame;
int k=0;
Mat Transform;
Mat Transform_avg=Mat::eye(2,3,CV_64FC1);
Mat warped;
while(k!=27)
capture >> frame;
cv::cvtColor(frame,frame,cv::COLOR_BGR2GRAY);
cv::equalizeHist(frame,frame);
cv::Canny(frame,frame_edg,64,64);
//frame=frame_edg.clone();
imshow("Cam_e",frame_edg);
imshow("Cam",frame);
if(!prev_frame.empty())
Transform=estimateRigidTransform(frame,prev_frame,0);
Transform(Range(0,2),Range(0,2))=Mat::eye(2,2,CV_64FC1);
Transform_avg+=(Transform-Transform_avg)/2.0;
warpAffine(frame,warped,Transform_avg,Size( frame.cols, frame.rows));
imshow("Camw",warped);
if(prev_frame.empty())
prev_frame=frame.clone();
k=waitKey(20);
cv::destroyAllWindows();
return 0;
您还可以查找论文:Chen_Halawa_Pang_FastVideoStabilization.pdf,因为我记得提供了 MATLAB 源代码。
【讨论】:
您好安德烈感谢您的回复。你能解释一下“Transform(Range(0,2),Range(0,2))=Mat::eye(2,2,CV_64FC1); Transform_avg+=(Transform-Transform_avg)/2.0;" 是什么意思吗?这2行呢?我还看到了 matlab 代码,我正在尝试将其转换为 C++。 变换(Range(0,2),Range(0,2))=Mat::eye(2,2,CV_64FC1); line 丢弃除平移之外的所有变换(旋转、缩放和剪切)。这样做是因为我不需要这种变换补偿,它增加了算法的稳定性。行 Transform_avg+=(Transform-Transform_avg)/2.0;这是变换位移补偿的区别。我记得 1/2 是 mor 鲁棒性的系数(我几年前写过这段代码)它也可以用作低通滤波器。 谢谢安德鲁,非常感谢您的回答。但是你提供的代码片段我的测试视频并没有给出好的结果。无论如何,谢谢。【参考方案2】:在您的“warpAffine(frame,warped,Transform_avg,Size(frame.cols, frame.rows));”中函数,您必须将 FLAG 指定为 WARP_INVERSE_MAP 以实现稳定。
我写的示例代码:
Mat src, prev, curr, rigid_mat, dst;
VideoCapture cap("test_a3.avi");
while (1)
bool bSuccess = cap.read(src);
if (!bSuccess) //if not success, break loop
cout << "Cannot read the frame from video file" << endl;
break;
cvtColor(src, curr, CV_BGR2GRAY);
if (prev.empty())
prev = curr.clone();
rigid_mat = estimateRigidTransform(prev, curr, false);
warpAffine(src, dst, rigid_mat, src.size(), INTER_NEAREST|WARP_INVERSE_MAP, BORDER_CONSTANT);
// ---------------------------------------------------------------------------//
imshow("input", src);
imshow("output", dst);
Mat dst_gray;
cvtColor(dst, dst_gray, CV_BGR2GRAY);
prev = dst_gray.clone();
waitKey(30);
希望这能解决您的问题:)
【讨论】:
【参考方案3】:冲浪不是那么快。我的工作方式是使用光流。首先,您必须使用 GoodFeaturesToTrack() 函数在第一帧上计算好的特征。之后,我使用 FindCornerSubPix() 函数进行了一些优化。
现在您的起始帧中已经有了特征点,接下来您要做的就是确定光流。有几个光流函数,但我使用的是 OpticalFlow.PyrLK(),在其中一个输出参数中,您可以获得当前帧中的特征点。有了它,您可以使用 FindHomography() 函数计算 Homography 矩阵。接下来你要做的是反转这个矩阵,你可以用谷歌很容易找到解释,接下来你调用 WarpPerspective() 函数来稳定你的框架。
PS。我放在这里的函数来自 EmguCV,OpenCV 的 .NET 包装器,所以可能会有一些差异
【讨论】:
以上是关于使用opencv稳定视频的主要内容,如果未能解决你的问题,请参考以下文章