优化相机参数和计算错误 - OpenCV

时间:2016-08-09 23:27:37

标签: c++ opencv

我一直试图用CvLevMarq来改进我的相机参数,但在阅读之后,它似乎导致了混合的结果 - 这正是我所经历的。我阅读了有关替代方案的内容,并发现EIGEN - 并且还发现了this library使用它。

但是,上面的库似乎使用了不支持OpenCV的拼接类,可能需要我将其移植到OpenCV

在继续这样做之前,这可能不是一件容易的事,我想我先问一下,看看是否有其他人有同样的问题?

我目前正在使用:

1。使用FASTFeatureDetector

计算功能
Ptr<FeatureDetector> detector = new FastFeatureDetector(5,true);
detector->detect(firstGreyImage, features_global[firstImageIndex].keypoints); // Previous picture
detector->detect(secondGreyImage, features_global[secondImageIndex].keypoints); // New picture

2. 使用SIFTDescriptorExtractor

提取功能
Ptr<SiftDescriptorExtractor> extractor = new SiftDescriptorExtractor();
extractor->compute(firstGreyImage, features_global[firstImageIndex].keypoints, features_global[firstImageIndex].descriptors); // Previous Picture
extractor->compute(secondGreyImage, features_global[secondImageIndex].keypoints, features_global[secondImageIndex].descriptors); // New Picture

3. BestOf2NearestMatcher

匹配的功能
vector<MatchesInfo> pairwise_matches;
BestOf2NearestMatcher matcher(try_use_gpu, 0.50f);
matcher(features_global, pairwise_matches);
matcher.collectGarbage();

4。 CameraParams.R四元数从设备传递(稍微不准确导致问题)

5。 CameraParams.Focal == 389.0f - 使用此值,389.0f是唯一一个水平匹配但不垂直匹配图像的值。

6。 Bundle AdjustmentcvLevMarqcalcError&amp; calcJacobian

Ptr<BPRefiner> adjuster = new BPRefiner();
adjuster->setConfThresh(0.80f);
adjuster->setMaxIterations(5);
(*adjuster)(features,pairwise_matches,cameras);

7。 ExposureCompensator(GAIN)

8。:OpenCV MultiBand Blender

到目前为止有效:

  • SeamFinder - 在某种程度上有效,但它取决于cvLevMarq算法的结果。即如果算法关闭,seamFinder也将关闭。

  • HomographyBasedEstimator效果很好。但是,因为它依赖&#34;关于这些功能,很遗憾不是我正在寻找的方法。

我不想依赖这些功能,因为我已经拥有了矩阵,如果有办法改进&#34;相反,当前的矩阵 - 那将是目标结果。

到目前为止的结果:

cvLevMarq&#34;俄罗斯轮盘赌&#34; 6/10:

这就是我试图达到10/10次的目标。但是4/10次,看起来就像这张照片下面的图片。

enter image description here

只需重新运行算法,结果就会发生变化。 4/10次看起来像这样(或更糟):

cvLevMarq&#34;俄罗斯轮盘赌&#34; 4/10:

enter image description here

期望的结果:

我希望&#34;改进&#34;我的相机参数具有我匹配的功能 - 希望图像完美对齐。而不是希望cvLevMarq将为我做(它赢得4/10次)的工作,是否有另一种方法来确保图像对齐?< / p>

更新:

我已尝试过这些版本:

OpenCV 3.1:在3.1中使用CVLevMarq就像玩俄罗斯轮盘赌一样。有时它可以完美地对齐它们,有时候它会将焦点估计为NAN,从而导致MultiBand Blender中的段错误(由于NAN,ROI = 0,0,1,1)

OpenCV 2.4.9 / 2.4.13:遗憾的是,将CvLevMarq与2.4.9或2.4.13一起使用会减去NAN问题。 6/10倍它可以完美地对齐图像,但另外4倍完全关闭。

我的猜测/想法:

  • Template Matching使用OpenCV。也许如果我模板匹配图像的末端(即x = 0,y = 0,高度= image.height,宽度= 50)。对此有何想法?

  • 我发现this有趣的论文关于Levenberg Marquardt应用于Homography。这看起来像是可以解决我的问题的东西,因为该论文使用角点检测和诸如此类来检测图像中的特征。对此有何想法?

  • 问题可能不在CvLevMarq,而在于BestOf2NearestMatcher?但是,我已经搜索了几天,而且我找不到另一种方法来返回成对匹配以传递给BPRefiner

  • Hough Line Transform检测第一张/第二张图像中的线条并使用它来对齐图像。有什么想法吗? - 有一件事可能是,如果图像没有任何线条怎么办?即空墙?

  • 也许我过度使用这么简单的东西......或者我可能不是吗?基本上,我试图对齐一组图像,这样我就可以扭曲它们而不会相互重叠。如果没有意义,请发表评论:)

8月12日更新:

尝试各种组合后,到目前为止绝对最佳的是CvLevMarq。唯一的问题是上图中显示的混合结果。如果有人有任何意见,我将永远感激。

3 个答案:

答案 0 :(得分:1)

看来你的参数初始化是个问题。我首先使用线性估计器,即忽略你的噪声传感器,然后用它作为非线性优化器的初始值。

快速方法是使用getaffinetransform,因为您主要是轮换。

答案 1 :(得分:1)

也许你想看看这个图书馆:fillna

干杯

答案 2 :(得分:1)

如果要拼接图像,则应该看到stitching_detailed.cpp。它可能会解决你的问题。

此外,我使用了带有Canny边缘检测的Graph Cut Seam Finding方法,以便在此代码中获得更好的拼接结果。如果您想优化此代码,请参阅here

另外,如果您打算将它用于个人用途,SIFT是好的。您应该知道,SIFT已获得专利,如果您将其用于商业用途,则需要付费。请改用ORB。

希望它有所帮助!