svd奇异值分解

基础题

 

证明式(15)中,取y=u4是该问题的最优解,

证明:

提示设置y’=u4+v,其中v正交于u4,证明

该式方法基于奇异值构造矩阵零空间。

解:

//
// Created by hyj on 18-11-11.
//
#include <iostream>
#include <vector>
#include <random>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <Eigen/Eigenvalues>

struct Pose
{
    Pose(Eigen::Matrix3d R, Eigen::Vector3d t) : Rwc(R), qwc(R), twc(t){};
    Eigen::Matrix3d Rwc;
    Eigen::Quaterniond qwc;
    Eigen::Vector3d twc;

    Eigen::Vector2d uv; // 这帧图像观测到的特征坐标
};
int main()
{
    std::cout << "1" << std::endl;
    int poseNums = 10;
    double radius = 8;
    double fx = 1.;
    double fy = 1.;
    std::vector<Pose> camera_pose;
    for (int n = 0; n < poseNums; ++n)
    {
        double theta = n * 2 * M_PI / (poseNums * 4); // 1/4 圆弧
        // 绕 z轴 旋转
        Eigen::Matrix3d R;
        R = Eigen::AngleAxisd(theta, Eigen::Vector3d::UnitZ());
        Eigen::Vector3d t = Eigen::Vector3d(radius * cos(theta) - radius, radius * sin(theta), 1 * sin(2 * theta));
        camera_pose.push_back(Pose(R, t));
    }

    // 随机数生成 1 个 三维特征点
    std::default_random_engine generator;
    std::uniform_real_distribution<double> xy_rand(-4, 4.0);
    std::uniform_real_distribution<double> z_rand(8., 10.);
    double tx = xy_rand(generator);
    double ty = xy_rand(generator);
    double tz = z_rand(generator);

    Eigen::Vector3d Pw(tx, ty, tz);

    // 这个特征从第三帧相机开始被观测,i=3
    int start_frame_id = 3;
    int end_frame_id = poseNums;
    for (int i = start_frame_id; i < end_frame_id; ++i)
    {
        Eigen::Matrix3d Rcw = camera_pose[i].Rwc.transpose();
        Eigen::Vector3d Pc = Rcw * (Pw - camera_pose[i].twc);

        double x = Pc.x();
        double y = Pc.y();
        double z = Pc.z();

        camera_pose[i].uv = Eigen::Vector2d(x / z, y / z);
    }

    /// TODO::homework; 请完成三角化估计深度的代码
    // 遍历所有的观测数据,并三角化
    Eigen::Vector3d P_est; // 结果保存到这个变量
    P_est.setZero();
    /* your code begin */

    //主要思想:相机多帧观测对应空间在一点
    Eigen::Matrix4d D;
    Eigen::MatrixXd P(2 * (end_frame_id - start_frame_id), 4);

    for (int i = 3, j = 0; i < poseNums; i++)
    {
        Eigen::Isometry3d Tcw = Eigen::Isometry3d::Identity();
        Tcw.rotate(camera_pose[i].Rwc.transpose());
        Tcw.pretranslate(-camera_pose[i].Rwc.transpose() * camera_pose[i].twc);

        P.block(j, 0, 1, 4) = camera_pose[i].uv.x() * Tcw.matrix().row(2) - Tcw.matrix().row(0);
        P.block(j + 1, 0, 1, 4) = camera_pose[i].uv.y() * Tcw.matrix().row(2) - Tcw.matrix().row(1);
        j += 2;
    }

    D = P.transpose() * P;
    Eigen::JacobiSVD<Eigen::MatrixXd> svd(D, Eigen::ComputeThinU | Eigen::ComputeThinV);

    Eigen::MatrixXd U = svd.matrixU();
    Eigen::MatrixXd V = svd.matrixV();

    P_est << (U.rightCols(1) * U.rightCols(1).bottomRows(1).inverse()).topRows(3);

    /* your code end */

    std::cout << "ground truth: \n"
              << Pw.transpose() << std::endl;
    std::cout << "your result: \n"
              << P_est.transpose() << std::endl;
    return 0;
}

 

 

 

 

参考:

https://blog.youkuaiyun.com/m0_37870649/article/details/80547167

https://blog.youkuaiyun.com/xiaocong1990/article/details/54909126

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SVD奇异值分解是一种常用的矩阵分解方法,可用于信号和图像的降噪。其原理和方法如下: ### 原理 奇异值分解可以将一个矩阵分解为三个矩阵的乘积,基本思想是把矩阵分解为U、Σ和V三个部分,其中U和V是正交矩阵,Σ是对角矩阵。通常噪声对应较小的奇异值,通过对Σ中的奇异值进行适当处理,如丢弃小奇异值并重构矩阵,就可以达到一定程度的降噪效果[^2][^4]。 ### 方法 在数字信号处理中,使用SVD进行降噪的具体步骤如下: 1. **构建矩阵**:将待降噪的信号构成一个矩阵[^2]。 2. **SVD分解**:对该矩阵进行SVD分解,得到U、Σ和V [^2]。 3. **选择奇异值**:根据降噪的需求,选择保留的奇异值个数,将其余的奇异值置零。较小的奇异值通常对应噪声,去除这些值可以减少噪声影响 [^2][^3][^4]。 4. **重构矩阵**:根据保留的奇异值,重新构建矩阵 [^2]。 5. **SVD运算**:对重构后的矩阵进行逆SVD运算,得到降噪后的信号 [^2]。 在图像降噪中,通过调整保留的奇异值数量k,可以在噪声去除和细节保留之间取得平衡。较小的k值(如5或10)可以有效去除噪声,但会丢失图像细节;较大的k值(如50或100)能保留更多细节,但降噪效果会降低 [^3]。 ### 代码示例(Python) 以下是一个简单的Python示例,使用NumPy库进行SVD降噪: ```python import numpy as np # 生成含噪声的信号 signal = np.linspace(0, 10, 100) noise = np.random.normal(0, 1, 100) noisy_signal = signal + noise # 构建矩阵 matrix = noisy_signal.reshape(-1, 1) # SVD分解 U, S, V = np.linalg.svd(matrix, full_matrices=False) # 选择保留的奇异值个数 k = 1 S[k:] = 0 # 重构矩阵 reconstructed_matrix = np.dot(U * S, V) # 提取降噪后的信号 denoised_signal = reconstructed_matrix.flatten() print("降噪前信号:", noisy_signal) print("降噪后信号:", denoised_signal) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值