内容简介:思路还是很容易想到的:1.首先使用KD树寻找当前点邻域的N个点,这里取了10个,直接调用了vlfeat。2.用最小二乘估计当前邻域点组成的平面,得到法向量。
思路还是很容易想到的:
1.首先使用KD树寻找当前点邻域的N个点,这里取了10个,直接调用了vlfeat。
2.用最小二乘估计当前邻域点组成的平面,得到法向量。
3.根据当前邻域点平均值确定邻域质心,通常质心会在弯曲表面的内部,反方向即为法线方向。
vlfeat在这里下载 ,如何配置我就不多说了。
处理效果如下:
原始点云:
点云表面法向量,做了降采样处理:
兔子果断变刺猬。
matlab代码如下:
clear all;
close all;
clc;
warning off;
pc = pcread('rabbit.pcd');
pc=pcdownsample(pc,'random',0.3); %0.3倍降采样
pcshow(pc);
pc_point = pc.Location'; %得到点云数据
kdtree = vl_kdtreebuild(pc_point); %使用vlfeat建立kdtree
normE=[];
for i=1:length(pc_point)
p_cur = pc_point(:,i);
[index, distance] = vl_kdtreequery(kdtree, pc_point, p_cur, 'NumNeighbors', 10); %寻找当前点最近的10个点
p_neighbour = pc_point(:,index)';
p_cent = mean(p_neighbour); %得到局部点云平均值,便于计算法向量长度和方向
%最小二乘估计平面
X=p_neighbour(:,1);
Y=p_neighbour(:,2);
Z=p_neighbour(:,3);
XX=[X Y ones(length(index),1)];
YY=Z;
%得到平面法向量
C=(XX'*XX)\XX'*YY;
%局部平面指向局部质心的向量
dir1 = p_cent-p_cur';
%局部平面法向量
dir2=[C(1) C(2) -1];
%计算两个向量的夹角
ang = dir1.*dir2 / (sqrt(dir1(1)^2 +dir2(1)^2) + sqrt(dir1(2)^2 +dir2(2)^2)+sqrt(dir1(3)^2 +dir2(3)^2) );
%根据夹角判断法向量正确的指向
flag = acos(ang);
dis = norm(dir1);
if flag<0
dis = -dis;
end
%画出当前点的表面法向量
t=(0:dis/100:dis)';
x = p_cur(1) + C(1)*t;
y = p_cur(2) + C(2)*t;
z = p_cur(3) + (-1)*t;
normE =[normE;x y z];
i
end
pcshowpair(pc,pointCloud(normE));
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法详解(卷1)——算法基础
[美]蒂姆·拉夫加登(Tim Roughgarden) / 徐波 / 人民邮电出版社 / 2019-1-1 / 49
算法是计算机科学领域最重要的基石之一。算法是程序的灵魂,只有掌握了算法,才能轻松地驾驭程序开发。 算法详解系列图书共有4卷,本书是第1卷——算法基础。本书共有6章,主要介绍了4个主题,它们分别是渐进性分析和大O表示法、分治算法和主方法、随机化算法以及排序和选择。附录A和附录B简单介绍了数据归纳法和离散概率的相关知识。本书的每一章均有小测验、章末习题和编程题,这为读者的自我检查以及进一步学习提......一起来看看 《算法详解(卷1)——算法基础》 这本书的介绍吧!