我正在尝试使用 OpenCV 拼接器类从立体设置中拼接多个帧,其中两个相机都不会移动。跨多个帧运行时,我的拼接结果很差。我尝试了几种不同的方法,我将在这里尝试解释。
使用stitcher.stitch( )
给定一对立体视图,我为某些帧运行了以下代码(VideoFile
是 OpenCVVideoCapture
对象的自定义包装器):
VideoFile f1( ... );
VideoFile f2( ... );
cv::Mat output_frame;
cv::Stitcher stitcher = cv::Stitcher::createDefault(true);
for( int i = 0; i < num_frames; i++ ) {
currentFrames.push_back(f1.frame( ));
currentFrames.push_back(f2.frame( ));
stitcher.stitch( currentFrames, output_mat );
// Write output_mat, put it in a named window, etc...
f1.next_frame();
f2.next_frame();
currentFrames.clear();
}
这在每一帧上都给出了非常好的结果,但由于参数是在视频中的每一帧估计的,你可以看到参数略有不同的拼接中的微小差异。
使用estimateTransform( )
&composePanorama( )
为了克服上述方法的问题,我决定尝试仅在第一帧上估计参数,然后使用composePanorama( )
拼接所有后续帧。
for( int i = 0; i < num_frames; i++ ) {
currentFrames.push_back(f1.frame( ));
currentFrames.push_back(f2.frame( ));
if( ! have_transform ) {
status = stitcher.estimateTransform( currentFrames );
}
status = stitcher.composePanorama(currentFrames, output_frame );
// ... as above
}
可悲的是,似乎有一个错误(在此处记录)导致两个视图以一种非常奇怪的方式分开,如下图所示:
第一帧:
第 2 帧:
...
第 8 帧:
composePanorama()
显然这是没用的,但我认为这可能只是因为错误,它基本上每次调用时都会将内在参数矩阵乘以一个常数。所以我对这个错误做了一个小补丁,阻止了这种情况的发生,但是拼接结果很差。补丁下方(modules/stitching/src/stitcher.cpp
),之后的结果:
243 for (size_t i = 0; i < imgs_.size(); ++i)
244 {
245 // Update intrinsics
246 // change following to *=1 to prevent scaling error, but messes up stitching.
247 cameras_[i].focal *= compose_work_aspect;
248 cameras_[i].ppx *= compose_work_aspect;
249 cameras_[i].ppy *= compose_work_aspect;
结果:
有谁知道我该如何解决这个问题?基本上我需要进行一次转换,然后在剩余的帧上使用它(我们正在谈论 30 分钟的视频)。
理想情况下,我正在寻找一些关于修补缝合器类的建议,但我愿意尝试手动编写不同的解决方案。较早的尝试涉及查找 SURF 点、关联它们和查找单应性,与拼接器类相比,结果相当差,所以如果可能的话,我宁愿使用它。