opencv与eigen做svd的一些区别。

主要想用eigen 的svd替换opencv的svd结果发现点问题。记录一下防止忘了吧。

第一个例子 。row大于col 两组V结果是一致的。大小为5*5

      int row = 9;
        int col = 5;
        std::vector> vec{ 
        { 0.68f, 0.597f, 1 ,4,5},
        { -0.211f, 0.823f , 2, 0.68f, 0.597f},
        { 0.566f, -0.605f, 3, 0.68f, 0.597f},
        { 0.566f, -0.65f , 3, 0.68f, 0.597f},
        { 0.566f, -0.05f ,2, 0.68f, 0.597f},
        { 0.7566f, -0.705f ,1, 0.68f, 0.597f},
        { 0.5f, -0.605f, 0, 0.68f, 0.597f },
        { 0.156f, -0.405f, 4 , 0.68f, 0.597f},
        { 0.25f, -0.305f, 3, 0.68f, 0.597f }
        };

        cv::Mat mat(row, col, CV_64FC1);
        for (int y = 0; y < row; ++y) {
            for (int x = 0; x < col; ++x) {
                mat.at(y, x) = vec.at(y).at(x);
            }
        }
        cv::Mat w, u, vt, v;
        cv::SVD::compute(mat, w, u, vt, 4);
        cout << "vt opecv = " << endl << vt.t() << endl;

    //    Mat EE = Mat(vt.t()).colRange(row, col) * 1.0;

    //    cout << "EE OPENCV = " << endl << EE << endl << endl;

        MatrixXd ddd = Eigen::MatrixXd::Zero(row, col);
        int cha = Q.channels();
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                ddd(i, j) = mat.at(i, j);
            }
        }

        JacobiSVD svd(ddd, ComputeThinU | ComputeThinV);
        MatrixXd U1, S1, V1;
        VectorXd vS = svd.singularValues();
        U1 = svd.matrixU();
        V1 = svd.matrixV();
        cout << "V1 eigen = " << endl << V1 << endl << endl;

 

输出:自己跑程序看一眼吧 不爱贴图了。

改为 row小于col 结果就有很大不同了。首先opencv的结果V是一个9*9的数组。eigen结果是9*5的数组

并且 opencv的V结果的转置的前5列就是eigen求得的V数组

int row = 5;
        int col = 9;
        std::vector> vec{ 
        { 0.68f, 0.597f, 1 ,4,5},
        { -0.211f, 0.823f , 2, 0.68f, 0.597f},
        { 0.566f, -0.605f, 3, 0.68f, 0.597f},
        { 0.566f, -0.65f , 3, 0.68f, 0.597f},
        { 0.566f, -0.05f ,2, 0.68f, 0.597f},
        { 0.7566f, -0.705f ,1, 0.68f, 0.597f},
        { 0.5f, -0.605f, 0, 0.68f, 0.597f },
        { 0.156f, -0.405f, 4 , 0.68f, 0.597f},
        { 0.25f, -0.305f, 3, 0.68f, 0.597f }
        };

        cv::Mat mat(row, col, CV_64FC1);
        for (int y = 0; y < row; ++y) {
            for (int x = 0; x < col; ++x) {
                mat.at(y, x) = vec.at(x).at();
            }
        }
        cv::Mat w, u, vt, v;
        cv::SVD::compute(mat, w, u, vt, 4);
        cout << "vt opecv = " << endl << vt.t() << endl;

    //    Mat EE = Mat(vt.t()).colRange(row, col) * 1.0;

    //    cout << "EE OPENCV = " << endl << EE << endl << endl;

        MatrixXd ddd = Eigen::MatrixXd::Zero(row, col);
        int cha = Q.channels();
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                ddd(i, j) = mat.at(i, j);
            }
        }

        JacobiSVD svd(ddd, ComputeThinU | ComputeThinV);
        MatrixXd U1, S1, V1;
        VectorXd vS = svd.singularValues();
        U1 = svd.matrixU();
        V1 = svd.matrixV();
        cout << "V1 eigen = " << endl << V1 << endl << endl;

续:查到问题了 对eigen不熟悉啊 ComputeThinU这个值改改就好 改改   但是 转置是逃不掉得了.

再加一个:BDCSVD   eigen一共有两种svd分解方法。一个是JacobiSVD一个是BDCSVD  。用法类似。

你可能感兴趣的:(opencv与eigen做svd的一些区别。)