OpenCV findEssentialMat()返回不正确的基本矩阵

时间:2019-07-05 19:14:23

标签: computer-vision opencv3.0

我遇到cv :: findEssentialMat()问题,有时返回不正确的基本矩阵。我发现,对于从图像对生成的一组特定的点对应关系,这些对应关系的某些子集(包括整个子集)与OpenCV的五点算法收敛到与正确解决方案截然不同的解决方案。之所以奇怪,是因为每个点的对应都非常相似。换句话说,没有异常值。

查看附件图像,该图像可视化要素如何从先前图像移动到当前图像。蓝色圆圈表示该特征在当前图像中的位置,绿色圆圈表示该特征在前一图像中的位置,红线表示对应关系。所有功能对应关系在相机如何在图像之间移动方面都是一致的。

enter image description here

这是我已经尝试过但没有成功的东西:

  • 将prob参数从0.999增加到0.999999。
  • 将方法从RANSAC更改为LMEDS

我也尝试过运行带有点对应关系子集的cv :: findEssentialMat()。这很有趣,因为某些子集的确会生成正确的基本矩阵,该矩阵是对以下正确转换进行编码的基本矩阵: t〜= [-1 0 0],

但是当使用整套的点对应关系时,我得到这个错误的翻译 t〜= [0 0 -1]

下面是一个最小的工作示例(cpp文件,cmake文件和yaml文件),演示了此问题。只需将程序运行为

./test <numFeaturesToUse>

例如,运行

./test 11 

查看cv :: findEssentialMat何时正常运行并运行

的示例
./test 12 

以查看未收敛到正确解决方案的示例。 如果有人能指出我做错了什么(如果有的话),将不胜感激!

test.cc

#include <opencv2/calib3d.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>

#include <iostream>


typedef std::vector<cv::Point2f> points;

using namespace std;

int main(int argc, char *argv[]) {
    if (argc != 2)
    {
        cout << "Usage: test.cc numFeaturesToUse" << endl;
        return 0;
    }

    int numFeaturesToUse = std::atoi(argv[1]); 


    // load features as cv::Mats
    cv::FileStorage inFile("../features.yaml", cv::FileStorage::READ);
    cv::Mat featuresRight_, featuresLeft_;

    inFile["featuresRight"] >> featuresRight_;

    bool loadFeaturesLeft = true;

    if (loadFeaturesLeft)
        inFile["featuresLeft"] >> featuresLeft_;
    else
    {
        // each feature in left image should be right feature shifted
        // to the right by 100 pixels. This always gets the correct
        // answer
        featuresLeft_ = featuresRight_.clone();

        cv::MatIterator_<cv::Vec2f> featRightIt = featuresRight_.begin<cv::Vec2f>();
        cv::MatIterator_<cv::Vec2f> featLeftIt = featuresLeft_.begin<cv::Vec2f>();
        while (featRightIt != featuresRight_.end<cv::Vec2f>())
        {
            (*featLeftIt)[0] += 100;
            (*featLeftIt)[1] += -1;

            featRightIt++;
            featLeftIt++;
        }
    }

    bool useSubset = true;
    if (useSubset)
    {        
        int startRow = 20;
        cv::Rect roi(0,startRow,1,numFeaturesToUse); // only use N rows of points starting at 
        featuresRight_ = featuresRight_(roi);
        featuresLeft_ = featuresLeft_(roi);
    }

    // perturb the feature (# 12) that is causing the problem
    // manually assign this feature to be shifted version of right feature
    // featuresLeft_.at<cv::Vec2f>(11)[0] += 1;
    // featuresLeft_.at<cv::Vec2f>(11)[1] += 1;

    // featuresRight_.at<cv::Vec2f>(11)[0] += -100;
    // featuresRight_.at<cv::Vec2f>(11)[1] += -400;
    //  featuresRight_.at<cv::Vec2f>(11)[0] = 400.0;
    //  featuresRight_.at<cv::Vec2f>(11)[1] = 400.0;

    // featuresLeft_.at<cv::Vec2f>(11)[0] = featuresRight_.at<cv::Vec2f>(11)[0] + 120;
    // featuresLeft_.at<cv::Vec2f>(11)[1] = featuresRight_.at<cv::Vec2f>(11)[1] - 5;

    double dsFactor = 0.7;

    cout << "Features right \n" << featuresRight_*dsFactor << "\n";
    cout << "Features left \n" << featuresLeft_*dsFactor << "\n";

    // draw the locations of left and right features on a mat
    // left - blue
    // right - gold
    cv::Mat image = cv::imread("../DJI_0396.JPG");
    cv::rotate(image, image, cv::ROTATE_90_COUNTERCLOCKWISE);

    cv::Scalar blue(255,0,0);
    cv::Scalar green(0,255,0);
    cv::Scalar red(0,0,255);

    cv::MatIterator_<cv::Vec2f> featRightIt = featuresRight_.begin<cv::Vec2f>();
    cv::MatIterator_<cv::Vec2f> featLeftIt = featuresLeft_.begin<cv::Vec2f>();
    while(featLeftIt != featuresLeft_.end<cv::Vec2f>())
    {
        cv::Point2f featureLeft(*featLeftIt);
        cv::Point2f featureRight(*featRightIt);
        cv::circle(image, featureLeft, 4, blue, -1); 
        cv::circle(image, featureRight, 4, green, -1); // green
        cv::line(
            image,                        // Draw onto this image
            featureLeft,                 // Starting here
            featureRight,                 // Ending here
            red,       // This color
            1,                           // This many pixels wide
            cv::LINE_AA                  // Draw line in this style
            );

        featLeftIt++;
        featRightIt++;
    }

    cv::resize(image, image, cv::Size(), dsFactor, dsFactor);
    cv::imshow("features", image);


    // assign camera matrix
    cv::Mat cameraMatrix = (cv::Mat_<double>(3,3) << 1082.77717353143, 0, 690.835449448,
                            0,  1082.77717353143, 457.750756458,
                            0, 0, 1 );

    bool rotate = true;
    if (rotate)
    {
        double fx,fy,cx,cy;
        fx = cameraMatrix.at<double>(0,0);
        fy = cameraMatrix.at<double>(1,1);
        cx = cameraMatrix.at<double>(0,2);
        cy = cameraMatrix.at<double>(1,2);
        cameraMatrix.at<double>(0,0) = fy; 
        cameraMatrix.at<double>(1,1) = fx;
        cameraMatrix.at<double>(0,2) = cy;
        cameraMatrix.at<double>(1,2) = cx;
    }

    cout << "camera matrix = " << cameraMatrix << "\n";
    assert(featuresLeft_.size() == featuresRight_.size());

    // findEssentialMat() settings 
    double prob = 0.999;
    //int method = cv::RANSAC;
    int method = cv::LMEDS;
    //double threshold = 0.1;

    cv::Mat E = cv::findEssentialMat(featuresLeft_, featuresRight_, cameraMatrix,
                                     method, prob);

    int totalFeatures = featuresLeft_.rows;

    cout << "StereoRig::EstimatePose: Essential matrix = \n" << E << endl;
    cv::Mat R_, translation_;
    int numInliers = cv::recoverPose(E, featuresLeft_, featuresRight_, cameraMatrix,
                                     R_, translation_); // outputs

    cout << "StereoRig::EstimatePose: Number of inliers = " << numInliers << " out of " << totalFeatures << " total features" << endl;

    double percentageInliers = (double) numInliers / totalFeatures;
    double thresh = 0.6;
    if (percentageInliers < thresh)
    {
        cout << "StereoRig::EstimatePose When estimating pose from feature correspondences, percentage of inliers ("
             << percentageInliers <<") was under the threshold ("<< thresh<<")." << endl;

    }

    cout << "Estimated translation = " << "\n";
    cout << translation_ << "\n";

    cv::waitKey(0);
    return 0; }

CMakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
set (CMAKE_CXX_STANDARD 14)
project(test)

# link to opencv build (only look for OpenCV3 not OpenCV2)
find_package( OpenCV 3 REQUIRED)

add_executable (test test.cc)
target_link_libraries (test ${OpenCV_LIBS})

features.yaml

%YAML:1.0
---
featuresLeft: !!opencv-matrix
   rows: 92
   cols: 1
   dt: "2f"
   data: [ 1.28847961e+02, 6.49093262e+02, 1.42563141e+02,
       6.48662964e+02, 8.19481445e+02, 1.19142212e+03, 7.20055664e+02,
       4.70487366e+02, 6.43603821e+02, 3.42356812e+02, 5.35456360e+02,
       5.23236694e+02, 1.42560211e+02, 6.48661682e+02, 4.50164185e+02,
       9.40511475e+02, 2.87309570e+02, 6.84542358e+02, 8.62315247e+02,
       1.20464592e+02, 6.15708496e+02, 2.43555664e+02, 1.30746323e+02,
       5.13080139e+02, 8.99102722e+02, 4.01146759e+02, 8.82642578e+02,
       4.15881439e+02, 5.71643616e+02, 2.78483398e+02, 6.49876892e+02,
       2.69117401e+02, 7.08090027e+02, 6.62893860e+02, 5.65718994e+02,
       4.85427002e+02, 6.91666748e+02, 7.81757141e+02, 4.73872772e+02,
       5.82393555e+02, 5.19562012e+02, 6.72122650e+01, 4.00382660e+02,
       2.22377808e+02, 5.84533264e+02, 5.59183533e+02, 8.66378845e+02,
       1.05224136e+02, 5.85873657e+02, 5.71247131e+02, 7.27359497e+02,
       5.70056396e+02, 4.35397614e+02, 5.80546875e+02, 6.60823730e+02,
       4.31280060e+02, 5.46277710e+02, 3.12825623e+02, 2.92994354e+02,
       6.69804443e+02, 3.80915070e+02, 8.45184326e+02, 5.54122681e+02,
       1.02158447e+03, 6.66822388e+02, 7.47606018e+02, 7.38320923e+02,
       8.25927917e+02, 4.38703217e+02, 1.87555298e+02, 5.21265625e+02,
       5.94745789e+02, 6.46222351e+02, 4.89565552e+02, 1.63613831e+02,
       4.85208130e+02, 6.58010864e+02, 9.67679749e+02, 6.48694763e+02,
       2.37516983e+02, 6.74387329e+02, 4.45746124e+02, 5.88605774e+02,
       5.35999390e+02, 6.20808105e+02, 2.63286713e+02, 3.44368896e+02,
       6.16288696e+02, 8.03049561e+02, 4.34126892e+02, 2.15325211e+02,
       6.25899841e+02, 3.06916382e+02, 4.56520416e+02, 4.95614868e+02,
       2.08671097e+02, 5.04676971e+02, 2.67499878e+02, 8.04450867e+02,
       2.89448669e+02, 4.97309570e+02, 9.19511292e+02, 5.60559875e+02,
       2.56943237e+02, 7.97375488e+02, 6.35597107e+02, 6.99451233e+02,
       5.04297241e+02, 5.86292419e+02, 3.40532043e+02, 2.91096863e+02,
       4.45543365e+02, 5.34794312e+02, 2.45132690e+02, 5.37259827e+02,
       1.69906967e+02, 4.61131104e+02, 9.09794434e+02, 5.24697693e+02,
       6.23089355e+02, 6.93494690e+02, 4.19500031e+02, 7.04664429e+02,
       2.68480499e+02, 5.59323608e+02, 8.14105797e+00, 7.20533752e+02,
       3.91805969e+02, 5.85539246e+02, 5.59671936e+02, 1.54184204e+02,
       5.36592224e+02, 5.88363586e+02, 5.00129486e+02, 8.33527039e+02,
       2.55457306e+01, 8.96319885e+02, 2.84405151e+02, 8.60649292e+02,
       4.74958618e+02, 5.79110352e+02, 5.90250793e+02, 7.92708252e+02,
       1.42511322e+02, 8.60564697e+02, 4.74950104e+02, 6.75626709e+02,
       3.95321686e+02, 6.55555237e+02, 9.86767151e+02, 4.55710693e+02,
       2.07409485e+02, 3.31513824e+02, 5.55117981e+02, 7.90092773e+02,
       4.63523285e+02, 1.76062378e+02, 6.18713623e+02, 6.79687073e+02,
       4.40630096e+02, 2.76415710e+02, 7.01047546e+02, 6.20903625e+02,
       8.57159729e+02, 5.22285217e+02, 5.58501221e+02, 3.54970581e+02,
       5.74421875e+02, 4.79196747e+02, 6.09657288e+02, 8.84093750e+02,
       1.07693872e+03, 6.33823853e+02, 8.33315430e+02, 2.37912460e+02,
       4.43286407e+02, 6.88389404e+02, 4.36370270e+02, 8.40665222e+02,
       3.36497498e+02, 1.77658432e+02, 5.66718872e+02, 7.55319702e+02,
       7.37769318e+00 ]
featuresRight: !!opencv-matrix
   rows: 92
   cols: 1
   dt: "2f"
   data: [ 3.48587513e+00, 6.54300903e+02, 2.16347313e+01,
       6.53776978e+02, 6.97840149e+02, 1.19988525e+03, 5.98826782e+02,
       4.76740784e+02, 5.22565491e+02, 3.47719086e+02, 4.13773651e+02,
       5.28816528e+02, 2.16297665e+01, 6.53775146e+02, 3.28051147e+02,
       9.46521362e+02, 1.65979507e+02, 6.89732117e+02, 7.42543884e+02,
       1.25529305e+02, 4.94935944e+02, 2.49277206e+02, 1.01769810e+01,
       5.18613708e+02, 7.78789978e+02, 4.06911591e+02, 7.62147339e+02,
       4.21893127e+02, 4.50675201e+02, 2.84116882e+02, 5.28738892e+02,
       2.74634521e+02, 5.86458496e+02, 6.69662903e+02, 4.44102234e+02,
       4.91375946e+02, 5.69598328e+02, 7.88479553e+02, 3.52315247e+02,
       5.88038025e+02, 3.99272858e+02, 7.24335175e+01, 2.79831665e+02,
       2.27995819e+02, 4.62965271e+02, 5.65336975e+02, 747., 110., 464.,
       577., 6.05831604e+02, 5.76349426e+02, 3.13826538e+02,
       5.86211914e+02, 5.39379211e+02, 4.37007294e+02, 4.25307678e+02,
       3.18409332e+02, 1.71548569e+02, 6.75439392e+02, 2.59090179e+02,
       8.50806824e+02, 4.32000031e+02, 1.02846155e+03, 5.44752502e+02,
       7.53849792e+02, 6.16563049e+02, 8.33063477e+02, 3.18476013e+02,
       1.92946686e+02, 3.99383270e+02, 6.00583191e+02, 5.24528076e+02,
       4.95570587e+02, 4.31030235e+01, 4.90446259e+02, 5.36113647e+02,
       9.74736084e+02, 5.28095642e+02, 2.43140930e+02, 5.53183777e+02,
       4.52007416e+02, 4.66995789e+02, 5.41647949e+02, 4.99978821e+02,
       2.68422241e+02, 223., 622., 6.82151550e+02, 4.39999298e+02,
       9.44022217e+01, 6.31038269e+02, 186., 462., 3.75099762e+02,
       2.14107742e+02, 3.83958862e+02, 2.73195770e+02, 6.83860474e+02,
       2.95132202e+02, 3.75323700e+02, 9.25819702e+02, 4.40014893e+02,
       2.62267639e+02, 6.75859680e+02, 6.42131897e+02, 5.78106018e+02,
       5.10620270e+02, 4.65280518e+02, 3.46075043e+02, 1.70320724e+02,
       4.50776031e+02, 4.13994263e+02, 2.50434418e+02, 417., 175.,
       3.39066467e+02, 9.16131042e+02, 4.02902557e+02, 6.29403015e+02,
       5.72313904e+02, 4.25308411e+02, 5.84261230e+02, 2.73812378e+02,
       4.39524597e+02, 1.32251701e+01, 5.99402161e+02, 3.97848175e+02,
       4.63748627e+02, 5.65522583e+02, 3.37356911e+01, 5.41680481e+02,
       4.66630371e+02, 5.05906525e+02, 714., 30., 7.76105896e+02,
       2.89903259e+02, 7.40108154e+02, 4.80904846e+02, 4.57319580e+02,
       5.96026062e+02, 673., 148., 7.40087891e+02, 4.81301239e+02,
       5.54387695e+02, 4.01024597e+02, 5.33782959e+02, 9.94106750e+02,
       3.35050629e+02, 2.12548187e+02, 2.10056046e+02, 5.60611633e+02,
       6.69055542e+02, 4.69386414e+02, 5.54003754e+01, 6.23763367e+02,
       5.58282837e+02, 4.46638702e+02, 1.54980133e+02, 7.06359802e+02,
       4.98765839e+02, 8.63861084e+02, 4.00624634e+02, 5.64329407e+02,
       2.33481201e+02, 5.79876953e+02, 3.57501984e+02, 6.15616211e+02,
       7.62703003e+02, 1.08548193e+03, 5.11708618e+02, 8.40311646e+02,
       1.17268921e+02, 4.48423584e+02, 5.66531982e+02, 4.42379242e+02,
       7.20351318e+02, 3.42316284e+02, 57., 572., 6.35811890e+02,
       1.21897068e+01 ]

0 个答案:

没有答案