点云_点云坐标变换_检查pcd格式和points状态

点云坐标变换

点云坐标变换-通过转换矩阵的方式

点云代码示例

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

代码示例

PCD Format check

# -*- 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
posted @ 2022-11-09 13:48  辰令  阅读(332)  评论(0编辑  收藏  举报