点云坐标变换
点云坐标变换-通过转换矩阵的方式
点云代码示例
import open3d as o3d
import numpy as np
from scipy.spatial.transform import Rotation
orig_pcd = o3d.io.read_point_cloud("aa.pcd")
##变换坐标系
"""points transform 点云格式转换 """
orig_points = np.asarray(orig_pcd.points)
src_pcd = np.zeros(( orig_points.shape[0],4))
src_pcd[:,:3] = orig_points
src_pcd[:,3]=np.ones((orig_points.shape[0]))
###TR matrix format (x, y, z, w) format
"""TR matrix 转换矩阵转换 """
R_mat = Rotation.from_quat([0.34,-0.01, -0.01, 0.3])
rotation_matrix = R_mat.as_matrix()
translate_matrix= np.array([0.5,-0.23,0.01]).reshape(-1,1)
TR_matrix = np.eye(4,dtype=np.float32)
TR_matrix[:3,:3] = rotation_matrix
TR_matrix[:3,3]= translate_matrix[:,0]
##进行转换
new_xyz_array = np.dot(TR_matrix, src_pcd.T).T[:, :3]
###绘制点云
dst_pcd = o3d.geometry.PointCloud()
dst_pcd.points = o3d.utility.Vector3dVector(new_xyz_array)
o3d.visualization.draw_geometries([orig_pcd,dst_pcd])
PCD格式
1.获取pcd格式
2.python点云match
代码示例
# -*- coding: utf-8 -*-
import os
import re
import numpy as np
import open3d as o3d
def parse_header(lines):
""" Parse header of PCD files.
"""
metadata = {}
for ln in lines:
if ln.startswith('#') or len(ln) < 2:
print(ln)
continue
match = re.match('(\w+)\s+([\w\s\.]+)', ln)
if not match:
print("warning: can't understand line: %s" % ln)
continue
key, value = match.group(1).lower(), match.group(2)
if key == 'version':
metadata[key] = value
elif key in ('fields', 'type'):
metadata[key] = value.split()
elif key in ('size', 'count'):
metadata[key] = list(map(int, value.split()))
elif key in ('width', 'height', 'points'):
metadata[key] = int(value)
elif key == 'viewpoint':
metadata[key] = list(map(float, value.split()))
elif key == 'data':
metadata[key] = value.strip().lower()
return metadata
def check_point_header(fname):
header = []
with open(fname, mode='rb') as f:
while True:
ln = f.readline().strip().decode("utf8")
header.append(ln)
if ln.startswith('DATA'):
metadata = parse_header(header)
break
return metadata
if __name__ == "__main__":
pcd_file = r"/data/test/16.pcd"
o3d_pcd = o3d.io.read_point_cloud(pcd_file)
print(type(o3d_pcd))
# print(np.asarray(o3d_pcd.points))
o3d_t_pcd = o3d.t.io.read_point_cloud(pcd_file)
print(type(o3d_t_pcd))
# Use pcd.point to access the points' attributes
exp_t_points = o3d_t_pcd.point
print(type(exp_t_points))
# Default attribute: "positions". The shape must be (N, 3)
points_xyz = exp_t_points['positions'].numpy()
# User-defined attributes from fields
pcd_intensity = exp_t_points['intensity'].numpy()
print(" max", np.max(pcd_intensity)," min",np.min(pcd_intensity))
pcd_metadata = check_point_header(pcd_file)
print(pcd_metadata)
Python 正则表达式
1.1 字符与字符类
\w 匹配Unicode单词字符,如果带有re.ascii,则匹配[a-zA-Z0-9_]中的一个
\s 匹配Unicode空白,如果带有re.ASCII,则匹配\t\n\r\f\v中的一个
1.2 量词
+ 匹配前面的字符1次或者多次
1.3 组与捕获
1.4 返回值是否是None来判断
匹配对象的属性与方法
m.group(g, ...)
返回编号或者组名匹配到的内容,默认或者0表示整个表达式匹配到的内容,如果指定多个,就返回一个元组
m.groups(default)
返回一个元组。包含所有捕获到内容的子分组,从1开始,如果指定了default值,则这个值作为那些没有捕获到内容的组的值
import re # 导入re 模块
ln = "Python is a good language"
str_pattern = '(\w+)\s+([\w\s\.]+)'
re_content = re.match(str_pattern, ln)
if re_content:
print(re_content.span())
print(re_content.group())
else:
print("没有匹配到内容")
参考
正则表达式简介 https://www.cnblogs.com/chenchaoze/p/9675161.html
https://github.com/dimatura/pypcd/blob/master/pypcd/pypcd.py
Point Cloud Library http://pointclouds.org/documentation/tutorials/pcd_file_format.html