以下3个opencv Mat实例之间有什么区别?

时间:2016-07-04 09:31:12

标签: c++ opencv matrix

在我的程序中,我需要一个3 * 3矩阵K(摄像机校准矩阵)和一个3 * 3矩阵F(基本矩阵)来计算E(基本矩阵):E = Kt() F K,但是当我使用

cv :: Matx33d K(518.0,0325.5,                    0,519.0,253.5,                    0,0,1);

它产生错误:行中的'operator *'不匹配:

E = K.t()* F * K;

但是当我使用

cv::Mat K(3,3,CV_64FC1);      //cannot be 32 (float)
K.at<double>(0,0) = 518.0;
K.at<double>(1,1) = 519.0;
K.at<double>(0,2) = 325.5;
K.at<double>(1,2) = 253.5;
K.at<double>(2,2) = 1;

它有效,但是当我使用

cv::Mat_<double> K = ( cv::Mat_<double>(3, 3) <<
         518.0,    0,325.5,
         0    ,519.0,253.5,
         0    ,    0,    1);

它也有效,但与上面相比产生完全不同的结果

有谁能告诉我3个opencv Mat insatances有什么区别?谢谢。

这是所有代码

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>

using namespace std;
using namespace cv;

int main()
{
    cout<<"Hello SLAM!"<<endl;
    cv::Mat img1,img2,img;


                                                              // first method :can run ,but yeild fault result
    cv::Mat K(3,3,CV_64FC1);      //cannot be 32 (float)
    K.at<double>(0,0) = 518.0;
    K.at<double>(1,1) = 519.0;
    K.at<double>(0,2) = 325.5;
    K.at<double>(1,2) = 253.5;
    K.at<double>(2,2) = 1;


                                                              // second method :cannont build
//    cv::Matx33d K (518.0,    0,325.5,
//                   0    ,519.0,253.5,
//                   0    ,    0,    1);//calibration matrix

//        cv::Matx33d K=cv::Matx33d(518.0,    0,325.5,
//                       0    ,519.0,253.5,
//                       0    ,    0,    1);//calibration matrix

                                                              // third method :can run ,yeild correcy result
    cv::Mat_<double> K = ( cv::Mat_<double>(3, 3) <<
             518.0,    0,325.5,
             0    ,519.0,253.5,
             0    ,    0,    1);


    img1= cv::imread("/home/kylefan/program/cmake_demo/image/rgb1.png",IMREAD_COLOR);
    img2= cv::imread("/home/kylefan/program/cmake_demo/image/rgb2.png",IMREAD_COLOR);

    vector<cv::Point2f> point1;
    vector<cv::Point2f> point2;
    cv::ORB orb;
    vector<cv::KeyPoint>kp1,kp2;
    cv::Mat desp1,desp2;

    orb(img1,cv::Mat(),kp1,desp1,false);
    orb(img2,cv::Mat(),kp2,desp2,false);

    cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("BruteForce-Hamming");

    double knn_match_ratio = 0.3;
    vector< vector<cv::DMatch>> matches_knn;

    matcher->knnMatch(desp1,desp2,matches_knn,2);

    vector<cv::DMatch> goodmatches;

    for(int i=0;i<matches_knn.size();i++)
    {
        if(matches_knn[i][0].distance < knn_match_ratio * matches_knn[i][1].distance)goodmatches.push_back(matches_knn[i][0]);
    }

    if(goodmatches.size()<20)
    {
        cout<<"too less goodmatches "<<endl;
    }

    for(auto m:goodmatches)
    {
        point1.push_back(kp1[m.queryIdx].pt);
        point2.push_back(kp2[m.queryIdx].pt);
    }
//    for(int j=0;j<goodmatches.size();j++)
//    {
//        //cout<<j<<":"<<point1[j].x<<","<<point1[j].y<<","<<point2[j].x<<","<<point2[j].y<<","<<endl;
//    }

    cv::Mat F = cv::findFundamentalMat(point1,point2,FM_RANSAC,3,0.99);//in calib3d

    cv::Mat_<double> E = K.t() *F*  K;

    SVD svd(E);

    cv::Matx33d W(0,-1,0,
                  1,0,0,
                  0,0,1);

    cv::Mat_<double> R = svd.u * Mat(W) * svd.vt;
    cv::Mat_<double> t = svd.u.col(2);

    cv::Matx34d P1(R(0,0),R(0,1),R(0,2),t(0),
                   R(1,0),R(1,1),R(1,2),t(1),
                   R(2,0),R(2,1),R(2,2),t(2));

    cout<<goodmatches.size()<<" goodmatches "<<endl;

    cout<<"F="<<F<<endl;
    cout<<"K="<<K<<endl;
    cout<<"E="<<E<<endl;
    cout<<"R="<<R<<endl;
    cout<<"t="<<t<<endl;
    cout<<"P1="<<P1<<endl;

    if(fabsf(determinant(R))-1.0 > 1e-07)
    {
        cerr << "det(R) != +-1.0, this is not a rotation matrix" << endl;
    }
    else
    {
        cout<<"rotation matrix is right"<<endl;
    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

在你的第二个版本中,你没有初始化矩阵元素,也没有全部设置。

cv::Mat K(3,3,CV_64FC1);      //cannot be 32 (float)
K.at<double>(0,0) = 518.0;
K.at<double>(1,1) = 519.0;
K.at<double>(0,2) = 325.5;
K.at<double>(1,2) = 253.5;
K.at<double>(2,2) = 1;

这意味着索引(0,1)中可以有任何值; (1,0); (2,0)和(2,1)。

要在创建时使用0初始化,请尝试:cv::Mat::zeros()

cv::Mat K = cv::Mat::zeros(3,3,CV_64FC1);      //cannot be 32 (float)
K.at<double>(0,0) = 518.0;
K.at<double>(1,1) = 519.0;
K.at<double>(0,2) = 325.5;
K.at<double>(1,2) = 253.5;
K.at<double>(2,2) = 1;