【ROS】【Python3】实现计算点云每一帧基于特征值的6维特征向量

在ros中实现计算每一帧点云的特征向量


思路流程

订阅点云数据

创建一个类class eigen_feature:

class eigen_feature:
	def __init__(self):
	def callback(self,lidar):
	def get_6features(self,eigenvalues):	
	def PCA(self,k_neighbor,sort=True):

其中的构造函数如下,订阅点云话题/rslidar_points,消息类型位PointCloud2

def __init__(self):
	# self.feature_pub = rospy.Publisher('/features',eigen_features,queue_size=1)
	self.pt_sub=rospy.Subscriber("/rslidar_points", PointCloud2, self.callback)
回调函数

当订阅到点云时,执行回调函数,回调函数中使用了open3d库。并且调用了类函数self.PCA、self.get_6features。其中,self.PCA对每一个点进行主成分分析,计算特征值和特征向量;self.get_6features函数根据PCA计算出的特征值计算基于特征值的6个特征。

def callback(self,lidar):
	
		# convert pointcloud2 to array
		lidar = pc2.read_points(lidar)
		points = np.array(list(lidar))
		
		# get a PointCloud
		point_cloud = PointCloud()
		point_cloud.points = Vector3dVector(points[:,0:3].reshape(-1,3))
    	
		# downsample
		point_cloud= point_cloud.voxel_down_sample(voxel_size=0.6)
		points=point_cloud.points
		points=np.asarray(points)
    	
		# build a kdtree
		pcd_tree = o3d.geometry.KDTreeFlann(point_cloud)
    	
		eigenfeatures = []
		K=19
		
		save_filename='/home/s/Dataset/syz.txt'
		
		for i in range(points.shape[0]):
			[k,index,_]=pcd_tree.search_knn_vector_3d(point_cloud.points[i],K+1)
			
			eigenvalues,eigenvectors=self.PCA(points[index[:],:])
			
			tmp=self.get_6features(eigenvalues=eigenvalues)
			
			eigenfeatures.append(tmp)
			
		# print("eigenfeatures size:{}".format(len(eigenfeatures)))
		
		# convert list[] to array
		eigenfeatures=np.array(eigenfeatures)
		print('eigenfeatures shape:{}'.format(eigenfeatures.shape))
			
		np.savetxt(save_filename,eigenfeatures)
		print(save_filename+" save!")

		# 退出
		try:
			os._exit(0)
		except:
			print('Program is dead')

self.PCA

def PCA(self,k_neighbor,sort=True):
	k_neighbor_T=k_neighbor.T
	C=np.matmul(k_neighbor_T,k_neighbor) # 3x3
	eigenvalues,eigenvectors=np.linalg.eig(C)

	if sort:
		sort=eigenvalues.argsort()[::-1]
		eigenvalues = eigenvalues[sort]
		eigenvectors = eigenvectors[:, sort]
	return eigenvalues, eigenvectors

self.get_6features

	
def get_6features(self,eigenvalues):
	
	v1=np.float(eigenvalues[0]) 
	v2=np.float(eigenvalues[1])
	v3=np.float(eigenvalues[2])
	
	sum=v1+v2+v3
	if sum==0:
		sum=0.000000001
	e1=v1/sum
	e2=v2/sum
	e3=v3/sum

	# print('v1:{},v2:{},v3:{}'.format(v1,v2,v3))
	if v1==0:
		v1=0.000000001
	L=(v1-v2)/v1   # 线性
	P=(v2-v3)/v1   # 平面性
	S=v3/v1        # 散度性
	O=3*np.power(e1*e2*e3,1/3)   # 全方差

	if e1<=0:
		e1=0.000000001
	if e2<=0:
		e2=0.000000001
	if e3<=0:
		e3=0.000000001

	E=e1*np.log(e1)+e2*np.log(e2)+e3*np.log(e3)  # 特征熵
	E=E*(-1)
	C=3*v3/sum       # 曲率变化

	return [L,P,S,O,E,C]
初始化节点
if __name__ == '__main__':
	print('------------------start-----------------')
	print("open3d:{}".format(o3d.__version__))
	eigen=eigen_feature()  # 初始化类,会调用类构造函数
	rospy.init_node('eigenfeature')  # 初始化节点
	rospy.spin()  # 一直循环(好像是这个意思)

完整代码

https://github.com/suyunzzz/aiimooc_lesson/tree/master/aiimooc_syz3

要注意代码运行时需要在对应的conda环境中运行,如果不知道怎么做可以参考我的上一篇博客

参考

https://github.com/suyunzzz/aiimooc_lesson/tree/master/aiimooc_syz3
点云生成鸟瞰图(Python)

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tech沉思录

点赞加投币,感谢您的资瓷~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值