【OpenCV】笔记(10)——视频稳定处理

时间:2021-06-25 18:36:04
 
视频稳定性
视频超分辨率处理
图像拼接

视频稳定性
#include <opencv2/opencv.hpp>
#include <opencv2/videostab.hpp>

#include <iostream>
#include <string>

using namespace std;
using namespace cv;
using namespace cv::videostab;

void processing(Ptr < IFrameSource>, string outputPath );

int main(int argc,const char ** argv)
{
                 //1           准备输入视频路径
                 //2           建立一个运动估计器
                 //3           建立一个稳定器
                 //4           使用创建的稳定器来稳定视频

                 Ptr<IFrameSource > stabilizedFrames;
                 try
                {
                                 //1-准备输入视频进行检查
                                 string inputPath;
                                 string outputPath;
                                 if (argc >1)
                                {
                                                inputPath = argv [1];
                                }
                                 else
                                {
                                                inputPath = ".\\cube4.avi" ;

                                }

                                 if (argc > 2)
                                                outputPath = argv [2];
                                 else
                                                outputPath = ".\\cube4_stabilized.avi" ;

                                 Ptr<VideoFileSource > source = makePtr<VideoFileSource>(inputPath);
                                cout << "frame cout (rough):" << source->count() << endl;

                                 //准备运动估计器
                                 //首先,准备运动估计生成器
                                 double min_inlier_ratio = 0.1;
                                 Ptr<MotionEstimatorRansacL2> est = makePtr<MotionEstimatorRansacL2>(MM_AFFINE);
                                 RansacParams ransac = est-> ransacParams();

                                ransac.size = 3;
                                ransac.thresh = 5;
                                ransac.eps = 0.5;
                                est ->setRansacParams(ransac);
                                est ->setMinInlierRatio(min_inlier_ratio);

                                 //2                           创建一个特征检查器
                                 int nkps = 1000;
                                 Ptr<GoodFeaturesToTrackDetector > feature_detector = makePtr<GoodFeaturesToTrackDetector >(nkps);

                                 //3           创建运动估计器
                                 Ptr<KeypointBasedMotionEstimator> motionEstBuilder = makePtr<KeypointBasedMotionEstimator>(est);
                                motionEstBuilder ->setDetector(feature_detector);
                                 Ptr<IOutlinerRejector>();
                                motionEstBuilder ->setOutlinerRejector(outlinerRejector);

                                 //准备稳定器
                                 StabilizerBase *stabilizer = 0;

                                 //首先,准备单程或者双程稳定器
                                 bool isTwoPass = 1;
                                 int radius_pass = 15;
                                 if (isTwoPass)
                                {
                                                 //使用双程稳定器
                                                 bool est_trim = true ;

                                                 TwoPassStabilizer *twoPassStabilizer = new TwoPassStabilizer();

                                                twoPassStabilizer->setEstimateTrimRatio(est_trim);
                                                twoPassStabilizer->setMotionStabilizer(makePtr< GaussianMotionFilter>(radius_pass));



                                }
                                 else
                                {
                                                 //使用一个单程稳定器
                                                 OnePassStabilizer *onePassStabilizer = new OnePassStabilizer();
                                                onePassStabilizer->setMotionFilter(makePtr< GaussianMotionFilter>(radius_pass));

                                                stabilizer = onePassStabilizer;
                                }

                                 //第二,设计参数
                                 int radius = 15;
                                 double trim_ratio = 0.1;
                                 bool incl_constr = false ;

                                stabilizer->setFrameSource(source);
                                stabilizer->setMotionEstimator(motionEstBuilder);

                                stabilizer->setRadius(radius);
                                stabilizer->setTrimRatio(trim_ratio);
                                stabilizer->setCorrectionForInclusion(incl_constr);
                                stabilizer->setBorderMode( BORDER_REPLICATE);

                                 //将稳定器赋值给简单框架源接口,以读取稳定帧
                                stabilizedFrames.reset( dynamic_cast<IFrameSource *>(stabilizer));

                                 //处理稳定帧,并显示和保存结果
                                processing(stabilizeFrames, outputPath);


                }

                 catch (const exception &e)
                {
                                cout << "error:" << e.what() << endl;
                                stabilizedFrames.release();
                                 return -1;
                }
                stabilizedFrames.release();
                
                
                 return 0;
}

void processing(Ptr <IFrameSource> stabilizedFrames, string outputPath)
{
                 VideoWriter writer;
                 Mat stabilizedFrame;
                 int nframes = 0;
                 double outputFps = 25;

                 //对于每个稳定帧
                 while (!(stabilizedFrame= stabilizedFrames->nextFrame()).empty())
                {
                                nframes++;

                                 //初始化writer(一次),并保存稳定帧
                                 if (!outputPath .empty())
                                {
                                                 if (!writer.isOpened())
                                                {
                                                                writer.open( outputPath, VideoWriter ::fourcc('X', 'V', 'I', 'D'), outputFps,
                                                                                stabilizedFrame.size ());
                                                                
                                                }
                                                writer << stabilizedFrame;
                                }

                                imshow( "stabilizedFrame", stabilizedFrame);
                                 char key = static_cast <char>(waitKey(3));
                                 if (key==27)
                                {
                                                cout << endl;break ;
                                }

                }
                cout << "processed frames:" << nframes << endl;
                cout << "finished" << endl;
}

未完待续......