点云_numpy_线性代数运算

数学概念和表达方式

数学的方式

  点积在数学中,又称数量积(dot product; scalar product),是指接受在实数R上的两个向量并返回一个实数值标量的二元运算。
   它是欧几里得空间的标准内积。
   两个向量a = [a1, a2,…, an]和b = [b1, b2,…, bn]的点积定义为:
     a·b=a1b1+a2b2+……+anbn。
	 内积(inner product),又称数量积(scalar product)、点积(dot product)是一种向量运算,
	 但其结果为某一数值,并非向量
数学和计算机概念有相似的地方,也也不同的地方,不要套用了

计算机概念和表达方式

NumPy

NumPy这一支由于和科学计算更强相关,还依赖BLAS/LAPACK这样的线性代数专用库
 通常编译的NumPy会使用openblas ,
 而Anaconda会采用inte免费提供性能更好的libmkl库实现BLAS接口(不开源)
BLAS info:
 * libraries ['openblas', 'openblas']
 * library_dirs ['/opt/OpenBLAS/lib']
 * define_macros [('HAVE_CBLAS', None)]
 * language c   
BLAS(Basic Linear Algebra Subprograms)即基础线性代数子程序库,里面拥有大量已经编写好的关于线性代数运算的程序
   BLAS库在高性能计算中被广泛应用,由此衍生出大量优化版本,
   如Intel的Intel MKL,AMD的ACML ACM(AMD Core Math Library)是AMD提出的数学核心库,Goto BLAS和ATLAS等非硬件厂商优化版本,
   以及利用GPU计算技术实现的CUBLAS CUBLAS(CUDA Basic Linear Algebra Subprograms)等

numpy历史

1. 标量-数值型数据--同质数据-异质数据

 2.numpy中主要操作的对象就是多维数组(ndarray),该数组由两部分组成:
  实际的数据
  描述这些数据的元数据
    ndarry基本属性
     ndim   axis 参数-轴线
     shape
     size
     dtype
NumPy数组的下标也是从0开始的。数组元素的数据类型用专门的对象表示
  a0D = np.array(3)
  a1D = np.array([1, 2, 3, 4])      或者 np.array([2, 3, 4], dtype=np.uint32)  或者 numpy.linspace and numpy.arange 
  a2D = np.array([[1, 2], [3, 4]])  或者 numpy.eye, numpy.diag, and numpy.vander 
  a3D = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) 后者 numpy.ones, numpy.zeros, and random define arrays based upon the desired shape

 传递形状维度的值为-1,表示维度通过数据进行推断

索引和切片

01.索引值(或称下标)来查找序列类型(如字符串、列表、元组...)中的单个元素
02.切片的作用就是截取序列对象 一个索引区间的元素- 切片(slice)就是一种截取索引片段的技术,借助切片技术,
   切片的书写形式:[i : i+n : m] ;其中,i 是切片的起始索引值,为列表首位时可省略;i+n 是切片的结束位置,为列表末位时可省略
 从序列的第i位索引起,向右取到后n位元素为止,按m间隔过滤 。
注意有所不同 
  python list 列表的切片 
    列表切片后得到的还是一个列表,占用新的内存地址。
     当取出切片的结果时,它是一个独立对象,因此,可以将其用于赋值操作,也可以用于其它传递值的场景。
     但是,切片只是浅拷贝-将切片结果取出,它可以作为独立对象使用,但是也要注意,是否取出了变长对象的元素。
	定义对象支持切片语法--list那样按照下标取出元素,需要实现__getitem__()方法
  python numpy--ndarry 的切片--是原来数据的视图
    切片 
	浅拷贝
	深拷贝

示例-np.transpose

transpose 按照轴(可以理解为索引)来处理多维数组的转置
swapaxes()函数 基本思想将数组的两个轴进行交换
  transpose函数中参数个数为轴的个数,而swapaxes函数中参数个数只能是两个。
  01.一维向量(行、列):
   在numpy中一维向量用一位数组array([1, 1, 1])表示,
     既能表示行向量也能表示列向量,一维向量转置后还是原来的样子(因为存储结构是数组)	 
   [12,3,1,0]    transpose 一样,reshape 变为二维
  二维
    transpose 转置--.T转置是换轴的一个特殊案例
	transpose() 这个函数如果括号内不带参数,就相当于转置,和.T效果一样,
  三维
    np.transpose(1,0,2)中三个参数代表三个轴,因为Python中默认下标从0开始,
     所以之前的索引顺序是(0,1,2),而现在将索引顺序变成了(1,0,2)

索引-维度和变换

扩展数组的形状--增加轴-Axis
 None、newaxis 在索引上的用法
  None类似numpy模块下的numpy.expand_dims()函数的扩展数组维度的功能,
      arr的形状是3*4*5,那么我调用arr1 = arr[:, None, ...],那么arr1的形状就是3*1*4*5(
  我们通过在索引数组时添加None或numpy.newaxis参数到某一个维度上,来添加这个维度
  expand_dims() 扩展数组维度
   np.expand_dims(arr, axis)	  
   a = np.array([[[1,2,3],[4,5,6]]])
   b = np.expand_dim(a, axis = 0) 中括号就会加在最前面的值,生成一个 [a]  
  np.newaxis的作用就是在这一位置增加一个一维,这一位置指的是np.newaxis	   

运算

 Replicating, joining, or mutating existing arrays
 对应元素相乘 element-wise product: np.multiply(), 或 *	是矩阵的逐元素成绩,不是矩阵的点乘
                            Numpy.dot(a,b)和运算符 ‘@’	
 dimension == 0 标量
 dimension == 1 矢量
 dimension == 2 矩阵   dimension<=2 时候,可以用一种专用的格式 numpy.matrix 来表示
 dimension > 2 普通张量

numpy 中有一堆表示乘法的运算。和输入的数据维度有关系
   numpy.dot 
       输入包含矢量时候则是内积,
	   不是矢量时候,则是矩阵乘法
	   三维: 前一个数组的最后一维(即数组最内层)的元素个数要等于后一个数组的倒数第二维
	   多维数组元素的点乘实际上是对两个数组的最内层元素进行计算
   numpy.matmul 是矩阵乘法 需要满足矩阵或者张量乘法的条件
   numpy.multiply 逐元素相乘 :
      A是5行4列能和1行4列的矩阵B逐元素相乘呢?
         因为numpy中的广播将1行4列广播成了5行4列,当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制
       * 对 numpy.matrix 是矩阵乘法,需要满足矩阵乘法条件,
	   * 对 numpy.array 是逐元素乘法
	   
   	广播类逐元素相乘						

变换

水平和垂直 :Horizontal Vertical
concatenate, 
   vstack, hstack,column_stack, dstack, c_, r_
 hstack是水平方向拼接数组  vstack是垂直方向拼接数组
 vstack 要求拼接的数据具用相同的列数。vstack相当于将数据一行一行的向后堆叠 沿着轴 0
 hstack 要求数据的数据具有相同的行数,hstack将同一纬度的数据按照原始数据的顺序合并为一个新的列表  沿着轴1   column_stack stacks 1D arrays as columns into a 2D array. It is equivalent to hstack only for 2D arrays: 
 dstack	沿着轴2
 numpy中的c_和r_,它们的作用是将两个矩阵拼接到一起。
 其中c_是将两个矩阵按列拼接到一起,相当于矩阵左右相加,拼接的矩阵行数要相等。
   而r_是将两个矩阵按行拼接,      相当于矩阵上下相加,要求矩阵的列数相等
 
split 
  vsplit  array_split  transpose, 
  vsplit splits along the vertical axis, and array_split	

增删
 numpy的numpy.delete()/insert()/append()
     numpy.delete(arr,obj,axis=None)	
     numpy.insert(arr,obj,value,axis=None)	
     numpy.append(arr,values,axis=None)		 

拷贝

视图--别名- 赋值:其实就是对象的引用(相当于取别名)
--基本数据类型的拷贝--对象的拷贝(对象中不可变元素,可变元素)
  不可变元素浅拷贝-不可变类型, 浅拷贝就一定是引用
(1)、深拷贝:拷贝了一份与原对象不同地址的对象,修改对象中的任何值,都不会改变深拷贝的对象的值。
(2)、浅拷贝:对原对象值的拷贝,地址仍然指向原对象的地址,原对象的值发生变化,拷贝对象的值也会随着改变。
 在浅拷贝时,拷贝出来的新对象的地址和原对象是不一样的,但是新对象里面的可变元素(如列表)的地址和原对象里的地址是相同的。
 也就是说浅拷贝它拷贝的是浅层次的数据结构(不可变元素),
 对象里的可变元素作为深层次的数据结构并没有被拷贝到新地址里面去,而是和原对象里的指向同一个地址
(3)、深拷贝和浅拷贝需要注意的地方是:可变元素的拷贝

  浅拷贝(copy):拷贝父对象,不会拷贝对象内部的子对象,会引用子对象。
  深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象

python 函数参数传递

根据传递形,函数的参数可分为位置参数,关键字参数,默认值参数,不定长参数
  不定长参数
    不定长参数**kwargs用于接收不定数量的关键字的关键字参数,调用函数时传入的所有参数被**kwargs接收后以字典形式保存。
	不定长参数*args用于接收不定数量的位置参数,调用函数时传入的所有参数被*args接收后以元组形式保存
是否会影响传入的参数--它们共同引用的,它们引用的是同一个
  不可变对象
     将实际参数值的副本(复制品)传入函数,而参数本身不会受到任何影响
  可变对象-如果实际参数的数据类型是可变对象(列表、字典),则函数参数的传递方式将采用引用传递方式。
    需要注意的是,引用传递方式的底层实现,采用的依然还是值传递的方式  

非结构化数据

2D图像数据
3D数据
   可分类为网格数据、点云数据、体数据、高程数据。
      Cloud point Data
      Mesh Data
      Volume Data
      Height Elevation Data 
	  RGBD 数据
    3D数据存储常用方法有空间数据库和文件存储
    3D模型数据组成包括几何数据、属性数据和纹理材质数据  
       3D 文本格式,通过定义点、线、面的方式来描述 3D 物体

维度

 一维空间  一个轴  axis0
 二维空间  axis0 axis1
 三维空间  axis0 axis1 axis2 
 ndim和shape来分别查看维度,以及在对应维度上的长度	 
    有m层即为m维,最外面1层对应axis0, 依次为axis1,axis2…

pytorch

import torch
  torch.float == torch.FloatTensor torch.cuda.FloatTensor
数据基本
  torch.tensor()
  torch.tensor().dtype .shape .size() .numel()  
    requires_grad 只有浮点型数据才能计算梯度
 数据集合
   torch.Tensor()  torch.normal() torch.randn() 
   torch.ones() torch.zeros() torch.empty() torch.eye() torch.full()
   torch.ones_like()  torch.zeros_like() torch.rand_like()
   .new_full() .new_zeros() .new_empty() .new_ones()
操作:reshape() resize_()  squeeze() unsqueeze() .expand .repeat
      tril() triu() diag()
	  cat() stack() chunk() split()
	  算术-代数-逻辑-矩阵
	   torch.min torch.argmin() torch.sam()
	   torch.t() torch.matmul() torch.trace() torch.inverse() 
	   
数据变换 Bridge with NumPy  

   numpy--> torch   torch.as_tensor()  torch.from_numpy()
   torch--> numpy    torch.numpy()

numpy

   import numpy as  np 
   dtype 
  tolist tofile tobytes
  transpose 
max argmax min argmin mean sum std 

2.IO-输入和输出
  np.load()   np.loadtxt() np.genfromtxt() np.fromstring() np.fromfile()
  np.save()  ndarray.tofile()
3.Linear algebra (numpy.linalg)
      The numpy.matmul function implements the @ operator
  Matrix and vector products  / Decompositions  /Matrix eigenvalues  /Norms and other numbers
     np.dot np.inner() np.outer() np.matmul()
     np.linalg.inv(a)
 Logic functions
 np.deg2rad()  np.rad2deg()
 np.reshape()  np.transpose()
 Joining arrays ==  np.stack() np.vstack() np.hstack() np.dstack() np.cloumn_stack() np.row_stack()  np.concatenate()
 Splitting arrays ==  np.split() np.vsplit() np.hsplit() np.dsplit() np.array_stack()  

代码示例

 # -*- coding: utf-8 -*-
 
 import numpy as np
 
 # 一维
 a = np.array([1, 2,3,4,5])
 b = np.array([7,6,8,9,0])
 c = np.array([10,20,30,40,50])
 np_ones = np.ones((a.shape[0]))
 print(a,a.shape ,a.size,a.ndim)
 # 同一维度 和非同一维度 进行拼接
 # 扩维拼接和非扩维拼接
 print(np.hstack((a,b,c,np_ones)))
 # T是transpose这个单词的开头,效果和transpose是一样的 
 test_conct = np.vstack((a,b,c,np_ones)) 
 print(test_conct)
 print(test_conct.shape,test_conct.size,test_conct.ndim)
 #print( test_conct.T) 
 #print(np.transpose(test_conct))
 # 类型、尺寸、形状、维度
 print(test_conct.T.dtype,test_conct.T.shape,test_conct.T.size,test_conct.T.ndim)
 
 np_ones_test = np.ones(5)

open3d

 import open3d as o3d 
 o3d.core.Tensor
 o3d.core.Dtype.Float32

Bridge with NumPy
# Tensor from Numpy.
a = o3d.core.Tensor(np.array([0, 1, 2]),dtype=o3d.core.Dtype.Float64,, device=o3c.Device("cpu:0"))
# Type casting
b = a.to(o3d.core.Dtype.Int32)
o3d.core.Tensor.from_numpy(...) 
o3d.core.Tensor.numpy(...). 
Changes in either of them will get reflected in other
Reduction  Slicing, indexing, getitem, and setitem  Logical operations  Comparison Operations

###open3d.io.read_point_cloud  open3d.io.write_point_cloud   Vector3dVector
###open3d.t.io.read_point_cloud  open3d.t.io.write_point_cloud
   open3d.t.geometry.PointCloud

参考

 https://numpy.org/
 https://numpy.org/doc/stable/reference/routines.linalg.html
 https://numpy.org/doc/stable/reference/routines.array-manipulation.html
 https://www.numpy.org.cn/reference/routines/
 https://numpy.org/doc/stable/reference/routines.io.html
 https://pytorch.org/tutorials/beginner/basics/tensorqs_tutorial.html
 http://www.open3d.org/docs/release/tutorial/core/tensor.html
https://numpy.org/doc/stable/user/quickstart.html
https://github.com/zhulf0804/PointPillars/blob/main/utils/vis_o3d.py
https://github.com/zhulf0804/PointPillars/blob/main/test.py
3D点云 (Lidar)检测入门篇 - PointPillars PyTorch实现 https://zhuanlan.zhihu.com/p/521277176
posted @ 2022-11-09 17:52  辰令  阅读(138)  评论(0编辑  收藏  举报