Python+Pytorch三维点云可视化

1、批量处理txt文件

import numpy as np
f_path=r'C:\Users\Admin\Desktop\shapenetcore_partanno_segmentation_benchmark_v0_normal_new\00000001\10.txt'
with open(f_path) as f:
    contents=f.read()
'''print(contents)'''
print(type(contents))
a = contents.split()
'''print(a)'''
a = np.array(a)
a = a.reshape(578628,9)
a = a[:,0:7]
print(a[0,0])
print(type(a ))

f_path=r'C:\Users\Admin\Desktop\shapenetcore_partanno_segmentation_benchmark_v0_normal_new\00000001\10.txt'
with open(f_path, 'w') as f:
        '''按列生成矩阵'''
        '''np.savetxt(f, np.column_stack(a), fmt='%s')'''
        '''按行生成矩阵'''
        np.savetxt(f, np.row_stack(a), fmt='%s')

2、路径的读取
1.os.getcwd()
print(" os.getcwd()",os.getcwd())的作用是获取当前文件的路径,和linux的pwd命令一致,其中getcwd()方法不能加参数

 os.getcwd() C:\Users\Admin\Desktop\Pointnet2

2.os.path.abspath(args)
os.path.abspath()要加上参数,用法是:在当前的工作目录下追加一个目录

3.拼接目录之os.path.join(ROOT_DIR, “mrcnn”)
os.path.join(ROOT_DIR, “logs”)必须要加上两个参数拼接,其中 ROOT_DIR一般通过os.getcwd()获得。

4.拼接目录之os.path.abspath(“mrcnn”)
os.path.abspath(“mrcnn”)的作用和3中的作用是一致的,但是本人觉得通过os.path.join方法更灵活,因为os.path.abspath(“mrcnn”)方法只能得到一个基于当前目录的路径,而os.path.join(ROOT_DIR, “mrcnn”)中的ROOT_DIR则可以是其他的路径,比如存放图片的路径,存放模型的路径等,先用ROOT_DIR定义,之后再调用。

3、tqdm介绍及常用方法
Tqdm 是一个快速,可扩展的Python进度条,可以在 Python 长循环中添加一个进度提示信息,用户只需要封装任意的迭代器 tqdm(iterator)。
使用pip就可以安装。

使用方法一: tqdm

tqdm(list)方法可以传入任意一种list,比如数组

from tqdm import trange
for i in trange(100):
    #do something
    pass

使用方法二: trange

trange(i) 是 tqdm(range(i)) 的简单写法

from tqdm import trange
for i in trange(100):
    #do something
    pass

使用方法三: 手动方法

在for循环外部初始化tqdm,可以打印其他信息

bar = tqdm(["a", "b", "c", "d"])
for char in pbar:
    pbar.set_description("Processing %s" % char)

optimizer.zero_grad() 功能
梯度初始化为零,把loss关于weight的导数变成0

Pytorch 中的view函数作用是将张量铺平

4、显示三维点云
需要安装模块:
open3d numpy matplotlib pandas plyfile pyntcloud

单独读取数据集,并在open3d中显示原点云图
注意:要把对应的数据集文件 如:”0.txt”放在对应的代码路径下

import open3d as o3d
import os
import numpy as np
import matplotlib.pyplot as plt
from pandas import DataFrame
from pyntcloud import PyntCloud

point_cloud_raw = np.genfromtxt(r"0.txt", delimiter=" ")  # 为 xyz的 N*3矩阵
point_cloud_raw = DataFrame(point_cloud_raw[:,0:3])  # 选取每一列 的 第0个元素到第二个元素   [0,3)
point_cloud_raw.columns = ['x', 'y', 'z']  # 给选取到的数据 附上标题
point_cloud_pynt = PyntCloud(point_cloud_raw)  # 将points的数据 存到结构体中

point_cloud_o3d = point_cloud_pynt.to_instance("open3d", mesh=False)  # 实例化

o3d.visualization.draw_geometries([point_cloud_o3d])  # 显示原始点云

《Python+Pytorch三维点云可视化》
显示程序2

import open3d as o3d    #导入open3d
import numpy as np
import matplotlib as plt
raw_point_cloud_matrix = np.genfromtxt(r"0.txt", delimiter=" ")
raw_point_cloud_matrix = raw_point_cloud_matrix[:,0:3].reshape((-1,3))
# print(raw_point_cloud_matrix)
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(raw_point_cloud_matrix)
print(pcd)
o3d.visualization.draw_geometries([pcd])

o3d.visualization.draw_geometries([point_cloud_o3d])  # 显示原始点云

5、使用matplotlib可视化点云分割结果
如何获取分割结果就不再赘述了,这里主要是在获取了分割结果后如何绘制,我是使用的matplotlib库,以ShapeNet为例:

首先设置每个类别的每个部分的颜色映设表:

import copy
import numpy as np
# 每个种类所对应的part类别
lab2seg={'Earphone': [16, 17, 18], 'Motorbike': [30, 31, 32, 33, 34, 35], 'Rocket': [41, 42, 43], 'Car': [8, 9, 10, 11],
     'Laptop': [28, 29], 'Cap': [6, 7], 'Skateboard': [44, 45, 46], 'Mug': [36, 37], 'Guitar': [19, 20, 21],
     'Bag': [4, 5], 'Lamp': [24, 25, 26, 27], 'Table': [47, 48, 49], 'Airplane': [0, 1, 2, 3], 'Pistol': [38, 39, 40],
     'Chair': [12, 13, 14, 15], 'Knife': [22, 23]}
#获取所要绘制点云数据的类别
cls=[]
with open('/results/seg_model_2.txt', 'r') as f:
    for i,line in enumerate(f):
        ls=line.strip().split()
        cls.append(ls[0][1:-2])
#生成颜色映射表
#因为只有几种颜色可选,所以分割结果按这几种颜色随机分配,可以自己改成其他的
map = ['r', 'g', 'b', 'c', 'm', 'y'] 
#随机生成颜色映射
idx = np.arange(0, len(map))
idx_all = []
np.random.seed(123)
for _ in range(len(lab2seg)):
    np.random.shuffle(idx)
    idx_all.append(copy.deepcopy(idx))
idx_all = np.array(idx_all)
#将生成的颜色映射表对应到不同种类的part类别上
for i,key in enumerate(lab2seg.keys()):
    lab2seg[key]=dict(zip(set(lab2seg[key]),[map[idx_all[i,j]] for j in range(len(set(lab2seg[key])))]))

依据所得到的颜色映射表绘制分割结果

def data_depict(bsize,fn,lab2seg,cls):
#bsize: 数据个数
#fn: 路径
#lab2seg: 生成的颜色对应表,即每个种类的每个part类别所对应的颜色,作为输入是为了使得不同结果间保持一致
#cls: 每个点云数据所对应的类别
    for j in range(bsize):
    	#读取点云和分割结果数据
        data= np.loadtxt(fn+'%d.txt'%j).astype(np.float32)
        #归一化
        data[:,:3]=pc_normalize(data[:,:3])
        #将数据点的part类别对应为lab2seg中设置的颜色
        colormap = [[] for _ in range(len(data))]
        for i in range(len(data)):
            colormap[i] = lab2seg[cls[j]][data[i, -1]]
        #设置图片大小
        plt.figure(figsize=(10,10))
        ax = plt.subplot(111, projection='3d')
        #设置视角
        ax.view_init(elev=30, azim=-60)
        #关闭坐标轴
        plt.axis('off')
        #设置坐标轴范围
        ax.set_zlim3d(-1, 1)
        ax.set_ylim3d(-1, 1)
        ax.set_xlim3d(-1, 1)
        ax.scatter(data[:, 0], data[:, 1], data[:, 2], c=colormap, s=20, marker='.') #, cmap='plasma')
        # plt.show()
        #保存为.eps文件,也可以是其他类型,注意保存不能和显示同时使用
        plt.savefig(fn + '%d.eps' % j, dpi=500,bbox_inches='tight',transparent=True)
    plt.close()
  
def pc_normalize(pc):
    l = pc.shape[0]
    centroid = np.mean(pc, axis=0)
    pc = pc - centroid[np.newaxis,:]
    m = np.max(np.sqrt(np.sum(np.power(pc,2), axis=1)),axis=0)
    pc = pc / m[np.newaxis,np.newaxis]
    return pc

《Python+Pytorch三维点云可视化》
《Python+Pytorch三维点云可视化》

import copy
import numpy as np
import matplotlib.pyplot as plt

def pc_normalize(pc):
    l = pc.shape[0]
    centroid = np.mean(pc, axis=0)
    pc = pc - centroid[np.newaxis, :]
    m = np.max(np.sqrt(np.sum(np.power(pc, 2), axis=1)), axis=0)
    pc = pc / m[np.newaxis, np.newaxis]
    return pc

def data_depict(bsize, fn,lab2seg, cls):
    # bsize: 数据个数
    # fn: 路径
    # lab2seg: 生成的颜色对应表,即每个种类的每个part类别所对应的颜色,作为输入是为了使得不同结果间保持一致
    # cls: 每个点云数据所对应的类别
    for j in range(bsize):
        # 读取点云和分割结果数据
        data = np.loadtxt(fn + '%d.txt' % j).astype(np.float32)
        # 归一化
        data[:, :3] = pc_normalize(data[:, :3])
        # 将数据点的part类别对应为lab2seg中设置的颜色
        colormap = [[] for _ in range(len(data))]
        for i in range(len(data)):
            colormap[i] = lab2seg[cls[j]][data[i, -1]]
        # 设置图片大小

        plt.figure(figsize=(10, 10))
        ax = plt.subplot(111, projection='3d')
        # 设置视角
        ax.view_init(elev=30, azim=-60)
        # 关闭坐标轴
        plt.axis('off')
        # 设置坐标轴范围
        ax.set_zlim3d(-1, 1)
        ax.set_ylim3d(-1, 1)
        ax.set_xlim3d(-1, 1)
        ax.scatter(data[:, 0], data[:, 1], data[:, 2], c=colormap, s=20, marker='.')  # , cmap='plasma')
        plt.show()
        # 保存为.eps文件,也可以是其他类型,注意保存不能和显示同时使用
        plt.savefig(fn + '%d.eps' % j, dpi=500, bbox_inches='tight', transparent=True)
    plt.close()

def main():
    print('hello1')
    # 每个种类所对应的part类别
    lab2seg = {'Earphone': [16, 17, 18], 'Motorbike': [30, 31, 32, 33, 34, 35], 'Rocket': [41, 42, 43],
               'Car': [8, 9, 10, 11],
               'Laptop': [28, 29], 'Cap': [6, 7], 'Skateboard': [44, 45, 46], 'Mug': [36, 37], 'Guitar': [19, 20, 21],
               'Bag': [4, 5], 'Lamp': [24, 25, 26, 27], 'Table': [47, 48, 49], 'Airplane': [0, 1, 2, 3],
               'Pistol': [38, 39, 40],
               'Chair': [12, 13, 14, 15], 'Knife': [22, 23]}
    # 获取所要绘制点云数据的类别
    cls = []
    with open('0.txt', 'r') as f:
        for i, line in enumerate(f):
            ls = line.strip().split()
            cls.append(ls[0][1:-2])
    # 生成颜色映射表
    # 因为只有几种颜色可选,所以分割结果按这几种颜色随机分配,可以自己改成其他的
    map = ['r', 'g', 'b', 'c', 'm', 'y']
    # 随机生成颜色映射
    idx = np.arange(0, len(map))
    idx_all = []
    np.random.seed(123)
    for _ in range(len(lab2seg)):
        np.random.shuffle(idx)
        idx_all.append(copy.deepcopy(idx))
    idx_all = np.array(idx_all)
    # 将生成的颜色映射表对应到不同种类的part类别上
    for i, key in enumerate(lab2seg.keys()):
        lab2seg[key] = dict(zip(set(lab2seg[key]), [map[idx_all[i, j]] for j in range(len(set(lab2seg[key])))]))
        print(lab2seg)
    print('hello2')

    data = np.loadtxt('0.txt')
    data = data.astype(np.float32)
    # 归一化
    data[:, :3] = pc_normalize(data[:, :3])
    # 将数据点的part类别对应为lab2seg中设置的颜色
    '''colormap = [[] for _ in range(len(data))]
    for i in range(len(data)):
        colormap[i] = 'g'
    '''
    colormap = [[] for _ in range(len(data))]
    for i in range(len(data)):
        '''colormap[i] = lab2seg[cls[12]][data[i, -1]'''
        #print(data[:, 6][0])
        if data[:, 6][i] == 0:
            colormap[i] = 'g'
        elif data[:, 6][i] == 1:
            colormap[i] = 'r'
        elif data[:, 6][i] == 2:
            colormap[i] = 'b'
        else:
            colormap[i] = 'c'
            # 设置图片大小

    plt.figure(figsize=(10, 10))
    ax = plt.subplot(111, projection='3d')
    # 设置视角
    ax.view_init(elev=30, azim=-60)
    # 关闭坐标轴
    plt.axis('off')
    # 设置坐标轴范围
    ax.set_zlim3d(-1, 1)
    ax.set_ylim3d(-1, 1)
    ax.set_xlim3d(-1, 1)
    ax.scatter(data[:, 0], data[:, 1], data[:, 2], c=colormap, s=20, marker='.')  # , cmap='plasma')
    plt.show()
    # 保存为.eps文件,也可以是其他类型,注意保存不能和显示同时使用
    #plt.savefig('%d.eps', dpi=500, bbox_inches='tight', transparent=True)

if __name__ == '__main__':
    main()

《Python+Pytorch三维点云可视化》

    原文作者:马少爷
    原文地址: https://blog.csdn.net/qq_27353621/article/details/123935022
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞