SVD分解 opencv实现

头文件

#ifndef DEBUG_LRN_SVD_H
#define DEBUG_LRN_SVD_H
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>


using namespace std;
using namespace cv;

int test_SVD();

void print_matrix(const vector<vector<float>>& vec);

#endif //DEBUG_LRN_SVD_H

源文件

#include "svd.h"

void print_matrix(const vector<vector<float>>& vec){
    if(vec.empty()){
        return;
    }
    for ( auto row: vec){
        if(row.empty()){
            return;
        }
        for ( auto elem: row){
            cout << elem << ", ";
        }
        cout << endl;
    }
    cout << endl;
}



int test_SVD()
{
    std::vector<std::vector<float>> vec{ { 0.68f, 0.597f },
                                         { -0.211f, 0.823f },
                                         { 0.566f, -0.605f } };
    cout << "source matrix:" << endl;
    print_matrix(vec);

//    cout << "C++ implement SVD:" << endl;
//    vector<vector<float>> matD, matU, matVt;
//    if (svd(vec, matD, matU, matVt) != 0) {
//        cout << "C++ implement singular value decomposition fail!" << endl;
//        return -1;
//    }
//    cout << "singular values:" << endl;
//    print_matrix(matD);
//    cout << "left singular vectors:" << endl;
//    print_matrix(matU);
//    cout << "transposed matrix of right singular values:" << endl;
//    print_matrix(matVt);

    cout << "opencv singular value decomposition:" << endl;
    const auto rows = (int)vec.size();
    const auto cols = (int)vec[0].size();
    cv::Mat mat(rows, cols, CV_32FC1);
    for (int y = 0; y < rows; ++y) {
        for (int x = 0; x < cols; ++x) {
            mat.at<float>(y, x) = vec.at(y).at(x);
        }
    }

    cv::Mat matD, matU, matVt;
    cv::SVD::compute(mat, matD, matU, matVt, 4);
    cout << "singular values:" << endl;
    cout << matD << endl;
    cout << "left singular vectors:" << endl;
    cout << matU << endl;
    cout << "transposed matrix of right singular values:" << endl;
    cout << matVt << endl;
    cv::Mat matUt, matV;
    cv::transpose(matU, matUt);
    cv::transpose(matVt, matV);

    cout << "verify if the result is correct:" << endl;
    cv::Mat reconMatD = matUt * mat * matV;
    cout << reconMatD << endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/theodoric008/p/9506015.html
今日推荐