首页 > 其他分享 >手写PCA(主元分析法)计算点云法向量(详细注释) 【Matlab代码】

手写PCA(主元分析法)计算点云法向量(详细注释) 【Matlab代码】

时间:2023-10-07 18:01:56浏览次数:36  
标签:end pw Point 矩阵 主元 Matlab 点云法 PCA 向量


原理

PCA原理

主元分析法PCA学习笔记

点云法向量与点云平面拟合的关系(PCA)

Estimating Surface Normals in a PointCloud

3D【24】PCA点云法向量估计

利用PCA计算点云的法线

3D点云法向量估计(最小二乘拟合平面)

为什么用PCA做点云法线估计?

利用PCA求点云的法向量

pca_demo.m

clc
clear
close all
n=50;
z=peaks(n);
x=1:n;y=1:n;
[x,y]=meshgrid(x,y);
P=[x(:),y(:),z(:)];

%读入屋顶点云
% P=load('building_Example2.txt');
% P=P(:,1:1:3);

%读入Building1.txt
% P=load('point_w.txt');
% P=P(:,1:1:3);


P=P';%P=3x2500
k=8;
[pn,pw] = pca(P, k);
pp = P+3.*pn;%pn为法向量,pw为评价曲率的一个参数

%求取曲率最大的500个点
P_=P';%P_ 是2500x3
[pw_,indice]=sort(pw);
indice=indice';

%找出曲率最大(或最小)的几个点,验证
% pw_first=indice(size(indice,1)-100:1:size(indice,1),:);%曲率最大值排前1000的点
pw_first=indice(1:1:700,:);%曲率最小值(最平坦)排前1000的点

for i=1:size(pw_first)
    Point_pw(i,1)=P_(pw_first(i),1);
    Point_pw(i,2)=P_(pw_first(i),2);
    Point_pw(i,3)=P_(pw_first(i),3);%Point_pw为曲率的前500个点
end


figure;
% scatter3( P(1,:)',P(2,:)',P(3,:)','.');
plot3(P(1,:)',P(2,:)',P(3,:)','g.');
hold on
plot3(Point_pw(:,1),Point_pw(:,2),Point_pw(:,3),'r*');
title("最平坦的前780个点");




% 使用matlab工具箱计算的法向量
figure(2);
P=P';
pt=pointCloud(P);
pcshow(pt);
hold on;

normals=pcnormals(pt,8);
u = normals(1:5:end,1);
v = normals(1:5:end,2);
w = normals(1:5:end,3);

x=P(1:5:end,1);
y=P(1:5:end,2);
z=P(1:5:end,3);
title('Matlab点云工具箱计算的 Normals of Point Cloud')
hold on
quiver3(x, y, z, u, v, w);
view(-37.5,45);
hold off

%使用pca计算的法向量
figure(3)
pcshow(pt);
hold on;
pn=pn';%对pn进行转置

u_p = pn(1:5:end,1);
v_p = pn(1:5:end,2);
w_p = pn(1:5:end,3);


title('PCA计算的 Normals of Point Cloud')
hold on
quiver3(x, y, z, u_p, v_p, w_p);
view(-37.5,45);
hold off

pca.m

% PCA主元分析法求法向量
% 输入:
% p:3*n的数值矩阵
% k:k近邻参数
% neighbors = transpose(knnsearch(transpose(p), transpose(p), 'k', k+1));
% neighbors一般可缺省。若之前做过k邻域求取操作也可直接调用,提高运算效率
% 输出
% n:法矢,已规定方向由邻域拟合出的平面指向查询点
% w:用于评估曲率的参数,详见:Mark P,et al. Multi-scale Feature Extraction on Point-Sampled Surfaces[J]. Computer Graphics Forum, 2010, 22(3): 281-289.

function [n,w] = pca(p, k, neighbors)%p为输入的点云
if nargin < 2
    error('no bandwidth specified')
end
if nargin < 3
    neighbors = transpose(knnsearch(transpose(p), transpose(p), 'k', k+1));%neighbor为一个索引矩阵,第一行代表第几个点,后8行代表K近邻的点。记录每个点及其周围的8个点
end
m = size(p,2);%返回第2维的维度
n = zeros(3,m); %存放法线的矩阵
w = zeros(1,m);
for i = 1:m
    x = p(:,neighbors(2:end, i));%x为8个邻域点    ,3x8的矩阵
    p_bar=mean(x,2);%每一行求均值(一共三行)
    
%     P =  (x - repmat(p_bar,1,k)) * transpose(x - repmat(p_bar,1,k));%中心化样本矩阵,再计算协方差矩阵
%     P = 1/(k) * (x - repmat(p_bar,1,k)) * transpose(x - repmat(p_bar,1,k)); %邻域协方差矩阵P
    P=(x - repmat(p_bar,1,k)) * transpose(x - repmat(p_bar,1,k))./(size(x,2)-1);
    
    [V,D] = eig(P);%求P的特征值、特征向量。 D是对应的特征值对角矩阵,V是特征向量(因为协方差矩阵为实对称矩阵,故特征向量为单位正交向量)
    
    [d0, idx] = min(diag(D)); %d0为最小特征值  idx为特征值的列数索引。diag():创建对角矩阵或获取矩阵的对角元素

    
    n(:,i) = V(:,idx);   % 最小特征值对应的特征向量为法矢,即法向量    
    
    %规定法矢方向指向
    flag = p(:,i) - p_bar;%由近邻点的平均点指向对应点的向量
    if dot(n(:,i),flag)<0%如果这个向量与法向量的数量积为负数(反向)
        n(:,i)=-n(:,i);%法向量取反向
    end
    if nargout > 1 
        w(1,i)=abs(d0)./sum(abs(diag(D)));%最小特征值的绝对值在协方差矩阵特征值绝对值的总和中占的比重
    end
end

效果 

在pca.m中是用到了matlab内置的K-NN查找K近邻点

近邻点查找效果如下,这里K取8,

手写PCA(主元分析法)计算点云法向量(详细注释) 【Matlab代码】_matlab

使用手写的PCA计算出的法向量和matlab点云处理工具箱计算的法向量的效果对比如下,

手写PCA(主元分析法)计算点云法向量(详细注释) 【Matlab代码】_matlab_02

 

手写PCA(主元分析法)计算点云法向量(详细注释) 【Matlab代码】_pca_03

可以看到,基本上是一样的。

 

 

标签:end,pw,Point,矩阵,主元,Matlab,点云法,PCA,向量
From: https://blog.51cto.com/u_14355665/7740673

相关文章

  • 安装包Matlab-中文科学编程软件-安装包下载方式
    Matlab应用是从外网软件论坛中引进的一款优质数据分析平台,该应用的UI布局设计参考了主流的办公应用,主体是由MATLAB和Simulink组成,内置了多达六百余种的函数运算模式,适合于每天需要处理大规模数据计算的行业,像仿真建模、系统算法的研发以及复杂的工程结构作图等,相信会是满意的选择。......
  • matlab下载-matlab软件官方版下载「编程开发」安装包下载方式
    matlab最新版本是一款非常不错的数学计算软件,这款软件非常的给力有着很强悍的算法以及模型创建能力,此版本更新了很多新的功能,能让你的办公使用更加强悍,快来下载试试吧。软件地址:看置顶贴Matlab2020b软件特色1、Matlab2020b提供用于科学计算及工程设计的高级语言。2、Matlab2020b可......
  • 在MATLAB中将两条曲线画在同一个图上
    在MATLAB中将两条曲线画在同一个图上,如果直接采用下面的代码,那么画的第二个图会将第一个图覆盖plot(x,p1,'LineWidth',2);plot(x,p2,'LineWidth',2);正确的做法是在两条语句中间添加holdon;plot(x,p1,'LineWidth',2);holdon;plot(x,p2,'LineWidth',2);———————————......
  • matlab多行注释方法
    方法一选中你要加注释的内容,然后选择工具菜单“text|comment”就可以了,如果要把注释变为语句,同样选中要转变的语句,然后用鼠标选择“text|uncomment”就可以了。用键盘的快捷键是"Ctrl+R".或者选中你要加注释的内容,右击鼠标选择“comment”,如果要把注释变为语句,同样选中要转变的......
  • MATLAB图论工具箱(哪有什么工具箱,就只是一堆函数而已)
    MATLAB图论工具箱图论基础Matlab图论工具箱提供了构建、操作和分析图形的函数和工具。在Matlab图论工具箱中,可以使用以下基本数据结构:graph:无向图。digraph:有向图。可以使用以下函数创建一个图或有向图:graph:创建一个无向图。digraph:创建一个有向图。%创建无......
  • Matlab-多y轴图片绘制
    %%多Y轴图%%MadebyLwcahin2023-06-26(公众号:Lwcah)%%公众号:Lwcah%%知乎、B站、小红书、抖音同名账号:Lwcah,感谢关注~%%更多MATLAB+SCI绘图教程敬请观看~%%清除环境变量closeall;clearall;clc;%%1行1列-定义整幅图出现的在电脑屏幕上的位置以及长和宽figure......
  • 线性系统与信号:MATLAB课时11节
    MATLAB课时B:初步操作  MATLAB课时1:使用函数  MATLAB课时2:M文件  MATLAB课时3:离散时间信号与系统  MATLAB课时4:连续时间滤波器  MATLAB课时5:离散时间IIR滤波器  MATLAB课时6:傅里叶级数应用   MATLAB课时7:傅里叶变换   MATLAB课时8:离散......
  • Matlab : 数理统计
    统计描述性统计(DescriptiveStatistics)描述性统计主要研究数据的中心趋势(CentralTendency)和变异(Variation).中心趋势(CentralTendency)函数作用mean()计算平均值median()计算中位数mode()计算众数prctile()计算百分位数max()计算最大值min()计算最小值X=[13555579......
  • 正弦函数在matlab中实现
    %正弦函数在MATLAB中如何实现%1.sin(45°)注意:参数值需要用“弧度”去定义>>x=sin(45*pi/180);%2.MATLAB中注意:开方-sqrt(x),指数函数-exp(x)>>y=sqrt(2*exp(x+0.5)+1); %3.MATLAB中几元几次方程的写法:2x+3y-z=2%8x+2y+3z=4%45x+3y+9z=23<<A=[2,3,-1;8,2,3;45,3,9];%......
  • Matlab : 符号表达式
    MATLAB强大的符号运算基于符号运算工具箱,具体请见其 官方文档.创建符号变量创建符号数字使用sym函数可以创建符号数字.使用符号数字可以精确地保存无理数,不会产生误差.sym(1/3) %得到1/31/3 %得到0.3333将无理数保存为符号数字可以避免将其转换为浮点数的误差:使用符号数......