PointNet&PointNet++源码ModelNetDataLoader理解

源码:https://github.com/yanx27/Pointnet_Pointnet2_pytorch

文件:ModelNetDataLoader.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-# 导入第三方库
import numpy as np
import warnings
import os
from torch.utils.data import Dataset
warnings.filterwarnings('ignore')# 将数据归一化
def pc_normalize(pc):# 计算pc簇的中心点,新的中心点每一个特征的值,是该簇所有数据在该特征的平均值centroid = np.mean(pc, axis=0)# 3D数据簇减去中心得到到中心的绝对距离pc = pc - centroid# 取到最大距离m = np.max(np.sqrt(np.sum(pc**2, axis=1)))# 将数据归一化pc = pc / mreturn pc# 最远点采样
def farthest_point_sample(point, npoint):"""Input:xyz: pointcloud data, [N, D]npoint: number of samplesReturn:centroids: sampled pointcloud index, [npoint, D]"""N, D = point.shapexyz = point[:, :3]# 先随机初始化一个centroids矩阵,# 后面用于存储npoint个采样点的索引位置centroids = np.zeros((npoint,))# 利用distance矩阵记录某个样本中所有点到某一个点的距离distance = np.ones((N,)) * 1e10  # 初值给个比较大的值,后面会迭代更新# 利用farthest表示当前最远的点,也是随机初始化,范围为0~Nfarthest = np.random.randint(0, N)# 直到采样点达到npoint,否则进行如下迭代for i in range(npoint):# 设当前的采样点centroids为当前的最远点farthest;centroids[i] = farthest# 取出这个中心点centroid的坐标centroid = xyz[farthest, :]# 求出所有点到这个farthest点的欧式距离,存在dist矩阵中dist = np.sum((xyz - centroid) ** 2, -1)# 建立一个mask,如果dist中的元素小于distance矩阵中保存的距离值,# 则更新distance中的对应值,# 即记录某个样本中每个点距离所有已出现的采样点的最小距离mask = dist < distancedistance[mask] = dist[mask]# 最后从distance矩阵取出最远的点为farthest,继续下一轮迭代farthest = np.argmax(distance, -1)point = point[centroids.astype(np.int32)]# 返回结果是npoint个采样点在原始点云中的索引return point# 加载数据集
class ModelNetDataLoader(Dataset):def __init__(self, root,  npoint=1024, split='train', uniform=False, normal_channel=True, cache_size=15000):self.root = root       # 数据集根目录self.npoints = npoint  # 对原始数据集下采样至1024个点self.uniform = uniform  # 是否归一化self.catfile = os.path.join(self.root, 'modelnet40_shape_names.txt')self.cat = [line.rstrip() for line in open(self.catfile)]self.classes = dict(zip(self.cat, range(len(self.cat))))self.normal_channel = normal_channelshape_ids = {}# 将数据集划分为训练集和测试集shape_ids['train'] = [line.rstrip() for line in open(os.path.join(self.root, 'modelnet40_train.txt'))]shape_ids['test'] = [line.rstrip() for line in open(os.path.join(self.root, 'modelnet40_test.txt'))]assert (split == 'train' or split == 'test')shape_names = ['_'.join(x.split('_')[0:-1]) for x in shape_ids[split]]# (shape_name, shape_txt_file_path) 元组列表self.datapath = [(shape_names[i], os.path.join(self.root, shape_names[i], shape_ids[split][i]) + '.txt') for iin range(len(shape_ids[split]))]print('The size of %s data is %d' % (split, len(self.datapath)))# 在内存中缓存数据点的大小self.cache_size = cache_size  # 核函数cache缓存大小,默认设置为15000self.cache = {}  # 从索引到(point_set, cls) 元组def __len__(self):return len(self.datapath)def _get_item(self, index):if index in self.cache:point_set, cls = self.cache[index]else:fn = self.datapath[index]cls = self.classes[self.datapath[index][0]]cls = np.array([cls]).astype(np.int32)point_set = np.loadtxt(fn[1], delimiter=',').astype(np.float32)if self.uniform:point_set = farthest_point_sample(point_set, self.npoints)else:point_set = point_set[0:self.npoints,:]point_set[:, 0:3] = pc_normalize(point_set[:, 0:3])if not self.normal_channel:point_set = point_set[:, 0:3]if len(self.cache) < self.cache_size:self.cache[index] = (point_set, cls)return point_set, cls  # 返回点云集及其分类def __getitem__(self, index):return self._get_item(index)if __name__ == '__main__':  # 测试模型导入是否无误# 导入第三方库import torch# 导入数据data = ModelNetDataLoader('/data/modelnet40_normal_resampled/', split='train', uniform=False, normal_channel=True,)DataLoader = torch.utils.data.DataLoader(data, batch_size=12, shuffle=True)for point, label in DataLoader:print(point.shape)print(label.shape)

PointNetPointNet++源码ModelNetDataLoader理解相关推荐

  1. android 点击事件消费,Android View事件分发和消费源码简单理解

    Android View事件分发和消费源码简单理解 前言: 开发过程中觉得View事件这块是特别烧脑的,看了好久,才自认为看明白.中间上网查了下singwhatiwanna粉丝的读书笔记,有种茅塞顿开 ...

  2. 结合源码深入理解Android Crash处理流程

    应用程序crash在开发过程中还是很常见的,本文主要是从源码的角度去跟踪下Android对于crash的处理流程.App crash的全称:Application crash.而Crash又分为:na ...

  3. Android学习之Activity源码的理解(一)

    一.Activity为Android系统中四大组件之一,是Android程序的呈现层,并通过界面与用户进行交互,因此理解Activity源码是有必要的. 二.之前我写过一篇文章:http://blog ...

  4. LruCache源码的理解

    LruCache源码的理解 使用场景 在Android手机上加载图片,一般会用到三级缓存策略 内存的缓存策略,一般会用到LruCache来解决 内存用于缓存遇到的问题 1. 手机给每个应用分配的内存空 ...

  5. 从源码角度理解LinearLayout#onMeasure对child的measure调用次数

    熟悉绘制流程的都知道,ViewGroup可以决定child的绘制时机以及调用次数. 今天我们就从LinearLayout开始学起,看一下它对子View的onMeasure调用次数具体是多少. 简单起见 ...

  6. 从源码角度理解FrameLayout#onMeasure对child的measure调用次数

    熟悉绘制流程的都知道,ViewGroup可以决定child的绘制时机以及调用次数. 今天我们就从最简单的FrameLayout开始学起,看一下它对子View的onMeasure调用次数具体是多少. 简 ...

  7. 从源码角度理解ConstraintLayout#onMeasure对child的measure调用次数

    熟悉绘制流程的都知道,ViewGroup可以决定child的绘制时机以及调用次数. 今天我们简单看下较为复杂的ConstraintLayout,看一下它对子View的onMeasure调用次数具体是多 ...

  8. PX4姿态解算源码原理理解

    PX4源码原理理解一.主要参考资料链接:1.1 取PX4源码一小部分姿态解算来进行讲解姿态解算源码中文注释:https://blog.csdn.net/zouxu634866/article/deta ...

  9. spring的事务隔离_再深一点:面试工作两不误,源码级理解Spring事务

    原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处. Spring有5种隔离级别,7种传播行为.这是面试常问的内容,也是代码中经常碰到的知识点.这些知识枯燥而且乏味,其中有些非 ...

最新文章

  1. java mysql aio_Java中的NIO,BIO,AIO分别是什么
  2. Android开发环境搭建全程演示(jdk+eclip+android sdk)
  3. Exp6 信息收集与漏洞扫描 20164314
  4. 数据结构与算法之递归系列
  5. 2021-02-25
  6. wordpress 插件_如何为您的Web应用程序创建WordPress插件
  7. 用 vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)
  8. Spark 连接 HBase 入库及查询操作
  9. .net get set 初始化_.NET项目升级:可为空引用
  10. 开设计算机课程的必要性,学前教育专业开设计算机音乐制作课程的必要性与可行性...
  11. 机器学习第18篇 - Boruta特征变量筛选(2)
  12. 技术实践:教你用Python搭建gRPC服务
  13. Jdbc普通查询、流式查询、游标查询
  14. EasyUI remote ajax方式提交验证
  15. ios 类别(category)
  16. css多重颜色渐变,CSS多重渐变颜色停止
  17. 插入排序 java实现
  18. pythonplot下载_Matplotlib for Python Developers PDF 下载
  19. Ubuntu安装配置tftp服务器
  20. arduino nano 蓝牙_基于Arduino的摩尔斯电码练习及无线收发报训练器

热门文章

  1. 软件项目为什么不能够如期交付?
  2. 业务流程图怎么画?简单的方法教程
  3. 有一个设计时钟的题目,进行详细分析(一)
  4. 深入解析Golang之Context
  5. 斯蒂文斯理工学院的计算机专业,斯蒂文斯理工学院计算机科学硕士专业入学要求及费用...
  6. 百度地图V5.0.0版本mapsdkvi.com.gdi.bgl.android.java.EnvDrawText异常
  7. 【转】MIUI8以及ViVO X9上在Android Studio运行出错集及其解决方案
  8. dpdk 20.02 igb_uio.ko 编译
  9. 21世纪什么最贵?“人才
  10. 基于FPGA的FOC电流采样Bug调试记录