opencv SVD算法

部署运行你感兴趣的模型镜像

参照:https://www.cnblogs.com/pinard/p/6251584.html 

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace  cv;
//SVD算法
int main()
{
	string filename = "C:/Users/Administrator/Desktop/标准测试图片/Fig0646(a)(lenna_original_RGB).tif";
	Mat img = imread(filename, IMREAD_GRAYSCALE);
	img.convertTo(img, CV_32FC1);//转换为float类型
	string tile = "压缩比率";
	Mat U, W, VT;
	SVD svd;
	svd.compute(img, W, U, VT);
	//将矩阵进行压缩
	//原始数据进行压缩之后是 m*m m*n n*n
	//由于特征值在前几行中占有的比率是比较大的,所以,仅仅选择前几行(r)作为好的特征值
	//那么分解的结果就变为 m*r r*r r*n 这样的形式
	double radio = 0.2;//压缩比率
	int rows = radio*img.rows;
	Mat WROI = Mat::zeros(rows, rows, CV_32FC1);//W矩阵的大小
	//填充举着WROI;
	for (int i = 0; i < rows;++i)
	{
		WROI.at<float>(i, i) = W.at<float>(i);
	}
	Mat UROI = U.colRange(0, rows);//主要注意的是,colrange中不包含End
	Mat VTROI = VT.rowRange(0, rows);
	Mat Result = UROI*WROI*VTROI;
	//将结果转换为灰度影像
	Result.convertTo(Result, CV_8UC1);
	namedWindow(tile);
	imshow(tile, Result);
	waitKey(0);
	return 0;
}

 

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>我们正在讨论OpenCV中的最近点迭代算法(Iterative Closest Point, ICP)。ICP是一种用于最小化两个点云之间差异的算法,常用于三维点云的配准,例如在计算机视觉、机器人学和医学成像中。OpenCV提供了ICP的实现,主要位于`cv2.ppf_match_3d_ICP`类中。 ### 1. ICP算法介绍 ICP算法用于寻找两个点云之间的最佳刚体变换(旋转和平移),使得其中一个点云(源点云)变换后与另一个点云(目标点云)尽可能重合。该算法迭代执行以下步骤: - **步骤1**:对于源点云中的每个点,在目标点云中找到最近邻点(对应点)。 - **步骤2**:计算使对应点之间的均方误差最小的刚体变换(旋转矩阵R和平移向量t)。 - **步骤3**:应用刚体变换到源点云。 - **步骤4**:重复上述步骤直到满足收敛条件(如变换参数的变化量小于阈值,或达到最大迭代次数)。 ### 2. 算法原理 设源点云为$P = \{p_i\}_{i=1}^{N_p}$,目标点云为$Q = \{q_j\}_{j=1}^{N_q}$。ICP算法最小化以下目标函数: $$ E(\mathbf{R}, \mathbf{t}) = \sum_{i=1}^{N_p} \| \mathbf{R} p_i + \mathbf{t} - q_{c(i)} \|^2 $$ 其中$c(i)$表示源点$p_i$在目标点云中对应的最近点的索引,$\mathbf{R}$是旋转矩阵(正交阵且行列式为1),$\mathbf{t}$是平移向量。 在每次迭代中,算法通过以下步骤求解: 1. **寻找对应点**:使用kd-tree等加速结构为每个$p_i$在$Q$中找到最近点$q_{c(i)}$。 2. **求解最优变换**:通过奇异值分解(SVD)或四元数等方法计算最优的$\mathbf{R}$和$\mathbf{t}$。具体来说: - 计算两个点云的质心: $$ \mu_p = \frac{1}{N_p} \sum_{i=1}^{N_p} p_i, \quad \mu_q = \frac{1}{N_p} \sum_{i=1}^{N_p} q_{c(i)} $$ - 计算去质心的点集: $$ p_i' = p_i - \mu_p, \quad q_i' = q_{c(i)} - \mu_q $$ - 计算矩阵: $$ \mathbf{H} = \sum_{i=1}^{N_p} p_i' q_i'^T $$ - 对$\mathbf{H}$进行SVD分解:$\mathbf{H} = \mathbf{U} \mathbf{\Sigma} \mathbf{V}^T$ - 则旋转矩阵为:$\mathbf{R} = \mathbf{V} \mathbf{U}^T$(如果$\det(\mathbf{R})<0$,则需调整符号以保证旋转矩阵的性质) - 平移向量为:$\mathbf{t} = \mu_q - \mathbf{R} \mu_p$ 3. **更新变换并应用**:将计算得到的变换应用到整个源点云。 4. **检查收敛**:如果变换参数的变化小于阈值或达到最大迭代次数,则停止迭代。 ### 3. OpenCV中的使用方法 OpenCV在`opencv_contrib`模块的`ppf_match_3d`中提供了ICP实现。以下是使用步骤: #### 安装 确保安装了包含`opencv_contrib`的OpenCV。可以通过pip安装(但pip安装可能不包含contrib模块,建议从源码编译): ```bash pip install opencv-contrib-python ``` #### 代码示例 ```python import cv2 import numpy as np # 创建ICP对象,设置参数:最大迭代次数、容忍误差、最大对应点距离等 icp = cv2.ppf_match_3d_ICP(100, tolerance=0.05, rejectionScale=2.5, numLevels=6) # 读取源点云和目标点云,格式为Nx3的numpy数组 # 假设source_cloud和target_cloud已经准备好 retval, residual, pose = icp.registerModelToScene(source_cloud, target_cloud) # 输出结果 print("变换矩阵:\n", pose) print("残差:", residual) ``` 参数说明: - `maxIterations`: 最大迭代次数 - `tolerance`: 收敛容忍度(连续两次变换的差异小于此值则停止) - `rejectionScale`: 用于剔除离群点的阈值倍数(基于距离分布) - `numLevels`: 金字塔层数(多尺度配准) 函数返回: - `retval`: 最终残差(均方误差) - `residual`: 同retval(历史原因保留两个返回值) - `pose`: 4x4刚体变换矩阵(将源点云变换到目标点云坐标系的变换矩阵) ### 注意事项 - 点云需要预处理(去噪、滤波、下采样)以提高配准效果和速度。 - 初始位置对ICP的收敛至关重要,如果初始位置偏差较大,可能陷入局部最优。可以使用粗配准(如基于特征的方法)提供初始变换。 - OpenCV的ICP实现要求点云为`np.float32`类型。 ### 总结 ICP是点云配准中的核心算法OpenCV提供了高效的实现。通过迭代寻找最近点并求解最优变换,ICP能够实现精确的点云配准。在实际应用中,合理的参数设置和预处理是成功的关键。 §§相关问题§§ 1. 如何预处理点云数据以提高ICP配准的精度和速度? 2. 如何处理初始位置不佳导致ICP陷入局部最优的问题? 3. OpenCV中的ICP算法支持多尺度配准吗?其原理是什么? 4. 除了ICP,OpenCV还提供了哪些点云配准算法? </think>### OpenCV最近点迭代算法(ICP)详解 #### 1. 算法介绍 最近点迭代(Iterative Closest Point, ICP)是三维点云配准的核心算法,用于寻找两个点云之间的最优刚体变换(旋转+平移)。OpenCV在`opencv_contrib`模块的`ppf_match_3d`中实现了ICP算法,主要用于: - 三维重建中的点云对齐 - SLAM(同步定位与地图构建) - 物体识别与位姿估计 - 医学图像配准[^1] #### 2. 算法原理 ICP通过迭代优化最小化距离误差: $$\argmin_{R,t} \sum_{i=1}^{N} \| \mathbf{q_i} - (\mathbf{R} \cdot \mathbf{p_i} + \mathbf{t}) \|^2$$ 其中: - $R$为旋转矩阵($3 \times 3$正交矩阵) - $t$为平移向量($3 \times 1$) - $p_i$为源点云 - $q_i$为目标点云对应点 **迭代步骤**: 1. **对应点匹配**:对源点云中每个点,在目标点云中找欧氏距离最近的点 $$ c(i) = \argmin_{j} \| \mathbf{q_j} - \mathbf{p_i} \| $$ 2. **变换估计**:通过SVD分解求解最优刚体变换 $$\mathbf{H} = \sum (\mathbf{p_i} - \mu_p)(\mathbf{q_i} - \mu_q)^T \quad \text{(协方差矩阵)}$$ $$\mathbf{U\Sigma V^T} = \text{SVD}(\mathbf{H})$$ $$\mathbf{R} = \mathbf{VU^T}, \quad \mathbf{t} = \mu_q - \mathbf{R}\mu_p$$ 3. **应用变换**:更新源点云位置 $\mathbf{p_i} \leftarrow \mathbf{R} \cdot \mathbf{p_i} + \mathbf{t}$ 4. **收敛判断**:重复直到均方误差$<\epsilon$或达最大迭代次数 #### 3. OpenCV实现方法 ```python import cv2 import numpy as np # 创建ICP对象 (OpenCV 4.x) icp = cv2.ppf_match_3d_ICP( iterations=200, # 最大迭代次数 tolerance=0.05, # 收敛阈值 rejectionScale=2.0, # 离群点剔除阈值 numLevels=6 # 金字塔层数 ) # 生成示例点云 (Nx3数组) source_cloud = np.random.rand(1000, 3).astype(np.float32) target_cloud = source_cloud @ np.array([[0.866, -0.5, 0], [0.5, 0.866, 0], [0,0,1]]) + [0.1, 0.2, 0.3] # 执行配准 _, residual, pose = icp.registerModelToScene(source_cloud, target_cloud) print(f"配准误差: {residual:.6f}") print(f"变换矩阵:\n{pose}") ``` **参数详解**: - `iterations`:最大迭代次数(建议100-500) - `tolerance`:均方误差变化阈值(通常0.01-0.001) - `rejectionScale`:剔除距离大于均距×该值的离群点 - `numLevels`:多分辨率金字塔层数(加速收敛) **输出说明**: - `residual`:最终均方误差 - `pose`:4×4齐次变换矩阵 $$ \mathbf{T} = \begin{bmatrix} \mathbf{R}_{3\times3} & \mathbf{t}_{3\times1} \\ \mathbf{0}_{1\times3} & 1 \end{bmatrix} $$ #### 4. 关键技巧 1. **数据预处理**: ```python # 点云下采样 (提升速度) voxel_size = 0.01 source_down = cv2.voxelDownSample(source_cloud, voxel_size) ``` 2. **法向量估计**(提升精度): ```python normals = cv2.ppf_match_3d.computeNormalsPC3d(source_cloud, 30) # 30邻域点 ``` 3. **初始位姿估计**: ```python icp.registerModelToScene(source, target, initialPose=guess_pose) ``` #### 5. 典型应用场景 1. **三维扫描配准**:多视角扫描点云对齐 ```python # 多帧配准 combined_cloud = first_frame for frame in frames[1:]: _, _, pose = icp.registerModelToScene(frame, combined_cloud) combined_cloud = transformPoints(frame, pose) ``` 2. **物体位姿估计**:匹配模型与场景点云 3. **动态场景重建**:RGB-D序列实时配准[^2] > **注意**:OpenCV的ICP实现要求点云为`np.float32`类型,且需安装`opencv-contrib-python`包
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值